1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
3 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/TablePlugins/IterateTable.h"
7 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
9 #include <boost/stacktrace.hpp>
11 #include "otsdaq/GatewaySupervisor/GatewaySupervisor.h"
12 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
13 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
15 #include <xdaq/NamespaceURI.h>
24 #define __MF_SUBJECT__ "CfgGUI"
26 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
27 #define TABLE_INFO_EXT std::string("Info.xml")
43 __SUP_COUT__ <<
"Constructor started." << __E__;
48 mkdir(((std::string)ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str(), 0755);
51 __SUP_COUT__ <<
"Constructor complete." << __E__;
55 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
58 void ConfigurationGUISupervisor::init(
void)
60 __SUP_COUT__ <<
"Initializing..." << __E__;
64 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
69 __SUP_COUT__ <<
"Done with test context." << __E__;
73 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
74 "will not launch when this test fails. "
75 <<
"Check the active context group from within Wizard Mode."
80 refreshUserSession(
"" , 1);
83 if(CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
86 <<
"After successful Config GUI init, marking alive for wiz mode!" << __E__;
87 CorePropertySupervisorBase::
93 void ConfigurationGUISupervisor::destroy(
void)
95 __SUP_COUT__ <<
"Destructing..." << __E__;
98 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
99 userConfigurationManagers_.begin();
100 it != userConfigurationManagers_.end();
106 userConfigurationManagers_.clear();
108 if(ConfigurationInterface::getInstance() !=
nullptr)
109 delete ConfigurationInterface::getInstance();
114 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
116 cgicc::Cgicc cgiIn(in);
117 std::string configWindowName =
119 if(configWindowName ==
"tableEditor")
120 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
121 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
122 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
123 if(configWindowName ==
"iterate")
124 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
125 "src='/WebPath/html/Iterate.html?urn="
126 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
128 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
129 "src='/WebPath/html/ConfigurationGUI.html?urn="
130 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
138 CorePropertySupervisorBase::setSupervisorProperty(
139 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
140 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
141 "deleteTableInfo=255");
143 CorePropertySupervisorBase::setSupervisorProperty(
144 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
148 CorePropertySupervisorBase::setSupervisorProperty(
149 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"get*");
157 CorePropertySupervisorBase::addSupervisorProperty(
158 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
159 "getActiveTableGroups");
162 CorePropertySupervisorBase::setSupervisorProperty(
163 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
168 void ConfigurationGUISupervisor::request(
const std::string& requestType,
171 const WebUsers::RequestUserInfo& userInfo)
176 __COUTTV__(requestType);
247 refreshUserSession(userInfo.username_, (refresh ==
"1"));
248 __COUTTV__(userInfo.username_);
254 const std::set<TableGroupKey>& sortedKeys = groupInfo.getKeys();
255 __COUTTV__(sortedKeys.size());
258 if(requestType ==
"saveTableInfo")
260 std::string tableName =
262 std::string columnCSV =
264 std::string allowOverwrite =
266 std::string tableDescription =
268 std::string columnChoicesCSV =
271 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
272 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
273 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
274 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
275 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
277 if(!allSupervisorInfo_.isWizardMode())
279 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
280 xmlOut.addTextElementToData(
"Error", ss.str());
283 handleSaveTableInfoXML(xmlOut,
289 allowOverwrite ==
"1");
291 else if(requestType ==
"deleteTableInfo")
293 std::string tableName =
295 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
296 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
298 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
299 requestType ==
"flattenToSystemAliases")
302 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
303 __COUT_WARN__ << requestType <<
" command received! " << __E__;
306 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
308 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
309 std::vector<std::string> hostnames;
312 if(requestType ==
"flattenToSystemAliases" &&
313 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
315 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
316 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
327 auto contexts = contextTable->getContexts();
329 for(
const auto& context : contexts)
336 for(i = 0; i < context.address_.size(); ++i)
337 if(context.address_[i] ==
'/')
339 hostnames.push_back(context.address_.substr(j));
340 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
345 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
352 catch(
const std::exception& e)
354 ss <<
"Exception message: " << e.what();
360 __SUP_COUT_ERR__ <<
"\n" << ss.str();
365 if(hostnames.size() == 0)
367 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
368 "'... Is there a valid Context group activated?"
370 __SUP_COUT_ERR__ <<
"\n" << ss.str();
372 xmlOut.addTextElementToData(
"Error", ss.str());
375 for(
const auto& hostname : hostnames)
377 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
378 "/StartOTS_action_" + hostname +
".cmd");
379 FILE* fp = fopen(fn.c_str(),
"w");
382 if(requestType ==
"gatewayLaunchOTS")
383 fprintf(fp,
"LAUNCH_OTS");
384 else if(requestType ==
"gatewayLaunchWiz")
385 fprintf(fp,
"LAUNCH_WIZ");
386 else if(requestType ==
"flattenToSystemAliases")
388 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
396 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
399 else if(requestType ==
"versionTracking" || requestType ==
"getVersionTracking")
402 if(requestType ==
"getVersionTracking")
406 __SUP_COUT__ <<
"type: " << type << __E__;
409 xmlOut.addTextElementToData(
410 "versionTrackingStatus",
411 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
412 else if(type ==
"ON")
414 ConfigurationInterface::setVersionTrackingEnabled(
true);
415 xmlOut.addTextElementToData(
416 "versionTrackingStatus",
417 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
419 else if(type ==
"OFF")
421 ConfigurationInterface::setVersionTrackingEnabled(
false);
422 xmlOut.addTextElementToData(
423 "versionTrackingStatus",
424 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
427 else if(requestType ==
"getColumnTypes")
430 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
431 std::vector<std::string> allDataTypes =
432 TableViewColumnInfo::getAllDataTypesForGUI();
433 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
436 for(
const auto& type : allTypes)
437 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
438 for(
const auto& dataType : allDataTypes)
439 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
441 for(
const auto& colDefault : allDefaults)
443 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
444 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
445 colDefault.first.second);
446 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
450 else if(requestType ==
"getGroupAliases")
455 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
457 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
465 catch(std::runtime_error& e)
467 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
469 __SUP_COUT_ERR__ <<
"\n" << ss.str();
470 xmlOut.addTextElementToData(
"Error", ss.str());
474 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
479 catch(
const std::exception& e)
481 ss <<
"Exception message: " << e.what();
486 __SUP_COUT_ERR__ <<
"\n" << ss.str();
487 xmlOut.addTextElementToData(
"Error", ss.str());
491 handleGroupAliasesXML(xmlOut, cfgMgr);
493 else if(requestType ==
"setGroupAliasInActiveBackbone")
495 std::string groupAliasCSV =
497 std::string groupNameCSV =
499 std::string groupKeyCSV =
502 __SUP_COUTV__(groupAliasCSV);
503 __SUP_COUTV__(groupNameCSV);
504 __SUP_COUTV__(groupKeyCSV);
506 handleSetGroupAliasInBackboneXML(
507 xmlOut, cfgMgr, groupAliasCSV, groupNameCSV, groupKeyCSV, userInfo.username_);
509 else if(requestType ==
"setTableAliasInActiveBackbone")
511 std::string tableAlias =
513 std::string tableName =
517 __SUP_COUT__ <<
"tableAlias: " << tableAlias << __E__;
518 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
519 __SUP_COUT__ <<
"version: " << version << __E__;
521 handleSetTableAliasInBackboneXML(xmlOut,
528 else if(requestType ==
"setAliasOfGroupMembers")
530 std::string versionAlias =
532 std::string groupName =
536 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
537 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
538 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
540 handleAliasGroupMembersInBackboneXML(xmlOut,
547 else if(requestType ==
"getVersionAliases")
549 handleVersionAliasesXML(xmlOut, cfgMgr);
551 else if(requestType ==
"getTableGroups")
553 bool doNotReturnMembers =
554 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
558 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
559 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
561 else if(requestType ==
"getTableGroupType")
563 std::string tableList =
565 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
567 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
569 else if(requestType ==
"getTables")
571 handleTablesXML(xmlOut, cfgMgr);
573 else if(requestType ==
"getContextMemberNames")
575 std::set<std::string> members = cfgMgr->getFixedContextMemberNames();
577 for(
auto& member : members)
578 xmlOut.addTextElementToData(
"ContextMember", member);
580 else if(requestType ==
"getBackboneMemberNames")
582 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
584 for(
auto& member : members)
585 xmlOut.addTextElementToData(
"BackboneMember", member);
587 else if(requestType ==
"getIterateMemberNames")
589 std::set<std::string> members = cfgMgr->getIterateMemberNames();
591 for(
auto& member : members)
592 xmlOut.addTextElementToData(
"IterateMember", member);
594 else if(requestType ==
"getSpecificTableGroup")
596 std::string groupName =
600 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
601 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
606 else if(requestType ==
"saveNewTableGroup")
608 std::string groupName =
610 bool ignoreWarnings =
611 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
612 bool allowDuplicates =
613 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
614 bool lookForEquivalent =
615 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
616 std::string tableList =
618 std::string comment =
621 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
622 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
623 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
624 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
625 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
626 __SUP_COUT__ <<
"comment: " << comment << __E__;
637 else if(requestType ==
"getSpecificTable")
639 std::string tableName =
642 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
643 int chunkSize = CgiDataUtilities::getDataAsInt(
646 bool descriptionOnly = CgiDataUtilities::getDataAsInt(
647 cgiIn,
"descriptionOnly");
648 bool allowIllegalColumns =
649 CgiDataUtilities::getDataAsInt(cgiIn,
"allowIllegalColumns");
650 bool rawData = CgiDataUtilities::getDataAsInt(cgiIn,
"rawData");
652 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
653 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
654 <<
" descriptionOnly: " << descriptionOnly
655 <<
" allowIllegalColumns: " << allowIllegalColumns
656 <<
" rawData: " << rawData << __E__;
659 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
661 if(allTableInfo.find(tableName) != allTableInfo.end())
663 if(versionStr ==
"" &&
664 allTableInfo.at(tableName).versions_.size())
667 auto it = allTableInfo.at(tableName).versions_.rbegin();
668 if(it->isScratchVersion())
672 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
675 std::map<std::string ,
679 std::string versionAlias;
680 versionAlias = versionStr.substr(
681 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
692 if(versionAliases.find(tableName) != versionAliases.end() &&
693 versionAliases[tableName].find(versionAlias) !=
694 versionAliases[tableName].end())
696 version = versionAliases[tableName][versionAlias];
697 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
702 << versionStr.substr(
703 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
704 <<
"'was not found in active version aliases!" << __E__;
707 version = atoi(versionStr.c_str());
710 __SUP_COUT__ <<
"version: " << version << __E__;
712 handleGetTableXML(xmlOut,
720 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
722 else if(requestType ==
"saveSpecificTable")
724 std::string tableName =
726 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
727 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
728 bool sourceTableAsIs =
729 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
730 bool lookForEquivalent =
731 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
732 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
733 std::string comment =
740 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
741 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
743 __SUP_COUT__ <<
"comment: " << comment << __E__;
744 __SUP_COUT__ <<
"data: " << data << __E__;
745 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
746 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
760 else if(requestType ==
"clearTableTemporaryVersions")
762 std::string tableName =
764 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
770 catch(std::runtime_error& e)
772 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
773 xmlOut.addTextElementToData(
774 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
778 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
779 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
782 else if(requestType ==
"clearTableCachedVersions")
784 std::string tableName =
786 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
797 catch(std::runtime_error& e)
799 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
800 xmlOut.addTextElementToData(
801 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
805 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
806 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
809 else if(requestType ==
"getGroupHistory")
816 __SUP_COUTV__(groupAction);
817 __SUP_COUTV__(groupType);
819 std::vector<std::map<std::string ,
822 groupAction, groupType,
true );
824 for(
const auto& group : groups)
826 auto parentEl = xmlOut.addTextElementToData(
827 "GroupHistoryEntry",
"");
828 for(
const auto& field : group)
832 else if(requestType ==
"getTreeView")
839 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
840 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
844 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
845 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
846 __SUP_COUTT__ <<
"startPath: " << startPath << __E__;
847 __SUP_COUTT__ <<
"depth: " << depth << __E__;
848 __SUP_COUTT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
849 __SUP_COUTT__ <<
"modifiedTables: " << modifiedTables << __E__;
850 __SUP_COUTT__ <<
"filterList: " << filterList << __E__;
852 handleFillTreeViewXML(xmlOut,
864 else if(requestType ==
"getTreeNodeCommonFields")
872 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
874 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
875 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
876 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
877 __SUP_COUT__ <<
"depth: " << depth << __E__;
880 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
881 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
882 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
884 handleFillTreeNodeCommonFieldsXML(xmlOut,
894 else if(requestType ==
"getUniqueFieldValuesForRecords")
903 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
904 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
905 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
906 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
907 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
908 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
910 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
919 else if(requestType ==
"getTreeNodeFieldValues")
928 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
929 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
930 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
931 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
932 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
933 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
935 handleFillGetTreeNodeFieldValuesXML(xmlOut,
944 else if(requestType ==
"setTreeNodeFieldValues")
954 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
955 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
956 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
957 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
958 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
959 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
960 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
962 handleFillSetTreeNodeFieldValuesXML(xmlOut,
973 else if(requestType ==
"addTreeNodeRecords")
981 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
982 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
983 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
984 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
985 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
987 handleFillCreateTreeNodeRecordsXML(xmlOut,
996 else if(requestType ==
"deleteTreeNodeRecords")
1004 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1005 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1006 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1007 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1008 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1010 handleFillDeleteTreeNodeRecordsXML(xmlOut,
1018 else if(requestType ==
"renameTreeNodeRecords")
1027 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1028 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1029 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1030 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1031 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1032 __SUP_COUTV__(newRecordList);
1034 handleFillRenameTreeNodeRecordsXML(xmlOut,
1043 else if(requestType ==
"copyTreeNodeRecords")
1050 unsigned int numberOfCopies =
1051 CgiDataUtilities::getDataAsInt(cgiIn,
"numberOfCopies");
1055 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1056 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1057 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1058 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1059 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1060 __SUP_COUTV__(numberOfCopies);
1062 handleFillCopyTreeNodeRecordsXML(xmlOut,
1071 else if(requestType ==
"getTableStructureStatusAsJSON")
1078 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1079 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1080 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1081 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1084 setupActiveTablesXML(xmlOut,
1093 xmlOut.addTextElementToData(
1094 "StructureStatusAsJSON",
1097 catch(
const std::runtime_error& e)
1099 __SUP_SS__ <<
"The table plugin feature getStructureStatusAsJSON(), does not "
1100 "seem to be supported for the table '"
1102 <<
".' Make sure you have the expected table plugin in your path, "
1103 "or contact system admins."
1105 ss <<
"Here is the error: " << e.what() << __E__;
1109 else if(requestType ==
"getArtdaqNodes")
1113 __SUP_COUTV__(modifiedTables);
1115 handleGetArtdaqNodeRecordsXML(xmlOut, cfgMgr, modifiedTables);
1117 else if(requestType ==
"saveArtdaqNodes")
1121 std::string subsystemString =
1124 __SUP_COUTV__(modifiedTables);
1125 __SUP_COUTV__(nodeString);
1126 __SUP_COUTV__(subsystemString);
1128 handleSaveArtdaqNodeRecordsXML(
1129 nodeString, subsystemString, xmlOut, cfgMgr, modifiedTables);
1131 else if(requestType ==
"getArtdaqNodeLayout")
1133 std::string contextGroupName =
1137 __SUP_COUTV__(contextGroupName);
1138 __SUP_COUTV__(contextGroupKey);
1140 handleLoadArtdaqNodeLayoutXML(
1141 xmlOut, cfgMgr, contextGroupName,
TableGroupKey(contextGroupKey));
1143 else if(requestType ==
"saveArtdaqNodeLayout")
1146 std::string contextGroupName =
1150 __SUP_COUTV__(layout);
1151 __SUP_COUTV__(contextGroupName);
1152 __SUP_COUTV__(contextGroupKey);
1154 handleSaveArtdaqNodeLayoutXML(
1155 xmlOut, cfgMgr, layout, contextGroupName,
TableGroupKey(contextGroupKey));
1157 else if(requestType ==
"checkAffectedActiveGroups")
1162 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1163 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1164 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1166 handleGetAffectedGroupsXML(
1167 xmlOut, cfgMgr, groupName,
TableGroupKey(groupKey), modifiedTables);
1169 else if(requestType ==
"saveTreeNodeEdit")
1173 std::string targetTableVersion =
1179 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
1180 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
1181 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
1182 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
1183 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
1184 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
1186 handleSaveTreeNodeEditXML(xmlOut,
1194 userInfo.username_);
1196 else if(requestType ==
"getLinkToChoices")
1199 std::string linkToTableVersion =
1206 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1207 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1208 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1209 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1210 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1212 handleGetLinkToChoicesXML(xmlOut,
1220 else if(requestType ==
"activateTableGroup")
1224 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1226 __SUP_COUT__ <<
"Activating group: " << groupName <<
"(" << groupKey <<
")"
1228 __SUP_COUTV__(ignoreWarnings);
1231 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1232 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1233 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1237 std::string accumulatedErrors, groupTypeString;
1245 groupName,
TableGroupKey(groupKey), &accumulatedErrors, &groupTypeString);
1247 if(accumulatedErrors !=
"")
1251 __SS__ <<
"Throwing exception on accumulated errors: "
1252 << accumulatedErrors << __E__;
1256 __COUT_WARN__ <<
"Ignoring warnings so ignoring this error:"
1257 << accumulatedErrors << __E__;
1258 __COUT_WARN__ <<
"Done ignoring the above error(s)." << __E__;
1260 xmlOut.addTextElementToData(
"AttemptedGroupActivationType", groupTypeString);
1262 catch(std::runtime_error& e)
1267 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1268 xmlOut.addTextElementToData(
1270 "Error activating table group '" + groupName +
"(" + groupKey +
")" +
1271 ".' Please see details below:\n\n" + std::string(e.what()));
1272 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1273 <<
" (" << groupKey <<
")" << __E__;
1282 catch(cet::exception& e)
1288 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1289 xmlOut.addTextElementToData(
"Error",
1290 "Error activating table group '" + groupName +
1291 "(" + groupKey +
")" +
"!'\n\n" +
1292 std::string(e.what()));
1293 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1294 <<
" (" << groupKey <<
")" << __E__;
1305 __SUP_COUT__ <<
"Unknown error detected!" << __E__;
1317 else if(requestType ==
"getActiveTableGroups")
1319 else if(requestType ==
"copyViewToCurrentColumns")
1321 std::string tableName =
1325 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1326 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1327 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1333 newTemporaryVersion =
1336 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1338 catch(std::runtime_error& e)
1340 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1341 xmlOut.addTextElementToData(
"Error",
1342 "Error copying view from '" + tableName +
"_v" +
1343 sourceVersion +
"'! " +
1344 std::string(e.what()));
1348 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1349 xmlOut.addTextElementToData(
1351 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1354 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1356 else if(requestType ==
"getLastTableGroups")
1359 std::map<std::string ,
1360 std::tuple<std::string ,
1365 theRemoteWebUsers_.getLastTableGroups(theGroups);
1367 for(
const auto& theGroup : theGroups)
1369 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupName",
1370 std::get<0>(theGroup.second));
1371 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupKey",
1372 std::get<1>(theGroup.second).toString());
1373 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupTime",
1374 std::get<2>(theGroup.second));
1407 handleOtherSubsystemActiveGroups(xmlOut, cfgMgr,
false );
1409 else if(requestType ==
"getSubsytemTableGroups")
1411 std::string subsystem =
1413 __SUP_COUTV__(subsystem);
1414 handleOtherSubsystemActiveGroups(
1415 xmlOut, cfgMgr,
true , subsystem);
1417 else if(requestType ==
"diffWithActiveGroup")
1419 std::string groupName =
1422 __SUP_COUTV__(groupName);
1423 __SUP_COUTV__(groupKey);
1428 else if(requestType ==
"diffWithGroupKey")
1430 std::string groupName =
1434 std::string diffGroupName =
1436 __SUP_COUTV__(groupName);
1437 __SUP_COUTV__(groupKey);
1438 __SUP_COUTV__(diffKey);
1439 __SUP_COUTV__(diffGroupName);
1441 handleGroupDiff(xmlOut,
1448 else if(requestType ==
"diffTableVersions")
1450 std::string tableName =
1454 __SUP_COUTV__(tableName);
1459 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1462 if(allTableInfo.find(tableName) != allTableInfo.end())
1464 if(vA.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1467 std::map<std::string ,
1471 std::string versionAlias;
1473 vA.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1475 if(versionAliases.find(tableName) != versionAliases.end() &&
1476 versionAliases[tableName].find(versionAlias) !=
1477 versionAliases[tableName].end())
1479 versionA = versionAliases[tableName][versionAlias];
1480 __SUP_COUT__ <<
"version alias translated to: " << versionA << __E__;
1483 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1484 <<
"'was not found in active version aliases!"
1488 versionA = atoi(vA.c_str());
1490 if(vB.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1493 std::map<std::string ,
1497 std::string versionAlias;
1499 vB.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1501 if(versionAliases.find(tableName) != versionAliases.end() &&
1502 versionAliases[tableName].find(versionAlias) !=
1503 versionAliases[tableName].end())
1505 versionB = versionAliases[tableName][versionAlias];
1506 __SUP_COUT__ <<
"version alias translated to: " << versionB << __E__;
1509 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1510 <<
"'was not found in active version aliases!"
1514 versionB = atoi(vB.c_str());
1518 versionA = atoi(vA.c_str());
1519 versionB = atoi(vB.c_str());
1522 __SUP_COUTV__(versionA);
1523 __SUP_COUTV__(versionB);
1525 handleTableDiff(xmlOut, cfgMgr, tableName, versionA, versionB);
1527 else if(requestType ==
"findGroupsWithTable")
1529 std::string tableName =
1531 std::string tableVersion =
1534 __SUP_COUTV__(tableName);
1535 __SUP_COUTV__(tableVersion);
1537 std::set<std::string> groupsContainingTable =
1538 cfgMgr->getConfigurationInterface()->findGroupsWithTable(
1540 __SUP_COUT__ <<
"Groups containing " << tableName <<
"-v" << tableVersion
1541 <<
" count: " << groupsContainingTable.size() << __E__;
1542 std::string groupsContainingTableString =
1544 __SUP_COUTTV__(groupsContainingTableString);
1546 xmlOut.addNumberElementToData(
"GroupsContainingCount",
1547 groupsContainingTable.size());
1548 xmlOut.addTextElementToData(
"GroupsContainingCSV", groupsContainingTableString);
1551 else if(requestType ==
"savePlanCommandSequence")
1554 std::string commands =
1560 __SUP_COUTV__(modifiedTables);
1561 __SUP_COUTV__(planName);
1562 __SUP_COUTV__(commands);
1563 __SUP_COUTV__(groupName);
1564 __SUP_COUTV__(groupKey);
1566 handleSavePlanCommandSequenceXML(xmlOut,
1575 else if(requestType ==
"mergeGroups")
1577 std::string groupANameContext =
1579 std::string groupAKeyContext =
1581 std::string groupBNameContext =
1583 std::string groupBKeyContext =
1585 std::string groupANameConfig =
1588 std::string groupBNameConfig =
1593 __SUP_COUTV__(groupANameContext);
1594 __SUP_COUTV__(groupAKeyContext);
1595 __SUP_COUTV__(groupBNameContext);
1596 __SUP_COUTV__(groupBKeyContext);
1597 __SUP_COUTV__(groupANameConfig);
1598 __SUP_COUTV__(groupAKeyConfig);
1599 __SUP_COUTV__(groupBNameConfig);
1600 __SUP_COUTV__(groupBKeyConfig);
1601 __SUP_COUTV__(mergeApproach);
1603 handleMergeGroupsXML(xmlOut,
1618 __SUP_SS__ <<
"requestType Request, " << requestType
1619 <<
", not recognized by the Configuration GUI Supervisor (was it "
1620 "intended for another Supervisor?)."
1622 __SUP_COUT__ <<
"\n" << ss.str();
1623 xmlOut.addTextElementToData(
"Error", ss.str());
1626 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1629 xmlOut, cfgMgr, userInfo.username_);
1630 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1633 catch(
const std::runtime_error& e)
1635 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1636 <<
".' Error: " << e.what() << __E__;
1637 __COUT_ERR__ <<
"\n" << ss.str();
1638 xmlOut.addTextElementToData(
"Error", ss.str());
1643 xmlOut.addTextElementToData(
1645 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1649 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1654 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1655 << requestType <<
".'" << __E__;
1660 catch(
const std::exception& e)
1662 ss <<
"Exception message: " << e.what();
1667 __COUT_ERR__ <<
"\n" << ss.str();
1668 xmlOut.addTextElementToData(
"Error", ss.str());
1673 xmlOut.addTextElementToData(
1675 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1679 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1699 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1702 const std::string& rootGroupName,
1704 const std::string& modifiedTables)
1707 __SUP_COUT__ <<
"rootGroupName " << rootGroupName <<
"(" << rootGroupKey
1708 <<
"). modifiedTables = " << modifiedTables << __E__;
1710 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1715 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT].second.isInvalid())
1717 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1718 if(cfgMgr->getFailedTableGroups().find(
1719 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT) !=
1720 cfgMgr->getFailedTableGroups().end())
1722 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1723 cfgMgr->getFailedTableGroups().at(
1724 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT);
1726 else if(cfgMgr->getFailedTableGroups().find(
1727 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1728 cfgMgr->getFailedTableGroups().end())
1730 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1731 cfgMgr->getFailedTableGroups().at(
1732 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1735 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION]
1736 .second.isInvalid())
1738 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1739 if(cfgMgr->getFailedTableGroups().find(
1740 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION) !=
1741 cfgMgr->getFailedTableGroups().end())
1743 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1744 cfgMgr->getFailedTableGroups().at(
1745 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION);
1747 else if(cfgMgr->getFailedTableGroups().find(
1748 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1749 cfgMgr->getFailedTableGroups().end())
1751 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1752 cfgMgr->getFailedTableGroups().at(
1753 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1762 std::map<std::string ,
TableVersion > rootGroupMemberMap;
1767 &rootGroupMemberMap,
1777 consideredGroups[groupType] =
1778 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1780 catch(
const std::runtime_error& e)
1783 if(rootGroupName.size())
1785 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1786 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1787 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1792 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1793 "name - assuming this was intentional."
1799 if(rootGroupName.size())
1801 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1802 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1807 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1808 "name - assuming this was intentional."
1812 std::map<std::string ,
1815 std::map<std::string ,
1817 modifiedTablesMapIt;
1819 std::istringstream f(modifiedTables);
1820 std::string table, version;
1821 while(getline(f, table,
','))
1823 getline(f, version,
',');
1824 modifiedTablesMap.insert(
1827 std::pair<bool /*foundAffectedGroup*/, TableVersion /*version*/>>(
1831 __SUP_COUT__ << modifiedTables << __E__;
1832 for(
auto& pair : modifiedTablesMap)
1833 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second.second
1838 xercesc::DOMElement* parentEl =
nullptr;
1839 std::string groupComment;
1840 std::vector<std::string> orderedGroupTypes(
1841 {ConfigurationManager::GROUP_TYPE_NAME_CONTEXT,
1842 ConfigurationManager::GROUP_TYPE_NAME_BACKBONE,
1843 ConfigurationManager::GROUP_TYPE_NAME_ITERATE,
1844 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION});
1845 for(
auto groupType : orderedGroupTypes)
1847 if(consideredGroups.find(groupType) == consideredGroups.end())
1850 const std::pair<std::string, TableGroupKey>& group = consideredGroups[groupType];
1852 if(group.second.isInvalid())
1855 __SUP_COUT__ <<
"Considering " << groupType <<
" group " << group.first <<
" ("
1856 << group.second <<
")" << __E__;
1874 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1876 for(
auto& table : memberMap)
1878 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1881 table.second != (*modifiedTablesMapIt).second.second)
1883 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1884 << (*modifiedTablesMapIt).second.second << __E__;
1886 memberMap[table.first] = (*modifiedTablesMapIt).second.second;
1887 (*modifiedTablesMapIt).second.first =
true;
1891 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1895 if(groupType == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
1897 __SUP_COUT__ <<
"Considering mockup tables for Configuration Group..."
1899 for(
auto& table : modifiedTablesMap)
1901 if(table.second.first)
1904 if(table.second.second.isMockupVersion() &&
1905 memberMap.find(table.first) == memberMap.end())
1907 __SUP_COUT__ <<
"Found mockup table '" << table.first
1908 <<
"' for Configuration Group." << __E__;
1909 memberMap[table.first] = table.second.second;
1912 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1916 "AddMemberVersion", table.second.second.toString(), parentEl);
1923 __SUP_COUTV__(affected);
1927 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1932 for(
auto& table : memberMap)
1936 "MemberVersion", table.second.toString(), parentEl);
1941 catch(std::runtime_error& e)
1943 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1944 xmlOut.addTextElementToData(
1945 "Error",
"Error getting affected groups! " + std::string(e.what()));
1949 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1950 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1961 void ConfigurationGUISupervisor::setupActiveTablesXML(
1964 const std::string& groupName,
1966 const std::string& modifiedTables,
1968 bool doGetGroupInfo,
1969 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1970 bool outputActiveTables,
1971 std::string* accumulatedErrors)
1974 xmlOut.addTextElementToData(
"tableGroup", groupName);
1975 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.
toString());
1977 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
1985 __SUP_COUT__ <<
"Refreshing all table info, ignoring warnings..." << __E__;
1986 std::string accumulatedWarnings =
"";
1988 &accumulatedWarnings,
2002 __SUP_COUT__ <<
"Restoring active table group tables..." << __E__;
2004 for(
const auto& activeGroup : activeGroups)
2006 if(activeGroup.second.first == groupName &&
2007 activeGroup.second.second == groupKey)
2009 __SUP_COUTT__ <<
"Skipping target active group." << __E__;
2012 __SUP_COUTT__ <<
"Loading " << activeGroup.first <<
" "
2013 << activeGroup.second.first <<
"(" << activeGroup.second.second
2018 activeGroup.second.second,
2024 __SUP_COUT__ <<
"Ignoring errors while setting up active tables for "
2025 << activeGroup.second.first <<
"("
2026 << activeGroup.second.second <<
")..." << __E__;
2032 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2034 std::map<std::string ,
TableVersion > modifiedTablesMap;
2036 modifiedTablesMapIt;
2038 if(usingActiveGroups)
2041 __SUP_COUT__ <<
"Using active groups." << __E__;
2045 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
2048 std::string groupComment, groupAuthor, tableGroupCreationTime, groupType;
2057 doGetGroupInfo ? &groupComment : 0,
2058 doGetGroupInfo ? &groupAuthor : 0,
2059 doGetGroupInfo ? &tableGroupCreationTime : 0,
2061 doGetGroupInfo ? &groupType : 0);
2065 xmlOut.addTextElementToData(
"tableGroupComment", groupComment);
2066 xmlOut.addTextElementToData(
"tableGroupAuthor", groupAuthor);
2067 xmlOut.addTextElementToData(
"tableGroupCreationTime", tableGroupCreationTime);
2068 xmlOut.addTextElementToData(
"tableGroupType", groupType);
2071 if(accumulatedErrors && *accumulatedErrors !=
"")
2072 __SUP_COUTV__(*accumulatedErrors);
2078 std::istringstream f(modifiedTables);
2079 std::string table, version;
2080 while(getline(f, table,
','))
2082 getline(f, version,
',');
2083 modifiedTablesMap.insert(
2084 std::pair<std::string /*name*/, TableVersion /*version*/>(
2088 for(
auto& pair : modifiedTablesMap)
2089 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
2094 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2095 xmlOut.addTextElementToData(
"DefaultNoLink",
2096 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
2099 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
2100 for(
const auto& tablePair : allActivePairs)
2101 orderedTableSet.emplace(tablePair.first);
2103 std::map<std::string, TableInfo>::const_iterator tableInfoIt;
2104 for(
auto& orderedTableName : orderedTableSet)
2106 tableInfoIt = allTableInfo.find(orderedTableName);
2107 if(tableInfoIt == allTableInfo.end())
2109 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
2114 if(outputActiveTables)
2115 xmlOut.addTextElementToData(
"ActiveTableName", orderedTableName);
2119 if((modifiedTablesMapIt = modifiedTablesMap.find(orderedTableName)) !=
2120 modifiedTablesMap.end())
2122 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
2123 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
2127 tableInfoIt->second.tablePtr_->setActiveView(
2128 (*modifiedTablesMapIt).second);
2132 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second
2133 <<
" failed. Reverting to v"
2134 << tableInfoIt->second.tablePtr_->getView().getVersion() <<
"."
2136 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
2137 xmlOut.addTextElementToData(
2139 "Error setting up active tables!\n\n" + std::string(ss.str()));
2143 if(outputActiveTables)
2145 xmlOut.addTextElementToData(
2146 "ActiveTableVersion",
2147 tableInfoIt->second.tablePtr_->getView().getVersion().toString());
2148 xmlOut.addTextElementToData(
2149 "ActiveTableComment",
2150 tableInfoIt->second.tablePtr_->getView().getAuthor() +
": " +
2151 tableInfoIt->second.tablePtr_->getView().getComment());
2159 catch(std::runtime_error& e)
2161 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
2163 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2164 xmlOut.addTextElementToData(
"Error", ss.str());
2169 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
2174 catch(
const std::exception& e)
2176 ss <<
"Exception message: " << e.what();
2181 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2182 xmlOut.addTextElementToData(
"Error", ss.str());
2201 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
2204 const std::string& groupName,
2206 const std::string& startPath,
2207 const std::string& modifiedTables,
2208 const std::string& recordList,
2209 const std::string& author)
2212 setupActiveTablesXML(xmlOut,
2227 __SUP_COUT__ << table->getTableName() << __E__;
2237 bool firstSave =
true;
2244 std::istringstream f(recordList);
2245 std::string recordUID;
2247 while(getline(f, recordUID,
','))
2251 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2256 .isTemporaryVersion())
2258 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2260 temporaryVersion = table->createTemporaryView(temporaryVersion);
2266 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2270 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2276 backupView.copy(table->getView(), temporaryVersion, author);
2285 unsigned int row = table->getViewP()->addRow(
2292 unsigned int col = table->getViewP()->getColStatus();
2293 table->getViewP()->setURIEncodedValue(
"1", row, col);
2300 table->getViewP()->setURIEncodedValue(
2301 recordUID, row, table->getViewP()->getColUID());
2309 table->getViewP()->init();
2313 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
2314 __SUP_COUT__ <<
"Before:" << __E__;
2315 table->getViewP()->print();
2316 table->getViewP()->copy(backupView, temporaryVersion, author);
2317 __SUP_COUT__ <<
"After:" << __E__;
2318 table->getViewP()->print();
2324 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2326 catch(std::runtime_error& e)
2328 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
2330 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2331 xmlOut.addTextElementToData(
"Error", ss.str());
2335 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
2340 catch(
const std::exception& e)
2342 ss <<
"Exception message: " << e.what();
2347 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2348 xmlOut.addTextElementToData(
"Error", ss.str());
2355 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
2360 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2361 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2362 for(
auto& activePair : allActivePairs)
2364 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
2365 xmlOut.addTextElementToData(
"NewActiveTableVersion",
2366 allTableInfo.at(activePair.first)
2367 .tablePtr_->getView()
2370 xmlOut.addTextElementToData(
2371 "NewActiveTableComment",
2372 allTableInfo.at(activePair.first).tablePtr_->getView().getAuthor() +
": " +
2373 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
2376 catch(std::runtime_error& e)
2378 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
2379 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2380 xmlOut.addTextElementToData(
"Error", ss.str());
2384 __SUP_SS__ << (
"Error!\n\n") << __E__;
2389 catch(
const std::exception& e)
2391 ss <<
"Exception message: " << e.what();
2396 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2397 xmlOut.addTextElementToData(
"Error", ss.str());
2415 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
2418 const std::string& groupName,
2420 const std::string& startPath,
2421 const std::string& modifiedTables,
2422 const std::string& recordList)
2425 setupActiveTablesXML(xmlOut,
2440 __SUP_COUT__ << table->getTableName() << __E__;
2450 bool firstSave =
true;
2454 std::istringstream f(recordList);
2455 std::string recordUID;
2458 while(getline(f, recordUID,
','))
2462 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2467 .isTemporaryVersion())
2469 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2471 temporaryVersion = table->createTemporaryView(temporaryVersion);
2477 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2481 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2492 table->getViewP()->findRow(table->getViewP()->getColUID(), recordUID);
2493 table->getViewP()->deleteRow(row);
2498 table->getViewP()->init();
2500 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2502 catch(std::runtime_error& e)
2504 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
2505 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2506 xmlOut.addTextElementToData(
"Error", ss.str());
2510 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
2515 catch(
const std::exception& e)
2517 ss <<
"Exception message: " << e.what();
2522 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2523 xmlOut.addTextElementToData(
"Error", ss.str());
2543 void ConfigurationGUISupervisor::handleFillRenameTreeNodeRecordsXML(
2546 const std::string& groupName,
2548 const std::string& startPath,
2549 const std::string& modifiedTables,
2550 const std::string& recordList,
2551 const std::string& newRecordList)
2554 setupActiveTablesXML(xmlOut,
2569 __SUP_COUT__ << table->getTableName() << __E__;
2580 std::vector<std::string> recordArray =
2582 std::vector<std::string> newRecordArray =
2588 if(recordArray.size() == 0 || recordArray.size() != newRecordArray.size())
2591 <<
"Invalid record size vs new record name size, they must be the same: "
2592 << recordArray.size() <<
" vs " << newRecordArray.size() << __E__;
2598 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2600 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2602 temporaryVersion = table->createTemporaryView(temporaryVersion);
2608 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2611 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2618 for(
unsigned int i = 0; i < recordArray.size(); ++i)
2620 row = table->getViewP()->findRow(
2621 table->getViewP()->getColUID(),
2624 table->getViewP()->setValueAsString(
2625 newRecordArray[i], row, table->getViewP()->getColUID());
2628 table->getViewP()->init();
2630 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2632 catch(std::runtime_error& e)
2634 __SUP_SS__ << (
"Error renaming record(s)!\n\n" + std::string(e.what())) << __E__;
2635 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2636 xmlOut.addTextElementToData(
"Error", ss.str());
2640 __SUP_SS__ << (
"Error renaming record(s)!\n\n") << __E__;
2645 catch(
const std::exception& e)
2647 ss <<
"Exception message: " << e.what();
2652 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2653 xmlOut.addTextElementToData(
"Error", ss.str());
2674 void ConfigurationGUISupervisor::handleFillCopyTreeNodeRecordsXML(
2677 const std::string& groupName,
2679 const std::string& startPath,
2680 const std::string& modifiedTables,
2681 const std::string& recordList,
2682 unsigned int numberOfCopies )
2688 setupActiveTablesXML(xmlOut,
2703 __SUP_COUT__ << table->getTableName() << __E__;
2714 std::vector<std::string> recordArray =
2720 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2722 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2724 temporaryVersion = table->createTemporaryView(temporaryVersion);
2730 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2733 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2740 for(
const auto& recordUID : recordArray)
2742 row = table->getViewP()->findRow(table->getViewP()->getColUID(),
2744 for(
unsigned int i = 0; i < numberOfCopies; ++i)
2745 table->getViewP()->copyRows(
2755 table->getViewP()->init();
2757 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2759 catch(std::runtime_error& e)
2761 __SUP_SS__ << (
"Error copying record(s)!\n\n" + std::string(e.what())) << __E__;
2762 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2763 xmlOut.addTextElementToData(
"Error", ss.str());
2767 __SUP_SS__ << (
"Error copying record(s)!\n\n") << __E__;
2772 catch(
const std::exception& e)
2774 ss <<
"Exception message: " << e.what();
2779 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2780 xmlOut.addTextElementToData(
"Error", ss.str());
2801 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2804 const std::string& groupName,
2806 const std::string& startPath,
2807 const std::string& modifiedTables,
2808 const std::string& recordList,
2809 const std::string& fieldList,
2810 const std::string& valueList,
2811 const std::string& author)
2814 setupActiveTablesXML(xmlOut,
2829 std::vector<std::string > fieldPaths;
2832 std::istringstream f(fieldList);
2833 std::string fieldPath;
2834 while(getline(f, fieldPath,
','))
2838 __SUP_COUT__ << fieldList << __E__;
2839 for(
const auto& field : fieldPaths)
2840 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2843 std::vector<std::string > fieldValues;
2846 std::istringstream f(valueList);
2847 std::string fieldValue;
2848 while(getline(f, fieldValue,
','))
2850 fieldValues.push_back(fieldValue);
2855 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2856 fieldValues.push_back(
"");
2858 __SUP_COUT__ << valueList << __E__;
2859 for(
const auto& value : fieldValues)
2860 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2863 if(fieldPaths.size() != fieldValues.size())
2866 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2873 std::istringstream f(recordList);
2874 std::string recordUID;
2877 while(getline(f, recordUID,
','))
2882 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2885 for(i = 0; i < fieldPaths.size(); ++i)
2887 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2888 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2893 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2934 if(!(temporaryVersion = table->getViewP()->getVersion())
2935 .isTemporaryVersion())
2939 table->createTemporaryView(table->getViewP()->getVersion());
2945 __SUP_COUT__ <<
"Created temporary version "
2946 << table->getTableName() <<
"-v" << temporaryVersion
2950 __SUP_COUT__ <<
"Using temporary version " << table->getTableName()
2951 <<
"-v" << temporaryVersion << __E__;
2955 table->getViewP()->setURIEncodedValue(fieldValues[i],
2966 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2968 catch(std::runtime_error& e)
2970 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2972 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2973 xmlOut.addTextElementToData(
"Error", ss.str());
2977 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2982 catch(
const std::exception& e)
2984 ss <<
"Exception message: " << e.what();
2989 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2990 xmlOut.addTextElementToData(
"Error", ss.str());
3009 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
3012 const std::string& groupName,
3014 const std::string& startPath,
3015 const std::string& modifiedTables,
3016 const std::string& recordList,
3017 const std::string& fieldList)
3020 setupActiveTablesXML(
3021 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3028 std::vector<std::string > fieldPaths;
3031 std::istringstream f(fieldList);
3032 std::string fieldPath;
3033 while(getline(f, fieldPath,
','))
3037 __SUP_COUT__ << fieldList << __E__;
3042 std::istringstream f(recordList);
3043 std::string recordUID;
3044 while(getline(f, recordUID,
','))
3048 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
3050 xercesc::DOMElement* parentEl =
3051 xmlOut.addTextElementToData(
"fieldValues", recordUID);
3054 for(
const auto& fieldPath : fieldPaths)
3060 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
3072 catch(std::runtime_error& e)
3074 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
3076 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3077 xmlOut.addTextElementToData(
"Error", ss.str());
3081 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
3086 catch(
const std::exception& e)
3088 ss <<
"Exception message: " << e.what();
3093 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3094 xmlOut.addTextElementToData(
"Error", ss.str());
3117 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
3120 const std::string& groupName,
3122 const std::string& startPath,
3124 const std::string& modifiedTables,
3125 const std::string& recordList,
3126 const std::string& fieldList)
3129 setupActiveTablesXML(
3130 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3134 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
3138 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
3139 __SUP_COUT__ << ss.str();
3148 std::vector<ConfigurationTree::RecordField> retFieldList;
3154 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3160 std::vector<std::string > fieldAcceptList, fieldRejectList;
3165 std::istringstream f(fieldList);
3166 std::string fieldPath, decodedFieldPath;
3167 while(getline(f, fieldPath,
','))
3171 if(decodedFieldPath[0] ==
'!')
3172 fieldRejectList.push_back(decodedFieldPath.substr(1));
3174 fieldAcceptList.push_back(decodedFieldPath);
3176 __SUP_COUT__ << fieldList << __E__;
3177 for(
auto& field : fieldAcceptList)
3178 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
3179 for(
auto& field : fieldRejectList)
3180 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
3184 std::vector<std::string > records;
3185 if(recordList ==
"*")
3189 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3190 for(
auto& record : records)
3191 __SUP_COUT__ <<
"recordList " << record << __E__;
3193 else if(recordList !=
"")
3197 std::istringstream f(recordList);
3198 std::string recordStr;
3199 while(getline(f, recordStr,
','))
3203 __SUP_COUT__ << recordList << __E__;
3204 for(
auto& record : records)
3205 __SUP_COUT__ <<
"recordList " << record << __E__;
3211 records, fieldAcceptList, fieldRejectList, depth);
3215 xercesc::DOMElement* parentTypeEl;
3216 for(
const auto& fieldInfo : retFieldList)
3219 "FieldTableName", fieldInfo.tableName_, parentEl);
3221 "FieldColumnName", fieldInfo.columnName_, parentEl);
3223 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
3225 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
3227 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
3229 fieldInfo.columnInfo_->getDefaultValue(),
3236 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
3238 "FieldColumnDataChoice",
3239 fieldInfo.columnInfo_->getDefaultValue(),
3241 for(
const auto& dataChoice : dataChoices)
3243 "FieldColumnDataChoice", dataChoice, parentTypeEl);
3246 catch(std::runtime_error& e)
3248 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3250 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3251 xmlOut.addTextElementToData(
"Error", ss.str());
3255 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3260 catch(
const std::exception& e)
3262 ss <<
"Exception message: " << e.what();
3267 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3268 xmlOut.addTextElementToData(
"Error", ss.str());
3300 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
3303 const std::string& groupName,
3305 const std::string& startPath,
3306 const std::string& modifiedTables,
3307 const std::string& recordList,
3308 const std::string& fieldList)
3311 setupActiveTablesXML(
3312 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3318 if(startPath ==
"/")
3324 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3325 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3330 std::vector<std::string > records;
3331 if(recordList ==
"*")
3335 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3336 for(
auto& record : records)
3337 __SUP_COUT__ <<
"recordList " << record << __E__;
3339 else if(recordList !=
"")
3343 std::istringstream f(recordList);
3344 std::string recordStr;
3345 while(getline(f, recordStr,
','))
3349 __SUP_COUT__ << recordList << __E__;
3350 for(
auto& record : records)
3351 __SUP_COUT__ <<
"recordList " << record << __E__;
3356 std::vector<std::string > fieldsToGet;
3361 if(fieldList ==
"AUTO")
3366 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
3368 std::vector<ConfigurationTree::RecordField> retFieldList;
3369 std::vector<std::string > fieldAcceptList,
3371 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
3373 records, fieldAcceptList, fieldRejectList, 5,
true );
3375 for(
const auto& retField : retFieldList)
3376 fieldsToGet.push_back(retField.relativePath_ + retField.columnName_);
3380 std::istringstream f(fieldList);
3381 std::string fieldPath;
3382 while(getline(f, fieldPath,
','))
3386 __SUP_COUTV__(fieldList);
3395 std::string fieldGroupIDChildLinkIndex;
3396 for(
auto& field : fieldsToGet)
3398 __SUP_COUTV__(field);
3400 xercesc::DOMElement* parentEl =
3401 xmlOut.addTextElementToData(
"field", field);
3407 std::set<std::string > uniqueValues =
3409 records, field, &fieldGroupIDChildLinkIndex);
3411 if(fieldGroupIDChildLinkIndex !=
"")
3413 "childLinkIndex", fieldGroupIDChildLinkIndex, parentEl);
3415 for(
auto& uniqueValue : uniqueValues)
3417 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
3424 catch(std::runtime_error& e)
3426 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3427 <<
"' and field list '" << fieldList <<
"!'\n\n"
3428 << e.what() << __E__;
3429 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3430 xmlOut.addTextElementToData(
"Error", ss.str());
3434 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3435 <<
"' and field list '" << fieldList <<
"!'\n\n"
3441 catch(
const std::exception& e)
3443 ss <<
"Exception message: " << e.what();
3448 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3449 xmlOut.addTextElementToData(
"Error", ss.str());
3473 void ConfigurationGUISupervisor::handleFillTreeViewXML(
3476 const std::string& groupName,
3478 const std::string& startPath,
3480 bool hideStatusFalse,
3481 const std::string& modifiedTables,
3482 const std::string& filterList,
3483 const std::string& diffGroupName ,
3486 __SUP_COUTT__ <<
"get Tree View: " << groupName <<
"(" << groupKey <<
")" << __E__;
3518 bool doDiff = (diffGroupName !=
"" && !diffGroupKey.
isInvalid());
3523 std::string diffAccumulateErrors;
3531 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3548 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3551 __SUP_COUTT__ <<
"Diff Group tables loaded." << __E__;
3553 *cfgMgr, diffMemberMap, diffGroupName, diffGroupKey);
3554 __SUP_COUTT__ <<
"Diff Group tables copied to local diff config manager."
3558 for(
auto& memberPair : diffMemberMap)
3560 ->setActiveView(memberPair.second);
3562 for(
const auto& lastGroupLoaded : cfgMgr->getLastTableGroups())
3563 __SUP_COUT__ <<
"cfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3564 << lastGroupLoaded.second.first.first <<
"("
3565 << lastGroupLoaded.second.first.second <<
")";
3567 for(
const auto& lastGroupLoaded : diffCfgMgr->getLastTableGroups())
3568 __SUP_COUT__ <<
"diffCfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3569 << lastGroupLoaded.second.first.first <<
"("
3570 << lastGroupLoaded.second.first.second <<
")";
3573 if(diffCfgMgr->getLastTableGroups().size() == 1)
3575 __SUP_COUT__ <<
"Type already loaded to diff = "
3576 << diffCfgMgr->getLastTableGroups().begin()->first << __E__;
3579 auto groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3580 if(diffCfgMgr->getLastTableGroups().begin()->first ==
3581 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
3582 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION;
3583 else if(diffCfgMgr->getLastTableGroups().begin()->first ==
3584 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3585 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3588 <<
"Loading " << groupTypeToLoad
3589 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first <<
"("
3590 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second
3595 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second,
3596 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first,
3597 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second);
3600 for(
auto& memberPair :
3601 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second)
3603 ->setActiveView(memberPair.second);
3611 __SUP_COUTT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3614 __SUP_COUTT__ <<
"diffCfgMgr " << activeTable.first <<
"-v"
3615 << activeTable.second << __E__;
3617 __SUP_COUTT__ <<
"Diff Group tables are setup: " << diffAccumulateErrors << __E__;
3622 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
3625 std::string accumulatedErrors =
"";
3626 setupActiveTablesXML(
3639 if(memberMap.size() > ConfigurationManager::getFixedContextMemberNames().size() +
3641 && startPath ==
"/")
3643 __COUTT__ <<
"Checking for orphaned tables..." << __E__;
3646 std::set<std::string > linkingTables;
3651 __COUTS__(30) <<
"Table " << tableInfo.first << __E__;
3652 if(!tableInfo.second.tablePtr_->isActive())
3655 __COUTS__(30) <<
"Table active " << tableInfo.first << __E__;
3657 const TableView& view = tableInfo.second.tablePtr_->getView();
3659 bool addedThisTable =
false;
3660 for(
unsigned int col = 0; col < view.getNumberOfColumns(); ++col)
3662 if(!view.getColumnInfo(col).isChildLink())
3665 __COUTS__(30) <<
"Table " << tableInfo.first
3666 <<
" col: " << view.getColumnInfo(col).getName() << __E__;
3668 for(
unsigned int r = 0; r < view.getNumberOfRows(); ++r)
3670 if(view.getDataView()[r][col] ==
"" ||
3671 view.getDataView()[r][col] ==
3672 TableViewColumnInfo::DATATYPE_STRING_DEFAULT ||
3673 view.getDataView()[r][col] ==
3674 TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT)
3679 linkingTables.emplace(tableInfo.first);
3680 addedThisTable =
true;
3682 linkingTables.emplace(
3683 view.getDataView()[r][col]);
3689 std::string missingTables =
"";
3690 for(
const auto& member : memberMap)
3693 if(linkingTables.find(member.first) != linkingTables.end())
3696 if(missingTables.size())
3697 missingTables +=
", ";
3698 missingTables += member.first;
3701 if(missingTables.size())
3703 __COUTV__(missingTables);
3704 std::stringstream ss;
3705 ss <<
"The following member tables of table group '" << groupName <<
"("
3707 <<
")' were identified as possibly orphaned (i.e. no active tables link "
3708 "to these tables, and these tables have no links to other tables):\n\n"
3709 << missingTables <<
".\n"
3711 xmlOut.addTextElementToData(
"NoTreeLinkWarning", ss.str());
3715 if(accumulatedErrors !=
"")
3717 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
3719 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
3722 __SUP_COUT__ <<
"Active table versions: "
3727 __SUP_COUTT__ <<
"Active tables are setup. No issues found." << __E__;
3728 __SUP_COUTT__ <<
"Active table versions: "
3734 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
3739 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
3740 std::map<std::string, ConfigurationTree> diffRootMap;
3742 if(startPath ==
"/")
3746 std::string accumulateTreeErrs;
3748 if(usingActiveGroups)
3749 rootMap = cfgMgr->
getChildren(0, &accumulateTreeErrs);
3751 rootMap = cfgMgr->
getChildren(&memberMap, &accumulateTreeErrs);
3756 diffCfgMgr->
getChildrenMap(&diffMemberMap, &diffAccumulateErrors);
3757 __SUP_COUTV__(diffRootMap.size());
3758 for(
auto& diffChild : diffRootMap)
3759 __SUP_COUTV__(diffChild.first);
3762 __SUP_COUTV__(accumulateTreeErrs);
3764 if(accumulateTreeErrs !=
"")
3765 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
3770 cfgMgr->
getNode(startPath,
true );
3773 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
3778 std::map<std::string , std::string > filterMap;
3782 std::set<char>({
';'}) ,
3783 std::set<char>({
'='}) );
3797 __SUP_COUTT__ <<
"Diff Group disconnected node." << __E__;
3802 catch(
const std::runtime_error& e)
3805 __SUP_COUTT__ <<
"Diff Group node does not exist." << __E__;
3812 for(
auto& treePair : rootMap)
3814 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
3818 __SUP_COUTT__ <<
"Diff Tree recursive handling." << __E__;
3821 std::set<std::string > rootMapToSearch;
3822 for(
const auto& rootMember : rootMap)
3823 rootMapToSearch.emplace(rootMember.first);
3825 std::stringstream rootSs;
3826 for(
const auto& rootMember : rootMap)
3827 rootSs <<
", " << rootMember.first;
3830 std::stringstream diffRootSs;
3831 for(
const auto& diffMember : diffRootMap)
3833 diffRootSs <<
", " << diffMember.first <<
":"
3834 << diffMember.second.getNodeType();
3835 if(rootMapToSearch.find(diffMember.first) ==
3839 std::stringstream missingSs;
3840 missingSs << diffMember.first <<
3842 " <<< Only in " << diffGroupName <<
"(" << diffGroupKey
3845 "diffNodeMissing", missingSs.str(), parentEl);
3848 if(diffMember.second.getNodeType() ==
"UIDLinkNode")
3859 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3860 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3862 __SUP_COUTT__ <<
"\t\t" << diffMember.second.getValueName() <<
": "
3863 << diffMember.second.getValueAsString() << __E__;
3865 __SUP_COUTT__ << diffMember.second.nodeDump();
3869 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3870 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3873 for(
auto& treePair : rootMap)
3875 if(diffRootMap.find(treePair.first) == diffRootMap.end())
3877 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3890 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3892 recursiveTreeToXML(treePair.second,
3897 diffRootMap.at(treePair.first));
3902 catch(std::runtime_error& e)
3904 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
3905 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3906 xmlOut.addTextElementToData(
"Error", ss.str());
3910 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
3915 catch(
const std::exception& e)
3917 ss <<
"Exception message: " << e.what();
3922 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3923 xmlOut.addTextElementToData(
"Error", ss.str());
3933 void ConfigurationGUISupervisor::recursiveTreeToXML(
3937 xercesc::DOMElement* parentEl,
3938 bool hideStatusFalse,
3939 std::optional<std::reference_wrapper<const ConfigurationTree>> diffTree)
3949 if(diffTree.has_value() &&
3950 t.
getValueName() != TableViewColumnInfo::COL_NAME_COMMENT &&
3951 t.
getValueName() != TableViewColumnInfo::COL_NAME_AUTHOR &&
3952 t.
getValueName() != TableViewColumnInfo::COL_NAME_CREATION)
3954 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
3956 if(diffTree->get().isValueNode())
3958 __COUTS__(30) <<
"\t" << diffTree->get().getValueAsString() <<
" ? "
3960 __COUTS__(30) <<
"\t" << diffTree->get().getTableName() <<
"-v"
3961 << diffTree->get().getTableVersion() <<
" ? "
3966 std::stringstream missingSs;
3967 auto diffGroupPair =
3968 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3969 diffTree->get().getTableName());
3970 missingSs <<
"<<< '" << diffTree->get().getValueAsString() <<
"' in "
3971 << diffGroupPair.first <<
"(" << diffGroupPair.second
3978 std::stringstream missingSs;
3980 auto diffGroupPair =
3981 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3983 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3984 << diffGroupPair.second <<
") >>>";
3998 if(t.
getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
3999 t.
getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
4004 for(
const auto& choice : choices)
4021 if(diffTree.has_value())
4023 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType()
4030 std::stringstream missingSs;
4032 auto diffGroupPair =
4033 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4035 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
4036 << diffGroupPair.second <<
") >>>";
4041 __COUTS__(30) <<
"\t\t diff isDisconnected "
4042 << diffTree->get().isDisconnected() << __E__;
4044 std::stringstream missingSs;
4046 auto diffGroupPair =
4047 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4049 missingSs <<
"<<< Link is "
4050 << (diffTree->get().isDisconnected() ?
"DISCONNECTED"
4052 <<
" in " << diffGroupPair.first <<
"("
4053 << diffGroupPair.second <<
") >>>";
4060 std::stringstream missingSs;
4062 auto diffGroupPair =
4063 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4065 missingSs <<
"<<< Link is "
4066 << (diffTree->get().isUIDLinkNode() ?
"a UID Link"
4068 <<
" in " << diffGroupPair.first <<
"("
4069 << diffGroupPair.second <<
") >>>";
4074 diffTree->get().getValueAsString())
4077 std::stringstream missingSs;
4079 auto diffGroupPair =
4080 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4082 missingSs <<
"<<< Link to '" << diffTree->get().getValueAsString()
4083 <<
"' in " << diffGroupPair.first <<
"("
4084 << diffGroupPair.second <<
") >>>";
4090 std::stringstream missingSs;
4093 auto dtchildren = diffTree->get().getChildrenMap();
4094 missingSs <<
"<<< Group link";
4095 if(tchildren.size() != dtchildren.size())
4096 missingSs <<
" has " << tchildren.size() <<
" vs "
4097 << dtchildren.size() <<
" children..";
4098 for(
auto& tchild : tchildren)
4099 if(dtchildren.find(tchild.first) == dtchildren.end())
4100 missingSs <<
" '" << tchild.first <<
"' missing..";
4101 for(
auto& dtchild : dtchildren)
4102 if(tchildren.find(dtchild.first) == tchildren.end())
4103 missingSs <<
" '" << dtchild.first <<
"' present...";
4106 if(missingSs.str().length() > std::string(
"<<< Group link").length())
4108 auto diffGroupPair =
4110 .getConfigurationManager()
4111 ->getGroupOfLoadedTable(diffTree->get().getTableName());
4112 missingSs <<
" in " << diffGroupPair.first <<
"("
4113 << diffGroupPair.second <<
") >>>";
4115 "nodeDiff", missingSs.str(), parentEl);
4143 xercesc::DOMElement* choicesParentEl =
4149 __COUTS__(30) <<
"choices.size() " << choices.size() << __E__;
4151 for(
const auto& choice : choices)
4173 xercesc::DOMElement* choicesParentEl =
4177 for(
const auto& choice : choices)
4184 bool returnNode =
true;
4198 "nodeStatus", t.
isEnabled() ?
"1" :
"0", parentEl);
4201 if(diffTree.has_value())
4204 <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
4213 auto diffGroupPair =
4215 .getConfigurationManager()
4217 missingSs <<
"<<< Not in " << diffGroupPair.first <<
"("
4218 << diffGroupPair.second <<
") >>>";
4220 "nodeDiff", missingSs.str(), parentEl);
4254 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
4257 const std::string& linkToTableName,
4259 const std::string& linkIdType,
4260 const std::string& linkIndex,
4261 const std::string& linkInitId)
4274 const std::string& tableName = linkToTableName;
4279 table->setActiveView(version);
4283 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
4284 << version << __E__;
4288 if(version != table->getViewVersion())
4290 __SUP_SS__ <<
"Target table version (" << version
4291 <<
") is not the currently active version (" << table->getViewVersion()
4292 <<
". Try refreshing the tree." << __E__;
4293 __SUP_COUT_WARN__ << ss.str();
4297 __SUP_COUT__ <<
"Active version is " << table->getViewVersion() << __E__;
4299 if(linkIdType ==
"UID")
4302 unsigned int col = table->getView().getColUID();
4303 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4304 xmlOut.addTextElementToData(
"linkToChoice",
4305 table->getView().getDataView()[row][col]);
4307 else if(linkIdType ==
"GroupID")
4313 __SUP_COUTV__(linkIndex);
4314 __SUP_COUTV__(linkInitId);
4316 std::set<std::string> setOfGroupIDs =
4317 table->getView().getSetOfGroupIDs(linkIndex);
4322 bool foundInitId =
false;
4323 for(
const auto& groupID : setOfGroupIDs)
4325 if(!foundInitId && linkInitId == groupID)
4328 xmlOut.addTextElementToData(
"linkToChoice", groupID);
4332 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
4335 unsigned int col = table->getView().getColUID();
4336 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4338 xmlOut.addTextElementToData(
"groupChoice",
4339 table->getView().getDataView()[row][col]);
4340 if(table->getView().isEntryInGroup(row, linkIndex, linkInitId))
4341 xmlOut.addTextElementToData(
"groupMember",
4342 table->getView().getDataView()[row][col]);
4347 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
4351 catch(std::runtime_error& e)
4353 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
4354 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4355 xmlOut.addTextElementToData(
"Error", ss.str());
4359 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
4364 catch(
const std::exception& e)
4366 ss <<
"Exception message: " << e.what();
4371 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4372 xmlOut.addTextElementToData(
"Error", ss.str());
4377 void ConfigurationGUISupervisor::handleMergeGroupsXML(
4380 const std::string& groupANameContext,
4382 const std::string& groupBNameContext,
4384 const std::string& groupANameConfig,
4386 const std::string& groupBNameConfig,
4388 const std::string& author,
4389 const std::string& mergeApproach)
4392 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
4393 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4394 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4395 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4396 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4412 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
4413 mergeApproach ==
"Skip"))
4415 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
4419 std::map<std::string ,
TableVersion > memberMapAContext,
4420 memberMapBContext, memberMapAConfig, memberMapBConfig;
4423 bool skippingContextPair =
false;
4424 bool skippingConfigPair =
false;
4425 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
4426 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
4428 skippingContextPair =
true;
4429 __SUP_COUTV__(skippingContextPair);
4431 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
4432 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
4434 skippingConfigPair =
true;
4435 __SUP_COUTV__(skippingConfigPair);
4439 if(!skippingContextPair)
4472 if(!skippingConfigPair)
4509 std::map<std::pair<std::string , std::string >,
4513 std::pair<std::string ,
4514 std::pair<std::string , std::string >>,
4516 groupidConversionMap;
4518 std::stringstream mergeReport;
4519 mergeReport <<
"======================================" << __E__;
4521 mergeReport <<
"Merging context group pair " << groupANameContext <<
" ("
4522 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4523 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4524 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4525 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4526 mergeReport <<
"======================================" << __E__;
4530 for(
unsigned int i = 0; i < 2; ++i)
4532 if(i == 0 && mergeApproach !=
"Rename")
4536 for(
unsigned int j = 0; j < 2; ++j)
4538 if(j == 0 && skippingContextPair)
4540 __COUT__ <<
"Skipping context pair..." << __E__;
4543 else if(j == 1 && skippingConfigPair)
4545 __COUT__ <<
"Skipping table pair..." << __E__;
4550 j == 0 ? memberMapAContext : memberMapAConfig;
4553 j == 0 ? memberMapBContext : memberMapBConfig;
4556 __COUT__ <<
"Context pair..." << __E__;
4558 __COUT__ <<
"Table pair..." << __E__;
4560 __COUT__ <<
"Starting member map B scan." << __E__;
4561 for(
const auto& bkey : memberMapBref)
4563 __SUP_COUTV__(bkey.first);
4565 if(memberMapAref.find(bkey.first) == memberMapAref.end())
4567 mergeReport <<
"\n'" << mergeApproach <<
"'-Missing table '"
4568 << bkey.first <<
"' A=v" << -1 <<
", adding B=v"
4569 << bkey.second << __E__;
4572 memberMapAref[bkey.first] = bkey.second;
4574 else if(memberMapAref[bkey.first] != bkey.second)
4577 __SUP_COUTV__(memberMapAref[bkey.first]);
4578 __SUP_COUTV__(bkey.second);
4583 __SUP_COUT__ <<
"Got table." << __E__;
4587 ->getVersionedTableByName(bkey.first,
4588 memberMapAref[bkey.first])
4594 mergeApproach ==
"Rename"
4595 ? TableBase::MergeApproach::RENAME
4596 : (mergeApproach ==
"Replace"
4597 ? TableBase::MergeApproach::REPLACE
4598 : TableBase::MergeApproach::SKIP),
4600 groupidConversionMap,
4603 table->getTableName() ==
4604 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME
4610 __SUP_COUTV__(newVersion);
4628 catch(std::runtime_error& e)
4631 <<
"There was an error saving the '"
4632 << table->getTableName()
4633 <<
"' merge result to a persistent table version. "
4634 <<
"Perhaps you can modify this table in one of the "
4635 "groups to resolve this issue, and then re-merge."
4636 << __E__ << e.what();
4640 __SUP_COUTV__(newVersion);
4642 memberMapAref[bkey.first] = newVersion;
4651 if(!skippingContextPair)
4653 __SUP_COUT__ <<
"New context member map complete." << __E__;
4660 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.
toString() +
4661 ") and " + groupBNameContext +
" (" + groupBKeyContext.
toString() +
").");
4664 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
4665 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.
toString());
4667 if(!skippingConfigPair)
4669 __SUP_COUT__ <<
"New table member map complete." << __E__;
4676 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.
toString() +
4677 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.
toString() +
").");
4680 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
4681 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.
toString());
4686 std::string mergeReportBasePath = std::string(__ENV__(
"USER_DATA"));
4687 std::string mergeReportPath =
"/ServiceData/";
4689 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4690 mergeReportPath +=
"ConfigurationGUI_mergeReports/";
4692 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4695 "merge_" + std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
4696 __SUP_COUTV__(mergeReportPath);
4698 FILE* fp = fopen((mergeReportBasePath + mergeReportPath).c_str(),
"w");
4701 fprintf(fp,
"%s", mergeReport.str().c_str());
4703 xmlOut.addTextElementToData(
"MergeReportFile",
4704 "/$USER_DATA/" + mergeReportPath);
4707 xmlOut.addTextElementToData(
"MergeReportFile",
"FILE FAILURE");
4711 catch(std::runtime_error& e)
4713 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
4714 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4715 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4716 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4717 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
4718 << e.what() << __E__;
4719 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4720 xmlOut.addTextElementToData(
"Error", ss.str());
4724 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
4725 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4726 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4727 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4728 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
4733 catch(
const std::exception& e)
4735 ss <<
"Exception message: " << e.what();
4740 __SUP_COUT_ERR__ <<
"\n" << ss.
str() << __E__;
4741 xmlOut.addTextElementToData(
"Error", ss.str());
4746 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
4749 const std::string& groupName,
4751 const std::string& modifiedTables,
4752 const std::string& author,
4753 const std::string& planName,
4754 const std::string& commandString)
4757 __COUT__ <<
"handleSavePlanCommandSequenceXML " << planName << __E__;
4760 setupActiveTablesXML(xmlOut,
4779 for(
const auto& commandPair : IterateTable::commandToTableMap_)
4780 if(commandPair.second !=
"")
4781 commandTableToEditMap.emplace(std::pair<std::string, TableEditStruct>(
4798 std::string groupName = planName +
"-Plan";
4799 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
4801 unsigned int groupIdCol =
4802 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
4803 unsigned int cmdTypeCol =
4804 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
4806 unsigned int targetGroupIdCol =
4807 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
4808 unsigned int targetTableCol =
4809 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
4810 unsigned int targetUIDCol =
4811 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
4813 std::string groupLinkIndex =
4814 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
4815 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
4817 std::pair<
unsigned int ,
unsigned int > commandUidLink;
4820 planTable.tableView_->getChildLink(
4821 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
4826 unsigned int cmdRow, cmdCol;
4827 std::string targetGroupName;
4831 std::string targetUID, cmdType;
4833 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
4836 targetUID = planTable.tableView_
4837 ->getDataView()[row][planTable.tableView_->getColUID()];
4838 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4841 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
4843 __SUP_COUT__ <<
"Removing." << __E__;
4847 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
4848 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(cmdType);
4849 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4850 cmdTypeTableIt->second !=
4854 commandTableToEditMap.at(cmdTypeTableIt->second);
4855 cmdRow = cmdTypeTableEdit.tableView_->findRow(
4856 cmdTypeTableEdit.tableView_->getColUID(),
4857 planTable.tableView_
4858 ->getDataView()[row][commandUidLink.second]);
4865 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4866 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4867 targetGroupName = cmdTypeTableEdit.tableView_
4868 ->getDataView()[cmdRow][cmdCol];
4870 for(
unsigned int trow = 0;
4871 trow < targetTable.tableView_->getNumberOfRows();
4875 if(targetTable.tableView_->isEntryInGroup(
4877 cmdTypeTableEdit.tableView_->getColumnInfo(cmdCol)
4878 .getChildLinkIndex(),
4881 __SUP_COUT__ <<
"Removing target." << __E__;
4883 if(targetTable.tableView_->removeRowFromGroup(
4894 __SUP_COUT__ <<
"No targets." << __E__;
4899 cmdTypeTableEdit.tableView_->deleteRow(cmdRow);
4905 if(planTable.tableView_->removeRowFromGroup(
4906 row, groupIdCol, groupName,
true ))
4915 std::vector<IterateTable::Command> commands;
4920 std::istringstream f(commandString);
4921 std::string commandSubString, paramSubString, paramValue;
4923 while(getline(f, commandSubString,
';'))
4925 __SUP_COUTT__ <<
"commandSubString " << commandSubString << __E__;
4926 std::istringstream g(commandSubString);
4929 while(getline(g, paramSubString,
','))
4931 __SUP_COUTT__ <<
"paramSubString " << paramSubString << __E__;
4934 if(paramSubString !=
"type")
4936 __SUP_SS__ <<
"Invalid command sequence" << __E__;
4940 commands.push_back(IterateTable::Command());
4942 getline(g, paramValue,
',');
4944 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4945 commands.back().type_ = paramValue;
4949 getline(g, paramValue,
',');
4951 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4953 commands.back().params_.emplace(
4954 std::pair<std::string ,
4966 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
4973 unsigned int row, tgtRow;
4974 unsigned int targetIndex;
4975 std::string targetStr, cmdUID;
4977 for(
auto& command : commands)
4979 __SUP_COUT__ <<
"command " << command.type_ << __E__;
4980 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
4984 row = planTable.tableView_->addRow(
4985 author,
true ,
"planCommand");
4986 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
4989 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
4992 planTable.tableView_->setValueAsString(
4993 "1", row, planTable.tableView_->getColStatus());
4996 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(command.type_);
4997 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4998 cmdTypeTableIt->second !=
5002 commandTableToEditMap.at(cmdTypeTableIt->second);
5003 __SUP_COUT__ <<
"table " << cmdTypeTableEdit.tableName_ << __E__;
5008 cmdRow = cmdTypeTableEdit.tableView_->addRow(
5009 author,
true , command.type_ +
"_COMMAND_");
5015 for(
auto& param : command.params_)
5017 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
5020 if(param.first == IterateTable::targetParams_.Tables_)
5022 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
5023 std::istringstream f(param.second);
5026 while(getline(f, targetStr,
'='))
5028 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
5029 if(!command.targets_.size() ||
5030 command.targets_.back().table_ !=
"")
5032 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
5035 command.addTarget();
5036 command.targets_.back().table_ = targetStr;
5039 command.targets_[targetIndex++].table_ = targetStr;
5045 if(param.first == IterateTable::targetParams_.UIDs_)
5047 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
5048 std::istringstream f(param.second);
5051 while(getline(f, targetStr,
'='))
5053 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
5054 if(!command.targets_.size() ||
5055 command.targets_.back().UID_ !=
"")
5057 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
5060 command.addTarget();
5061 command.targets_.back().UID_ = targetStr;
5064 command.targets_[targetIndex++].UID_ = targetStr;
5069 cmdCol = cmdTypeTableEdit.tableView_->findCol(param.first);
5071 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
5073 cmdTypeTableEdit.tableView_->setURIEncodedValue(
5074 param.second, cmdRow, cmdCol);
5078 cmdTypeTableEdit.tableView_
5079 ->getDataView()[cmdRow][cmdTypeTableEdit.tableView_->getColUID()];
5081 if(command.targets_.size())
5085 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
5088 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5089 IterateTable::commandTargetCols_.TargetsLink_);
5090 cmdTypeTableEdit.tableView_->setValueAsString(
5091 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
5093 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5094 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
5095 cmdTypeTableEdit.tableView_->setValueAsString(
5096 cmdUID +
"_Targets", cmdRow, cmdCol);
5100 for(
const auto& target : command.targets_)
5102 __SUP_COUT__ << target.
table_ <<
" " << target.UID_ << __E__;
5105 tgtRow = targetTable.tableView_->addRow(
5106 author,
true ,
"commandTarget");
5107 targetTable.tableView_->addRowToGroup(
5108 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
5111 targetTable.tableView_->setValueAsString(
5112 target.table_, tgtRow, targetTableCol);
5115 targetTable.tableView_->setValueAsString(
5116 target.UID_, tgtRow, targetUIDCol);
5121 planTable.tableView_->setValueAsString(
5122 cmdTypeTableEdit.tableName_, row, commandUidLink.first);
5123 planTable.tableView_->setValueAsString(
5124 cmdUID, row, commandUidLink.second);
5126 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
5136 planTable.tableView_->print();
5137 planTable.tableView_->init();
5139 __SUP_COUT__ <<
"requestType tables:" << __E__;
5141 for(
auto& modifiedConfig : commandTableToEditMap)
5143 __SUP_COUTV__(modifiedConfig.second.modified_);
5144 modifiedConfig.second.tableView_->print();
5145 modifiedConfig.second.tableView_->init();
5148 targetTable.tableView_->print();
5149 targetTable.tableView_->init();
5154 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
5160 if(planTable.createdTemporaryVersion_)
5162 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
5163 << planTable.temporaryVersion_ << __E__;
5166 planTable.temporaryVersion_);
5169 if(targetTable.createdTemporaryVersion_)
5171 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
5172 << targetTable.temporaryVersion_ << __E__;
5175 targetTable.temporaryVersion_);
5178 for(
auto& modifiedConfig : commandTableToEditMap)
5180 if(modifiedConfig.second
5181 .createdTemporaryVersion_)
5183 __SUP_COUT__ <<
"Erasing temporary version "
5184 << modifiedConfig.second.tableName_ <<
"-v"
5185 << modifiedConfig.second.temporaryVersion_ << __E__;
5188 modifiedConfig.second.temporaryVersion_);
5202 planTable.tableName_,
5203 planTable.originalVersion_,
5206 planTable.temporaryVersion_,
5209 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
5210 << finalVersion << __E__;
5215 targetTable.tableName_,
5216 targetTable.originalVersion_,
5219 targetTable.temporaryVersion_,
5222 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
5223 << finalVersion << __E__;
5225 for(
auto& modifiedConfig : commandTableToEditMap)
5227 if(!modifiedConfig.second.modified_)
5229 if(modifiedConfig.second
5230 .createdTemporaryVersion_)
5232 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5233 << modifiedConfig.second.tableName_ <<
"-v"
5234 << modifiedConfig.second.temporaryVersion_ << __E__;
5237 modifiedConfig.second.temporaryVersion_);
5245 modifiedConfig.second.tableName_,
5246 modifiedConfig.second.originalVersion_,
5248 modifiedConfig.second.table_,
5249 modifiedConfig.second.temporaryVersion_,
5252 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
5253 << finalVersion << __E__;
5256 handleFillModifiedTablesXML(xmlOut, cfgMgr);
5258 catch(std::runtime_error& e)
5260 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
5261 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5262 xmlOut.addTextElementToData(
"Error", ss.str());
5266 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
5271 catch(
const std::exception& e)
5273 ss <<
"Exception message: " << e.what();
5278 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5279 xmlOut.addTextElementToData(
"Error", ss.str());
5292 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(
HttpXmlDocument& xmlOut,
5294 const std::string& tableName,
5296 const std::string& type,
5297 const std::string& uid,
5298 const std::string& colName,
5299 const std::string& newValue,
5300 const std::string& author)
5303 __SUP_COUT__ <<
"Editing table " << tableName <<
"(" << version <<
") uid=" << uid
5304 <<
" type=" << type << __E__;
5314 table->setActiveView(version);
5318 if(version.isTemporaryVersion())
5321 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
5322 << version << __E__;
5326 __SUP_COUT__ <<
"Active version is " << table->getViewVersion() << __E__;
5327 __SUP_COUTTV__(table->getView().getComment());
5329 if(version != table->getViewVersion())
5331 __SUP_SS__ <<
"Target table version (" << version
5332 <<
") is not the currently active version (" << table->getViewVersion()
5333 <<
"). Try refreshing the tree." << __E__;
5337 unsigned int col = -1;
5338 if(type ==
"uid" || type ==
"delete-uid" || type ==
"tree-copy")
5339 col = table->getView().getColUID();
5340 else if(type ==
"node-comment")
5341 col = table->getView().findCol(TableViewColumnInfo::COL_NAME_COMMENT);
5342 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
5343 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
5344 col = table->getView().findCol(colName);
5345 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
5346 type ==
"table-newUIDRow" || type ==
"table-newRow")
5350 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
5355 if(type ==
"table" || type ==
"link-comment")
5358 if(table->getView().isURIEncodedCommentTheSame(newValue))
5361 <<
"' is the same as the current comment. No need to save change."
5377 TableVersion temporaryVersion = table->createTemporaryView(version);
5379 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5381 TableView* cfgView = table->getTemporaryView(temporaryVersion);
5384 __SUP_COUTTV__(table->getView().getComment());
5390 if(type ==
"table" || type ==
"link-comment")
5395 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
5398 unsigned int row = cfgView->
addRow(
5399 author,
true , newValue );
5414 else if(type ==
"table-newGroupRow")
5417 unsigned int csvIndex = newValue.find(
',');
5419 std::string linkIndex = newValue.substr(0, csvIndex);
5420 std::string groupId = newValue.substr(csvIndex + 1);
5423 csvIndex = groupId.find(
',');
5424 std::string newRowUID = groupId.substr(csvIndex + 1);
5425 groupId = groupId.substr(0, csvIndex);
5427 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
5431 unsigned int row = cfgView->
addRow(author,
5457 else if(type ==
"delete-uid")
5460 unsigned int row = cfgView->
findRow(col, uid);
5463 else if(type ==
"tree-copy")
5466 __COUTV__(newValue);
5467 std::vector<std::string> paramArray =
5471 if(paramArray.size() != 2)
5473 __SS__ <<
"Illegal parameters for tree copy request: must be number of "
5474 "copy instances & depth of copy."
5479 unsigned int row = cfgView->
findRow(col, uid);
5482 unsigned int numberOfInstances = atoi(paramArray[0].c_str());
5483 unsigned int depth = atoi(paramArray[1].c_str());
5485 __COUTV__(numberOfInstances);
5486 if(numberOfInstances > 1000)
5488 __SS__ <<
"Illegal parameters - the maximum number of copy instances is "
5489 "1000. Number of instances provided was "
5490 << numberOfInstances << __E__;
5497 ConfigurationSupervisorBase::recursiveCopyTreeUIDNode(xmlOut,
5506 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
5507 type ==
"value-bool" || type ==
"value-bitmap" || type ==
"node-comment")
5513 __SUP_SS__ <<
"Value '" << newValue
5514 <<
"' is the same as the current value. No need to save "
5515 "change to tree node."
5520 else if(type ==
"link-UID" || type ==
"link-GroupID")
5523 std::pair<
unsigned int ,
unsigned int > linkPair;
5527 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
5531 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
5534 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
5536 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
5539 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
5541 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
5542 csvIndexStart = csvIndex + 1;
5543 csvIndex = newValue.find(
',', csvIndexStart);
5544 std::string newLinkId = newValue.substr(
5549 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
5553 bool changed =
false;
5554 bool needSecondaryChange = (type ==
"link-GroupID");
5559 __SUP_COUT__ <<
"Value '" << newTable
5560 <<
"' is the same as the current value." << __E__;
5568 std::string originalValue = cfgView->
getValueAsString(row, linkPair.second);
5572 __SUP_COUT__ <<
"Value '" << newLinkId
5573 <<
"' is the same as the current value." << __E__;
5578 needSecondaryChange =
5584 if(needSecondaryChange)
5586 bool secondaryChanged =
false;
5587 bool defaultIsInGroup =
5593 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
5595 table->eraseView(temporaryVersion);
5616 catch(std::runtime_error&
5619 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
5620 "temporary version."
5622 table->eraseView(temporaryVersion);
5626 xmlOut.addTextElementToData(
5628 "Error saving primary tree node! " + std::string(e.what()));
5638 __SUP_COUTV__(newValue);
5639 csvIndexStart = csvIndex + 1;
5640 csvIndex = newValue.find(
',', csvIndexStart);
5642 csvIndexStart, csvIndex - csvIndexStart));
5645 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5656 table->setActiveView(version);
5660 if(version.isTemporaryVersion())
5663 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
5665 << newTable <<
" v" << version << __E__;
5669 __SUP_COUT__ << newTable <<
" active version is "
5670 << table->getViewVersion() << __E__;
5672 if(version != table->getViewVersion())
5675 if(version.isMockupVersion())
5676 ss <<
"Target table '" << newTable
5677 <<
"' is likely not a member of the current table group "
5678 <<
"since the mock-up version was not successfully loaded. "
5683 "To add a table to a group, click the group name to go to "
5685 "group view, then click 'Add/Remove/Modify Member Tables.' "
5687 "can then add or remove tables and save the new group." +
5689 "OR!!! Click the following button to add the table '" +
5691 "' to the currently active Configuration Group: " +
5692 "<input type='button' style='color:black !important;' " +
5693 "title='Click to add table to the active Configuration "
5695 "onclick='addTableToConfigurationGroup(\"" + newTable +
5696 "\"); Debug.closeErrorPop();event.stopPropagation();' "
5697 "value='Add Table'>" +
5701 ss <<
"Target table version (" << version
5702 <<
") is not the currently active version ("
5703 << table->getViewVersion() <<
"). Try refreshing the tree."
5709 temporaryVersion = table->createTemporaryView(version);
5711 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5713 cfgView = table->getTemporaryView(temporaryVersion);
5717 if(type ==
"link-UID")
5727 __SUP_COUT__ <<
"target col " << col << __E__;
5729 unsigned int row = -1;
5732 row = cfgView->
findRow(col, newLinkId);
5737 if(row == (
unsigned int)-1)
5739 __SUP_COUT__ <<
"New link UID '" << newLinkId
5740 <<
"' was not found, so attempting to change UID of "
5742 << originalValue <<
"'" << __E__;
5745 row = cfgView->
findRow(col, originalValue);
5748 secondaryChanged =
true;
5749 __SUP_COUT__ <<
"Original target record '"
5750 << originalValue <<
"' was changed to '"
5751 << newLinkId <<
"'" << __E__;
5756 __SUP_COUT__ <<
"Original target record '" << originalValue
5757 <<
"' not found." << __E__;
5761 else if(type ==
"link-GroupID")
5769 __SUP_COUT__ <<
"target col " << col << __E__;
5772 std::vector<std::string> memberUIDs;
5775 csvIndexStart = csvIndex + 1;
5776 csvIndex = newValue.find(
',', csvIndexStart);
5777 memberUIDs.push_back(
5778 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
5779 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
5781 (
unsigned int)std::string::npos);
5791 std::string targetUID;
5792 bool shouldBeInGroup;
5795 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
5797 targetUID = cfgView->getDataView()[row][cfgView->
getColUID()];
5798 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
5800 shouldBeInGroup =
false;
5801 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
5802 if(targetUID == memberUIDs[i])
5805 shouldBeInGroup =
true;
5812 if(shouldBeInGroup && !isInGroup)
5814 __SUP_COUT__ <<
"Changed to YES: " << row << __E__;
5815 secondaryChanged =
true;
5820 else if(!shouldBeInGroup && isInGroup)
5822 __SUP_COUT__ <<
"Changed to NO: " << row << __E__;
5823 secondaryChanged =
true;
5827 else if(targetUID ==
5829 ->getDefaultRowValues()[cfgView->
getColUID()] &&
5833 defaultIsInGroup =
true;
5839 if(!secondaryChanged)
5842 <<
"No changes to secondary view. Erasing temporary table."
5844 table->eraseView(temporaryVersion);
5865 catch(std::runtime_error&
5868 __SUP_COUT__ <<
"Caught error while editing secondary table. "
5869 "Erasing temporary version."
5871 table->eraseView(temporaryVersion);
5872 secondaryChanged =
false;
5875 xmlOut.addTextElementToData(
5877 "Error saving secondary tree node! " + std::string(e.what()));
5885 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
5887 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
5889 <<
"', and selected group members are the same as the "
5891 <<
"No need to save changes to tree." << __E__;
5897 else if(0 && !changed)
5902 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
5904 <<
"' are the same as the current values. No need to save "
5905 "change to tree node."
5915 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5916 table->eraseView(temporaryVersion);
5930 catch(std::runtime_error& e)
5932 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
5933 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5934 xmlOut.addTextElementToData(
"Error", ss.str());
5938 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
5943 catch(
const std::exception& e)
5945 ss <<
"Exception message: " << e.what();
5950 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5951 xmlOut.addTextElementToData(
"Error", ss.str());
5995 void ConfigurationGUISupervisor::handleGetTableXML(
HttpXmlDocument& xmlOut,
5997 const std::string& tableName,
5999 bool allowIllegalColumns ,
6001 bool descriptionOnly )
6004 char tmpIntStr[100];
6005 xercesc::DOMElement *parentEl, *subparentEl;
6007 std::string accumulatedErrors =
"";
6009 if(allowIllegalColumns)
6010 xmlOut.addTextElementToData(
"allowIllegalColumns",
"1");
6012 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo(
6013 allowIllegalColumns ,
6014 allowIllegalColumns ? &accumulatedErrors : 0,
6023 xmlOut.addTextElementToData(
"ExistingTableNames",
6024 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
6025 for(
auto& configPair : allTableInfo)
6027 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
6028 if(configPair.first == tableName &&
6029 configPair.second.versions_.find(version) ==
6030 configPair.second.versions_.end())
6032 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
6038 xmlOut.addTextElementToData(
"TableName", tableName);
6039 xmlOut.addTextElementToData(
"TableDescription",
6040 table->getTableDescription());
6057 for(
const auto& aliases : versionAliases)
6058 for(
const auto& alias : aliases.second)
6059 __SUP_COUTT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
6060 <<
" ==> " << alias.second << __E__;
6062 catch(
const std::runtime_error& e)
6064 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
6065 << e.what() << __E__;
6068 auto tableIterator = versionAliases.find(tableName);
6070 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
6073 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
6079 std::vector<std::string> aliases;
6080 if(tableIterator != versionAliases.end())
6083 for(
const auto& aliasPair : tableIterator->second)
6085 if(v == aliasPair.second)
6087 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
6088 << aliasPair.first << __E__;
6089 aliases.push_back(aliasPair.first);
6097 __SUP_COUT__ <<
"Handling version w/aliases" << __E__;
6100 TableVersion::INVALID)
6105 else if(hi.
version() + 1 == v.version())
6112 if(lo.
version() != TableVersion::INVALID)
6122 if(versionAliases.size())
6126 for(
const auto& alias : aliases)
6128 hi = lo = TableVersion::INVALID;
6133 if(lo.
version() != TableVersion::INVALID)
6147 if(version.isInvalid())
6149 tableViewPtr = table->getMockupViewP();
6157 std::string localAccumulatedErrors =
"";
6162 allowIllegalColumns ,
6163 &localAccumulatedErrors,
6169 xmlOut.addTextElementToData(
"TableRawData",
6170 tableViewPtr->getSourceRawData());
6172 const std::set<std::string>& srcColNames =
6173 tableViewPtr->getSourceColumnNames();
6174 for(
auto& srcColName : srcColNames)
6175 xmlOut.addTextElementToData(
"ColumnHeader", srcColName);
6177 if(!version.isTemporaryVersion())
6182 tableViewPtr = cfgMgr
6186 allowIllegalColumns ,
6187 &localAccumulatedErrors,
6193 if(localAccumulatedErrors !=
"")
6194 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
6196 catch(std::runtime_error& e)
6198 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
6199 <<
"... defaulting to mock-up! " << __E__;
6200 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
6202 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6204 tableViewPtr = table->getMockupViewP();
6206 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6210 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
6211 <<
"... defaulting to mock-up! "
6212 <<
"(You may want to try again to see what was partially loaded "
6213 "into cache before failure. "
6214 <<
"If you think, the failure is due to a column name change, "
6215 <<
"you can also try to Copy the failing view to the new column "
6217 <<
"'Copy and Move' functionality.)" << __E__;
6222 catch(
const std::exception& e)
6224 ss <<
"Exception message: " << e.what();
6230 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6232 tableViewPtr = table->getMockupViewP();
6234 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6237 xmlOut.addTextElementToData(
"TableVersion", version.toString());
6243 xercesc::DOMElement* choicesParentEl;
6244 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
6246 std::vector<TableViewColumnInfo> colInfo = tableViewPtr->getColumnsInfo();
6248 for(
int i = 0; i < (int)colInfo.size(); ++i)
6253 "ColumnDataType", colInfo[i].getDataType(), parentEl);
6258 "ColumnDefaultValue", colInfo[i].getDefaultValue(), parentEl);
6262 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
6263 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
6264 colInfo[i].isChildLink())
6266 for(
auto& choice : colInfo[i].getDataChoices())
6271 "ColumnMinValue", colInfo[i].getMinValue(), parentEl);
6273 "ColumnMaxValue", colInfo[i].getMaxValue(), parentEl);
6279 if(version.isInvalid())
6280 tableViewPtr->
init();
6282 catch(std::runtime_error& e)
6285 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
6292 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
6294 for(
int r = 0; r < (int)tableViewPtr->getNumberOfRows(); ++r)
6296 sprintf(tmpIntStr,
"%d", r);
6297 xercesc::DOMElement* tmpParentEl =
6300 for(
int c = 0; c < (int)tableViewPtr->getNumberOfColumns(); ++c)
6302 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
6304 std::string timeAsString;
6305 tableViewPtr->
getValue(timeAsString, r, c);
6310 "Entry", tableViewPtr->getDataView()[r][c], tmpParentEl);
6315 xmlOut.addTextElementToData(
"TableComment", tableViewPtr->getComment());
6316 xmlOut.addTextElementToData(
"TableAuthor", tableViewPtr->getAuthor());
6317 xmlOut.addTextElementToData(
"TableCreationTime",
6318 std::to_string(tableViewPtr->getCreationTime()));
6319 xmlOut.addTextElementToData(
"TableLastAccessTime",
6320 std::to_string(tableViewPtr->getLastAccessTime()));
6325 std::vector<std::string> defaultRowValues =
6326 table->getMockupViewP()->getDefaultRowValues();
6328 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
6330 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
6333 const std::set<std::string> srcColNames = tableViewPtr->getSourceColumnNames();
6335 if(accumulatedErrors !=
"")
6337 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
6338 "perhaps you can ignore this, ") +
6339 "but please note the following warnings:\n" + accumulatedErrors)
6341 __SUP_COUT_ERR__ << ss.str();
6342 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6344 else if(!version.isTemporaryVersion() &&
6346 (srcColNames.size() != tableViewPtr->getNumberOfColumns() ||
6347 tableViewPtr->getSourceColumnMismatch() !=
6350 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
6351 <<
":v" << version <<
". Please see the details below:\n\n"
6352 << tableViewPtr->getMismatchColumnInfo();
6354 __SUP_COUT__ <<
"\n" << ss.str();
6355 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6359 catch(std::runtime_error& e)
6361 __SUP_SS__ <<
"Error getting table view!\n\n " << e.what() << __E__;
6362 __SUP_COUT_ERR__ << ss.str();
6363 xmlOut.addTextElementToData(
"Error", ss.str());
6367 __SUP_SS__ <<
"Error getting table view!\n\n " << __E__;
6372 catch(
const std::exception& e)
6374 ss <<
"Exception message: " << e.what();
6379 __SUP_COUT_ERR__ << ss.str();
6380 xmlOut.addTextElementToData(
"Error", ss.str());
6391 std::string username,
bool refresh)
6393 uint64_t sessionIndex =
6396 std::stringstream ssMapKey;
6397 ssMapKey << username <<
":" << sessionIndex;
6398 std::string mapKey = ssMapKey.str();
6399 __SUP_COUTT__ <<
"Using Config Session " << mapKey
6400 <<
" ... Total Session Count: " << userConfigurationManagers_.size()
6401 <<
" refresh=" << refresh << __E__;
6403 time_t now = time(0);
6409 for(
auto& pair : userConfigurationManagers_)
6410 __SUP_COUTTV__(pair.first);
6413 const std::string preLoadCfgMgrName =
":0";
6414 if(userConfigurationManagers_.size() == 1 &&
6415 userConfigurationManagers_.find(preLoadCfgMgrName) !=
6416 userConfigurationManagers_.end())
6418 __SUP_COUT__ <<
"Using pre-loaded Configuration Manager. time=" << time(0) <<
" "
6419 << clock() <<
" Setting author from "
6420 << userConfigurationManagers_.at(preLoadCfgMgrName)->getUsername()
6421 <<
" to " << username << __E__;
6422 userConfigurationManagers_[mapKey] =
6423 userConfigurationManagers_.at(preLoadCfgMgrName);
6424 userLastUseTime_[mapKey] = userLastUseTime_.at(preLoadCfgMgrName);
6426 userConfigurationManagers_.at(mapKey)->setUsername(username);
6429 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
6431 __SUP_COUT__ <<
"Creating new Configuration Manager. time=" << time(0) <<
" "
6432 << clock() << __E__;
6438 userConfigurationManagers_[mapKey]->getAllTableInfo(
6446 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
6448 __SUP_SS__ <<
"Fatal error managing user sessions! Check the logs for "
6449 "Configuration Interface failure."
6451 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6456 (now - userLastUseTime_[mapKey]) >
6457 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
6459 __SUP_COUT__ <<
"Refreshing all table info." << __E__;
6460 userConfigurationManagers_[mapKey]->getAllTableInfo(
6468 __SUP_COUTT__ <<
"Configuration Manager for author="
6469 << userConfigurationManagers_[mapKey]->getUsername()
6470 <<
" ready. time=" << time(0) <<
" " << clock() <<
" runTimeSeconds()="
6471 << userConfigurationManagers_[mapKey]->runTimeSeconds() << __E__;
6474 userLastUseTime_[mapKey] = now;
6477 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
6478 it != userLastUseTime_.end();
6480 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
6482 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
6484 delete userConfigurationManagers_[it->first];
6485 if(!(userConfigurationManagers_.erase(it->first)))
6487 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
6489 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6492 userLastUseTime_.erase(it);
6499 return userConfigurationManagers_[mapKey];
6507 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(
HttpXmlDocument& xmlOut,
6509 std::string& tableName)
6511 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
6512 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
6513 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
6514 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6518 __SUP_COUT_ERR__ << (
"Error renaming file to " +
6519 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6522 xmlOut.addTextElementToData(
6524 (
"Error renaming Table Info File to " +
6525 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
6540 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
6543 std::string& tableName,
6544 const std::string& data,
6545 const std::string& tableDescription,
6546 const std::string& columnChoicesCSV,
6547 bool allowOverwrite)
6551 std::string capsName;
6556 catch(std::runtime_error& e)
6558 xmlOut.addTextElementToData(
"Error", e.what());
6564 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
6568 xmlOut.addTextElementToData(
"TableName", tableName);
6569 xmlOut.addTextElementToData(
"OverwriteError",
"1");
6570 xmlOut.addTextElementToData(
6572 "File already exists! ('" +
6573 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
6578 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
6579 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
6580 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
6581 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
6584 std::stringstream outss;
6586 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
6587 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
6588 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
6589 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
6590 outss <<
"\t\t\t<VIEW Name=\"" << capsName
6591 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
6597 std::istringstream columnChoicesISS(columnChoicesCSV);
6598 std::string columnChoicesString;
6599 std::string columnDefaultValue, columnMinValue, columnMaxValue;
6600 std::vector<std::string> columnParameters;
6601 std::vector<std::string> columnData =
6604 for(
unsigned int c = 0; c < columnData.size() - 1; ++c)
6608 __COUT__ <<
"Column #" << c <<
": "
6610 for(
unsigned int p = 0; p < columnParameters.size(); ++p)
6612 __COUT__ <<
"\t Parameter #" << p <<
": " << columnParameters[p] << __E__;
6614 __COUT__ <<
"\t creating the new xml" << __E__;
6616 std::string& columnType = columnParameters[0];
6617 std::string& columnName = columnParameters[1];
6618 std::string& columnDataType = columnParameters[2];
6619 const std::string columnStorageName =
6622 outss <<
"\t\t\t\t<COLUMN Type=\"";
6623 outss << columnType;
6624 outss <<
"\" \t Name=\"";
6625 outss << columnName;
6626 outss <<
"\" \t StorageName=\"";
6629 outss << columnStorageName;
6631 catch(std::runtime_error& e)
6633 xmlOut.addTextElementToData(
6635 std::string(
"For column name '") + columnName +
"' - " + e.what());
6638 outss <<
"\" \t DataType=\"";
6639 outss << columnDataType;
6643 std::string* columnDefaultValuePtr =
nullptr;
6644 if(columnDefaultValue !=
6647 __SUP_COUT__ <<
"FOUND user spec'd default value '" << columnDefaultValue
6649 outss <<
"\" \t DefaultValue=\"";
6650 outss << columnParameters[3];
6651 columnDefaultValuePtr = &columnParameters[3];
6653 getline(columnChoicesISS, columnChoicesString,
';');
6654 outss <<
"\" \t DataChoices=\"";
6655 outss << columnChoicesString;
6657 std::string* columnMinValuePtr =
nullptr;
6658 std::string* columnMaxValuePtr =
nullptr;
6660 if(columnParameters.size() > 4 &&
6664 if(columnMinValue !=
"")
6666 if(columnMinValue !=
6669 __SUP_COUT__ <<
"FOUND user spec'd min value '" << columnParameters[4]
6674 __SS__ <<
"Inavlid user spec'd min value '" << columnParameters[4]
6675 <<
"' which evaluates to '" << columnMinValue
6676 <<
"' and is not a valid number. The minimum value must "
6677 "be a number (environment variables and math "
6678 "operations are allowed)."
6682 outss <<
"\" \t MinValue=\"" << columnParameters[4];
6683 columnMinValuePtr = &columnParameters[4];
6688 if(columnMaxValue !=
"")
6690 if(columnMaxValue !=
6693 __SUP_COUT__ <<
"FOUND user spec'd max value = " << columnMaxValue
6698 __SS__ <<
"Inavlid user spec'd max value '" << columnParameters[5]
6699 <<
"' which evaluates to '" << columnMaxValue
6700 <<
"' and is not a valid number. The maximum value must "
6701 "be a number (environment variables and math "
6702 "operations are allowed)."
6706 outss <<
"\" \t MaxValue=\"" << columnParameters[5];
6707 columnMaxValuePtr = &columnParameters[5];
6719 columnDefaultValuePtr,
6720 columnChoicesString,
6726 catch(
const std::runtime_error& e)
6728 __SS__ <<
"Error identified with Column #" << c <<
": \n" << e.what();
6735 outss <<
"\t\t\t</VIEW>\n";
6736 outss <<
"\t\t</TABLE>\n";
6737 outss <<
"\t</ROOT>\n";
6739 __SUP_COUT__ << outss.str() << __E__;
6741 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
6744 xmlOut.addTextElementToData(
"Error",
6745 "Failed to open destination Table Info file:" +
6746 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
6750 fprintf(fp,
"%s", outss.str().c_str());
6753 __SUP_COUT_INFO__ <<
"Finished saving Table Info for '" << tableName
6754 <<
".' Looking for errors in all table column info..." << __E__;
6758 std::string accumulatedErrors =
"";
6762 if(accumulatedErrors !=
"")
6764 __SUP_SS__ << (
"The new version of the '" + tableName +
6765 "' table column info was saved, however errors were detected "
6766 "reading back the table '" +
6767 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
6770 __SUP_COUT_ERR__ << ss.str() << __E__;
6771 xmlOut.addTextElementToData(
"Error", ss.str());
6777 handleGetTableXML(xmlOut, cfgMgr, tableName,
TableVersion());
6780 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
6783 for(
const auto& cfgInfo : allTableInfo)
6789 catch(std::runtime_error& e)
6791 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
6792 <<
"Error identified in column info of table '"
6793 << cfgInfo.first <<
"':\n\n"
6794 << e.what() <<
"\n\n"
6808 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
6811 const std::string& groupAliasCSV,
6812 const std::string& groupNameCSV,
6813 const std::string& groupKeyCSV,
6814 const std::string& author)
6818 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6820 const std::string groupAliasesTableName =
6821 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6822 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6824 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
6826 xmlOut.addTextElementToData(
"Error", ss.str());
6831 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6832 for(
auto& memberName : backboneMembers)
6834 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6835 <<
"\"]=" << activeVersions[memberName] << __E__;
6837 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6838 xmlOut.addTextElementToData(
"oldBackboneVersion",
6839 activeVersions[memberName].toString());
6847 TableVersion originalVersion = activeVersions[groupAliasesTableName];
6848 TableVersion temporaryVersion = table->createTemporaryView(originalVersion);
6850 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6851 bool isDifferent =
false;
6855 TableView* configView = table->getTemporaryView(temporaryVersion);
6857 unsigned int col = configView->
findCol(
"GroupKeyAlias");
6858 unsigned int ccol = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6859 unsigned int ncol = configView->
findCol(
"GroupName");
6860 unsigned int kcol = configView->
findCol(
"GroupKey");
6863 std::vector<std::string> groupAliases =
6865 std::vector<std::string> groupNames =
6867 std::vector<std::string> groupKeys =
6874 for(
const auto& groupAlias : groupAliases)
6876 if(groupAlias ==
"" || groupNames[i] ==
"" || groupKeys[i] ==
"")
6879 __SUP_COUT_WARN__ <<
"Empty alias parameter found [" << i <<
"] = {"
6880 << groupAlias <<
", " << groupNames[i] <<
"("
6881 << groupKeys[i] <<
")}" << __E__;
6886 bool localIsDifferent =
false;
6887 const std::string& groupName = groupNames[i];
6891 unsigned int row = -1;
6895 row = configView->
findRow(col, groupAlias);
6901 if(row == (
unsigned int)-1)
6903 localIsDifferent =
true;
6904 row = configView->
addRow();
6908 "This Group Alias was automatically setup by the server.", row, ccol);
6909 configView->
setValue(groupAlias, row, col);
6912 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6914 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6915 << configView->getDataView()[row][ncol] << __E__;
6916 if(groupName != configView->getDataView()[row][ncol])
6918 configView->
setValue(groupName, row, ncol);
6919 localIsDifferent =
true;
6922 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6923 << configView->getDataView()[row][kcol] << __E__;
6924 if(groupKey.
toString() != configView->getDataView()[row][kcol])
6927 localIsDifferent =
true;
6930 if(localIsDifferent)
6935 configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
6939 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
6946 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6949 table->eraseView(temporaryVersion);
6956 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6963 table->getTableName(),
6974 <<
"\t\t**************************** Using the existing table version"
6978 table->eraseView(temporaryVersion);
6979 newAssignedVersion = activeVersions[groupAliasesTableName];
6981 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6982 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
6985 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6987 catch(std::runtime_error& e)
6989 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << e.what() << __E__;
6990 __SUP_COUT_ERR__ << ss.str();
6991 xmlOut.addTextElementToData(
"Error", ss.str());
6995 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << __E__;
7000 catch(
const std::exception& e)
7002 ss <<
"Exception message: " << e.what();
7007 __SUP_COUT_ERR__ << ss.str();
7008 xmlOut.addTextElementToData(
"Error", ss.str());
7019 void ConfigurationGUISupervisor::handleSetTableAliasInBackboneXML(
7022 const std::string& tableAlias,
7023 const std::string& tableName,
7025 const std::string& author)
7029 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7031 const std::string versionAliasesTableName =
7032 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7033 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7035 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7037 xmlOut.addTextElementToData(
"Error", ss.str());
7042 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7043 for(
auto& memberName : backboneMembers)
7045 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7046 <<
"\"]=" << activeVersions[memberName] << __E__;
7048 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7049 xmlOut.addTextElementToData(
"oldBackboneVersion",
7050 activeVersions[memberName].toString());
7058 TableVersion originalVersion = activeVersions[versionAliasesTableName];
7059 TableVersion temporaryVersion = table->createTemporaryView(originalVersion);
7061 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7063 bool isDifferent =
false;
7067 TableView* configView = table->getTemporaryView(temporaryVersion);
7070 unsigned int col2 = configView->
findCol(
"VersionAlias");
7071 unsigned int col3 = configView->
findCol(
"TableName");
7075 unsigned int row = -1;
7080 unsigned int tmpRow = -1;
7083 tmpRow = configView->
findRow(col3, tableName, tmpRow + 1);
7084 }
while(configView->getDataView()[tmpRow][col2] != tableAlias);
7091 if(row == (
unsigned int)-1)
7094 row = configView->
addRow();
7097 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7099 std::string(
"Entry was added by server in ") +
7100 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7104 col = configView->
findCol(
"VersionAliasUID");
7106 tableName.substr(0, tableName.rfind(
"Table")) + tableAlias, row, col);
7108 configView->
setValue(tableAlias, row, col2);
7109 configView->
setValue(tableName, row, col3);
7112 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
7114 col = configView->
findCol(
"Version");
7115 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
7116 << configView->getDataView()[row][col] << __E__;
7117 if(version.toString() != configView->getDataView()[row][col])
7119 configView->
setValue(version.toString(), row, col);
7126 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7130 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7135 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
7138 table->eraseView(temporaryVersion);
7145 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
7151 table->getTableName(),
7161 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7165 table->eraseView(temporaryVersion);
7166 newAssignedVersion = activeVersions[versionAliasesTableName];
7168 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7169 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7172 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
7174 catch(std::runtime_error& e)
7176 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7177 __SUP_COUT_ERR__ << ss.str();
7178 xmlOut.addTextElementToData(
"Error", ss.str());
7182 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7187 catch(
const std::exception& e)
7189 ss <<
"Exception message: " << e.what();
7194 __SUP_COUT_ERR__ << ss.str();
7195 xmlOut.addTextElementToData(
"Error", ss.str());
7204 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
7207 const std::string& versionAlias,
7208 const std::string& groupName,
7210 const std::string& author)
7214 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7216 const std::string versionAliasesTableName =
7217 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7218 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7220 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7222 xmlOut.addTextElementToData(
"Error", ss.str());
7227 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7228 for(
auto& memberName : backboneMembers)
7230 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7231 <<
"\"]=" << activeVersions[memberName] << __E__;
7233 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7234 xmlOut.addTextElementToData(
"oldBackboneVersion",
7235 activeVersions[memberName].toString());
7244 table->createTemporaryView(activeVersions[versionAliasesTableName]);
7246 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7248 TableView* configView = table->getTemporaryView(temporaryVersion);
7251 bool isDifferent =
false;
7270 xmlOut.addTextElementToData(
7273 "\" can not be retrieved!");
7278 unsigned int col2 = configView->
findCol(
"VersionAlias");
7279 unsigned int col3 = configView->
findCol(
"TableName");
7281 for(
auto& memberPair : memberMap)
7283 bool thisMemberIsDifferent =
false;
7284 unsigned int row = -1;
7286 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
7287 << memberPair.second <<
" to " << versionAlias << __E__;
7293 unsigned int tmpRow = -1;
7296 tmpRow = configView->
findRow(col3, memberPair.first, tmpRow + 1);
7297 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
7304 if(row == (
unsigned int)-1)
7306 thisMemberIsDifferent =
true;
7307 row = configView->
addRow();
7310 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7312 std::string(
"Entry was added by server in ") +
7313 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7319 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
7324 configView->
setValue(versionAlias, row, col2);
7325 configView->
setValue(memberPair.first, row, col3);
7328 col = configView->
findCol(
"Version");
7330 if(memberPair.second.toString() != configView->getDataView()[row][col])
7332 configView->
setValue(memberPair.second.toString(), row, col);
7333 thisMemberIsDifferent =
true;
7336 if(thisMemberIsDifferent)
7339 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7343 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7346 if(thisMemberIsDifferent)
7355 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
7356 <<
" as new table version" << __E__;
7358 newAssignedVersion =
7359 cfgMgr->
saveNewTable(versionAliasesTableName, temporaryVersion);
7363 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7367 table->eraseView(temporaryVersion);
7368 newAssignedVersion = activeVersions[versionAliasesTableName];
7371 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7372 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7373 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
7375 catch(std::runtime_error& e)
7377 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7378 __SUP_COUT_ERR__ << ss.str();
7379 xmlOut.addTextElementToData(
"Error", ss.str());
7383 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7388 catch(
const std::exception& e)
7390 ss <<
"Exception message: " << e.what();
7395 __SUP_COUT_ERR__ << ss.str();
7396 xmlOut.addTextElementToData(
"Error", ss.str());
7410 void ConfigurationGUISupervisor::handleGroupAliasesXML(
HttpXmlDocument& xmlOut,
7414 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7416 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
7417 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
7419 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
7420 << groupAliasesTableName
7421 <<
" is a required member of the Backbone table group."
7422 <<
"\n\nLikely you need to activate a valid Backbone table group."
7424 __SUP_COUT__ << ss.str();
7429 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
7430 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
7431 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
7432 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
7433 activeVersions[groupAliasesTableName].toString());
7435 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7440 <<
" ==> " << numOfThreads <<
" threads for alias group loads." << __E__;
7442 if(numOfThreads < 2)
7444 std::string groupName, groupKey, groupComment, groupAuthor, groupCreateTime,
7446 for(
auto& aliasNodePair : aliasNodePairs)
7448 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7449 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7451 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7452 xmlOut.addTextElementToData(
"GroupName", groupName);
7453 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7454 xmlOut.addTextElementToData(
7456 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7457 .getValueAsString());
7461 ConfigurationManager::UNKNOWN_INFO;
7462 groupType = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7479 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7480 << groupKey <<
")' to extract group comment and type."
7483 xmlOut.addTextElementToData(
"GroupComment", groupComment);
7484 xmlOut.addTextElementToData(
"GroupType", groupType);
7489 int threadsLaunched = 0;
7490 int foundThreadIndex = 0;
7491 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
7492 for(
int i = 0; i < numOfThreads; ++i)
7493 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
7495 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
7496 std::string groupName, groupKey;
7498 for(
auto& aliasNodePair : aliasNodePairs)
7501 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
7503 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7504 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7506 if(threadsLaunched >= numOfThreads)
7509 foundThreadIndex = -1;
7510 while(foundThreadIndex == -1)
7512 for(
int i = 0; i < numOfThreads; ++i)
7513 if(*(threadDone[i]))
7515 foundThreadIndex = i;
7518 if(foundThreadIndex == -1)
7520 __SUP_COUTT__ <<
"Waiting for available thread..." << __E__;
7524 threadsLaunched = numOfThreads - 1;
7526 __SUP_COUTT__ <<
"Starting load group thread... " << groupName <<
"("
7527 << groupKey <<
")" << __E__;
7528 *(threadDone[foundThreadIndex]) =
false;
7532 std::string theGroupName,
7534 std::shared_ptr<ots::GroupInfo> theGroupInfo,
7535 std::shared_ptr<std::atomic<bool>> theThreadDone) {
7545 sharedGroupInfoPtrs.back(),
7546 threadDone[foundThreadIndex])
7557 foundThreadIndex = -1;
7558 for(
int i = 0; i < numOfThreads; ++i)
7559 if(!*(threadDone[i]))
7561 foundThreadIndex = i;
7564 if(foundThreadIndex != -1)
7566 __SUP_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
7570 }
while(foundThreadIndex != -1);
7574 for(
auto& aliasNodePair : aliasNodePairs)
7576 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7577 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7579 if(groupKey != sharedGroupInfoPtrs[i]->getLatestKey().toString())
7581 __SUP_SS__ <<
"Error loading group information for the group alias '"
7582 << aliasNodePair.first <<
"' mapping to group '" << groupName
7583 <<
"(" << groupKey <<
")" << __E__;
7587 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7588 xmlOut.addTextElementToData(
"GroupName", groupName);
7589 xmlOut.addTextElementToData(
7590 "GroupKey", sharedGroupInfoPtrs[i]->getLatestKey().toString());
7591 xmlOut.addTextElementToData(
7593 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7594 .getValueAsString());
7596 xmlOut.addTextElementToData(
7597 "GroupComment", sharedGroupInfoPtrs[i]->getLatestKeyGroupComment());
7598 xmlOut.addTextElementToData(
7599 "GroupAuthor", sharedGroupInfoPtrs[i]->getLatestKeyGroupAuthor());
7600 xmlOut.addTextElementToData(
7601 "GroupCreationTime",
7602 sharedGroupInfoPtrs[i]->getLatestKeyGroupCreationTime());
7603 xmlOut.addTextElementToData(
7604 "GroupType", sharedGroupInfoPtrs[i]->getLatestKeyGroupTypeString());
7623 void ConfigurationGUISupervisor::handleVersionAliasesXML(
HttpXmlDocument& xmlOut,
7627 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7629 std::string versionAliasesTableName =
7630 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7631 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7633 __SUP_SS__ <<
"Active version of VersionAliases missing!"
7634 <<
"Make sure you have a valid active Backbone Group." << __E__;
7635 xmlOut.addTextElementToData(
"Error", ss.str());
7638 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
7639 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
7640 xmlOut.addTextElementToData(
"VersionAliasesVersion",
7641 activeVersions[versionAliasesTableName].toString());
7643 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7646 for(
auto& aliasNodePair : aliasNodePairs)
7650 xmlOut.addTextElementToData(
7652 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
7653 xmlOut.addTextElementToData(
7654 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
7655 xmlOut.addTextElementToData(
7656 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
7657 xmlOut.addTextElementToData(
7659 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7660 .getValueAsString());
7670 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
7674 std::string name, versionStr;
7675 auto c = tableList.find(
',', 0);
7678 while(c < tableList.length())
7681 name = tableList.substr(i, c - i);
7683 c = tableList.find(
',', i);
7684 if(c == std::string::npos)
7686 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
7687 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7688 xmlOut.addTextElementToData(
"Error", ss.str());
7692 versionStr = tableList.substr(i, c - i);
7694 c = tableList.find(
',', i);
7699 std::string groupTypeString =
"";
7705 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7707 catch(std::runtime_error& e)
7709 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
7710 __SUP_COUT__ <<
"\n" << ss.str();
7711 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7712 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7716 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
7721 catch(
const std::exception& e)
7723 ss <<
"Exception message: " << e.what();
7728 __SUP_COUT__ <<
"\n" << ss.str();
7729 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7730 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7750 void ConfigurationGUISupervisor::handleTableGroupsXML(
HttpXmlDocument& xmlOut,
7754 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7760 if(!cfgMgr->getAllGroupInfo().size() ||
7761 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
"" ||
7762 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
7763 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN ||
7765 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE) !=
7766 TableGroupKey::INVALID &&
7767 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
7768 ConfigurationManager::GroupType::CONTEXT_TYPE)) !=
7769 cfgMgr->getAllGroupInfo().end() &&
7770 (cfgMgr->getAllGroupInfo()
7771 .at(cfgMgr->getActiveGroupName(
7772 ConfigurationManager::GroupType::CONTEXT_TYPE))
7773 .getLatestKeyGroupTypeString() ==
"" ||
7774 cfgMgr->getAllGroupInfo()
7775 .at(cfgMgr->getActiveGroupName(
7776 ConfigurationManager::GroupType::CONTEXT_TYPE))
7777 .getLatestKeyGroupTypeString() ==
7778 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)) ||
7780 cfgMgr->getActiveGroupKey(
7781 ConfigurationManager::GroupType::CONFIGURATION_TYPE) !=
7782 TableGroupKey::INVALID &&
7783 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
7784 ConfigurationManager::GroupType::CONFIGURATION_TYPE)) !=
7785 cfgMgr->getAllGroupInfo().end() &&
7786 (cfgMgr->getAllGroupInfo()
7787 .at(cfgMgr->getActiveGroupName(
7788 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
7789 .getLatestKeyGroupTypeString() ==
"" ||
7790 cfgMgr->getAllGroupInfo()
7791 .at(cfgMgr->getActiveGroupName(
7792 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
7793 .getLatestKeyGroupTypeString() ==
7794 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)))
7797 <<
"Group Info cache appears empty or stale. Attempting to regenerate..."
7807 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
7809 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7811 std::string groupName;
7812 std::string groupString, groupTypeString, groupComment, groupCreationTime,
7814 for(
auto& groupInfo : allGroupInfo)
7816 groupName = groupInfo.first;
7821 if(groupInfo.second.getKeys().size() == 0)
7823 __SUP_COUT__ <<
"Group name '" << groupName
7824 <<
"' found, but no keys so ignoring." << __E__;
7828 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7829 xmlOut.dataSs_ <<
"<TableGroupKey value='" << groupInfo.second.getLatestKey()
7833 xmlOut.dataSs_ <<
"<TableGroupType value='"
7834 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
7836 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7838 groupInfo.second.getLatestKeyGroupComment(),
7841 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7842 << groupInfo.second.getLatestKeyGroupAuthor() <<
"'/>" << __E__;
7843 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7844 << groupInfo.second.getLatestKeyGroupCreationTime() <<
"'/>"
7850 xmlOut.dataSs_ <<
"<TableGroupMembers value=''>" << __E__;
7852 for(
auto& memberPair : groupInfo.second.getLatestKeyMemberMap())
7854 xmlOut.dataSs_ <<
"\t<MemberName value='" << memberPair.first <<
"'/>"
7856 xmlOut.dataSs_ <<
"\t<MemberVersion value='" << memberPair.second <<
"'/>"
7863 xmlOut.dataSs_ <<
"</TableGroupMembers>" << __E__;
7868 for(
auto& keyInSet : groupInfo.second.getKeys())
7870 if(keyInSet == groupInfo.second.getLatestKey())
7873 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7874 xmlOut.dataSs_ <<
"<TableGroupKey value='" << keyInSet <<
"'/>" << __E__;
7879 bool loadingHistoricalInfo =
false;
7880 if(loadingHistoricalInfo)
7899 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7900 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7902 <<
")' to extract group comment and type." << __E__;
7905 xmlOut.dataSs_ <<
"<TableGroupType value='" << groupTypeString <<
"'/>"
7907 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7911 xmlOut.dataSs_ <<
"<TableGroupAuthor value='" << groupAuthor <<
"'/>"
7913 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='" << groupCreationTime
7923 xmlOut.dataSs_ <<
"<TableGroupType value='"
7924 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
7927 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7930 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7933 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7941 xmlOut.dataSs_ <<
"<TableGroupMembers/>" << __E__;
7946 __SUP_COUTT__ << groupName <<
" runtime=" << cfgMgr->runTimeSeconds() << __E__;
7948 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7963 void ConfigurationGUISupervisor::handleTablesXML(
HttpXmlDocument& xmlOut,
7966 if(cfgMgr->getAllGroupInfo().size() == 0 || cfgMgr->
getActiveVersions().size() == 0)
7968 __SUP_COUT__ <<
"Table Info cache appears empty. Attempting to regenerate."
7978 xercesc::DOMElement* parentEl;
7979 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
7982 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
7983 for(
const auto& tablePair : allTableInfo)
7984 orderedTableSet.emplace(tablePair.first);
7988 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
7990 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
7993 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
7995 for(
const auto& orderedTableName : orderedTableSet)
7998 std::map<std::string, TableInfo>::const_iterator it =
7999 allTableInfo.find(orderedTableName);
8000 if(it == allTableInfo.end())
8002 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
8011 xmlOut.addTextElementToData(
"TableName", it->first);
8012 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
8015 if(versionAliases.find(it->first) != versionAliases.end())
8016 for(
auto& aliasVersion : versionAliases[it->first])
8017 if(it->second.versions_.find(aliasVersion.second) !=
8018 it->second.versions_
8022 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
8030 auto vSpanToXML = [](
auto const& sortedKeys,
auto& xmlOut,
auto& configEl) {
8032 size_t lo = -1, hi = -1;
8033 for(
auto& keyInOrder : sortedKeys)
8036 if(keyInOrder.isScratchVersion())
8039 if(lo ==
size_t(-1))
8041 hi = lo = keyInOrder.
version();
8044 else if(hi + 1 == keyInOrder.version())
8052 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
8054 xmlOut.addTextElementToParent(
8056 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8058 hi = lo = keyInOrder.
version();
8061 if(lo !=
size_t(-1))
8064 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
8066 xmlOut.addTextElementToParent(
8068 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8073 vSpanToXML(it->second.versions_, xmlOut, parentEl);
8086 void ConfigurationGUISupervisor::handleGetArtdaqNodeRecordsXML(
8089 const std::string& modifiedTables)
8091 __COUT__ <<
"Retrieving artdaq nodes..." << __E__;
8094 setupActiveTablesXML(
8095 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8097 std::map<std::string ,
8098 std::map<std::string , std::vector<std::string >>>
8099 nodeTypeToObjectMap;
8100 std::map<std::string , std::string >
8103 std::vector<std::string > artdaqSupervisorInfo;
8105 std::string artdaqSupervisorName;
8107 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap, artdaqSupervisorInfo);
8109 if(artdaqSupervisorInfo.size() != 4 )
8111 __SUP_COUT__ <<
"No artdaq supervisor found." << __E__;
8115 __SUP_COUT__ <<
"========== "
8116 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
8118 unsigned int paramIndex = 0;
8120 auto parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
8121 artdaqSupervisorInfo[paramIndex++]);
8123 std::string typeString =
"artdaqSupervisor";
8126 typeString +
"-status", artdaqSupervisorInfo[paramIndex++], parentEl);
8128 typeString +
"-contextAddress", artdaqSupervisorInfo[paramIndex++], parentEl);
8130 typeString +
"-contextPort", artdaqSupervisorInfo[paramIndex++], parentEl);
8132 for(
auto& subsystem : info.subsystems)
8134 typeString =
"subsystem";
8136 __SUP_COUT__ <<
"\t\t"
8137 <<
"Found " << typeString <<
" " << subsystem.first <<
" \t := '"
8138 << subsystem.second.label <<
"'" << __E__;
8142 typeString +
"-id", std::to_string(subsystem.first), parentEl);
8145 std::to_string(subsystem.second.sources.size()),
8150 std::to_string(subsystem.second.destination),
8155 __SUP_COUT__ <<
"========== "
8156 <<
"Found " << nodeTypeToObjectMap.size() <<
" process types." << __E__;
8158 for(
auto& nameTypePair : nodeTypeToObjectMap)
8160 typeString = nameTypePair.first;
8162 __SUP_COUT__ <<
"\t"
8163 <<
"Found " << nameTypePair.second.size() <<
" " << typeString
8166 for(
auto& artdaqNode : nameTypePair.second)
8168 __SUP_COUT__ <<
"\t\t"
8169 <<
"Found '" << artdaqNode.first <<
"' " << typeString << __E__;
8172 if(artdaqNode.second.size() < 2)
8174 __SUP_SS__ <<
"Impossible parameter size for node '" << artdaqNode.first
8175 <<
"' " << typeString <<
" - please notify admins!" << __E__;
8183 if(artdaqNode.second.size() > paramIndex)
8185 __SUP_COUTT__ <<
"\t\t\t"
8186 <<
"-multinode: " << artdaqNode.second[paramIndex] << __E__;
8188 typeString +
"-multinode", artdaqNode.second[paramIndex++], nodeEl);
8190 if(artdaqNode.second.size() > paramIndex)
8192 __SUP_COUTT__ <<
"\t\t\t"
8193 <<
"-nodefixedwidth: " << artdaqNode.second[paramIndex]
8196 artdaqNode.second[paramIndex++],
8199 if(artdaqNode.second.size() > paramIndex)
8201 __SUP_COUTT__ <<
"\t\t\t"
8202 <<
"-hostarray: " << artdaqNode.second[paramIndex] << __E__;
8204 typeString +
"-hostarray", artdaqNode.second[paramIndex++], nodeEl);
8206 if(artdaqNode.second.size() > paramIndex)
8208 __SUP_COUTT__ <<
"\t\t\t"
8209 <<
"-hostfixedwidth: " << artdaqNode.second[paramIndex]
8212 artdaqNode.second[paramIndex++],
8217 __SUP_COUTT__ <<
"\t\t\t"
8218 <<
"-status: " << artdaqNode.second[paramIndex] << __E__;
8220 typeString +
"-status", artdaqNode.second[paramIndex++], parentEl);
8221 __SUP_COUTT__ <<
"\t\t\t"
8222 <<
"-hostname: " << artdaqNode.second[paramIndex] << __E__;
8224 typeString +
"-hostname", artdaqNode.second[paramIndex++], parentEl);
8225 __SUP_COUTT__ <<
"\t\t\t"
8226 <<
"-subsystem: " << artdaqNode.second[paramIndex] << __E__;
8228 typeString +
"-subsystem", artdaqNode.second[paramIndex], parentEl);
8232 __SUP_COUT__ <<
"Done retrieving artdaq nodes." << __E__;
8243 void ConfigurationGUISupervisor::handleSaveArtdaqNodeRecordsXML(
8244 const std::string& nodeString,
8245 const std::string& subsystemString,
8248 const std::string& modifiedTables)
8250 __SUP_COUT__ <<
"Saving artdaq nodes..." << __E__;
8253 setupActiveTablesXML(
8254 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8257 std::map<std::string ,
8258 std::map<std::string , std::vector<std::string >>>
8259 nodeTypeToObjectMap;
8265 std::map<std::string , std::string >
8266 nodeTypeToStringMap;
8271 for(
auto& typePair : nodeTypeToStringMap)
8273 if(typePair.first ==
"")
8278 nodeTypeToObjectMap.emplace(
8280 std::map<std::string ,
8281 std::vector<std::string /*property*/>>()));
8283 std::map<std::string , std::string >
8284 nodeRecordToStringMap;
8287 typePair.second, nodeRecordToStringMap, {
';'}, {
'='});
8291 for(
auto& nodePair : nodeRecordToStringMap)
8293 if(nodePair.first ==
"")
8298 std::vector<std::string > nodePropertyVector;
8301 nodePair.second, nodePropertyVector, {
','});
8306 for(
unsigned int i = 0; i < nodePropertyVector.size(); ++i)
8311 nodePropertyVector[i] =
8315 nodeTypeToObjectMap[typePair.first].emplace(
8317 nodePropertyVector));
8323 std::map<std::string , std::string >
8330 std::map<std::string , std::string >
8331 tmpSubsystemObjectMap;
8333 subsystemString, tmpSubsystemObjectMap, {
';'}, {
':'});
8338 for(
auto& subsystemPair : tmpSubsystemObjectMap)
8343 subsystemObjectMap.emplace(
8350 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap);
8352 __SUP_COUT__ <<
"Done saving artdaq nodes." << __E__;
8362 void ConfigurationGUISupervisor::handleLoadArtdaqNodeLayoutXML(
8366 const std::string& contextGroupName ,
8369 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8372 const std::string& finalContextGroupName =
8374 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8378 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8380 const std::string& finalConfigGroupName =
8381 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8383 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8388 std::stringstream layoutPath;
8389 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8390 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8391 << finalConfigGroupKey <<
".dat";
8393 fp = fopen(layoutPath.str().c_str(),
"r");
8396 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8397 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
8398 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
8402 __SUP_COUTV__(layoutPath.str());
8407 std::stringstream layoutPath;
8408 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8409 <<
"_" << finalContextGroupKey <<
".dat";
8410 __SUP_COUTV__(layoutPath.str());
8412 fp = fopen(layoutPath.str().c_str(),
"r");
8415 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8416 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
8420 __SUP_COUTV__(layoutPath.str());
8427 const size_t maxLineSz = 1000;
8428 char line[maxLineSz];
8429 if(!fgets(line, maxLineSz, fp))
8438 unsigned int rows, cols;
8440 sscanf(line,
"%u %u", &rows, &cols);
8442 __COUT__ <<
"Grid rows,cols = " << rows <<
"," << cols << __E__;
8444 xmlOut.addTextElementToData(
"grid-rows", std::to_string(rows));
8445 xmlOut.addTextElementToData(
"grid-cols", std::to_string(cols));
8448 char name[maxLineSz];
8449 char type[maxLineSz];
8451 while(fgets(line, maxLineSz, fp))
8454 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
8456 xmlOut.addTextElementToData(
"node-type", type);
8457 xmlOut.addTextElementToData(
"node-name", name);
8458 xmlOut.addTextElementToData(
"node-x", std::to_string(x));
8459 xmlOut.addTextElementToData(
"node-y", std::to_string(y));
8473 void ConfigurationGUISupervisor::handleSaveArtdaqNodeLayoutXML(
8476 const std::string& layoutString,
8477 const std::string& contextGroupName,
8480 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8482 const std::string& finalContextGroupName =
8484 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8488 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8490 const std::string& finalConfigGroupName =
8491 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8493 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8495 __SUP_COUTV__(layoutString);
8497 std::stringstream layoutPath;
8498 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8499 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8500 << finalConfigGroupKey <<
".dat";
8501 __SUP_COUTV__(layoutPath.str());
8506 if(fields.size() < 2 || (fields.size() - 2) % 4 != 0)
8508 __SUP_SS__ <<
"Invalid layout string fields size of " << fields.size() << __E__;
8512 FILE* fp = fopen(layoutPath.str().c_str(),
"w");
8515 __SUP_SS__ <<
"Could not open layout file for writing for '"
8516 << finalContextGroupName <<
"(" << finalContextGroupKey <<
") + "
8517 << finalConfigGroupName <<
"(" << finalConfigGroupKey
8518 <<
")': " << layoutPath.
str() << __E__;
8525 fprintf(fp,
"%s %s\n", fields[0].c_str(), fields[1].c_str());
8528 for(
unsigned int i = 2; i < fields.size(); i += 4)
8531 fields[i + 0].c_str(),
8532 fields[i + 1].c_str(),
8533 fields[i + 2].c_str(),
8534 fields[i + 3].c_str());
8542 void ConfigurationGUISupervisor::handleOtherSubsystemActiveGroups(
8546 std::string targetSubsystem )
8552 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8555 for(
auto subsystem : children)
8557 __SUP_COUTV__(subsystem.first);
8561 std::string userPath =
8562 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8563 __SUP_COUTV__(userPath);
8566 catch(
const std::runtime_error& e)
8568 __SUP_COUT__ <<
"Ignoring errors in handling other subsystem active groups "
8569 "(assuming the subsystem information map is not setup in "
8570 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8571 <<
") -- here is the error: \n"
8572 << e.what() << __E__;
8579 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8581 for(
auto subsystem : children)
8583 if(targetSubsystem !=
"" && targetSubsystem != subsystem.first)
8586 xercesc::DOMElement* parent =
8587 xmlOut.addTextElementToData(
"SubsystemName", subsystem.first);
8592 std::string filename, userDataPath;
8593 std::string username, hostname;
8595 std::map<std::string ,
8597 retMap = cfgMgr->getOtherSubsystemActiveTableGroups(
8598 subsystem.first, &userDataPath, &hostname, &username);
8600 for(
const auto& retPair : retMap)
8603 retPair.second.first,
8606 retPair.second.second.toString(),
8610 std::vector<std::string> filenameTypes = {
"Configured",
8614 "ActivatedBackbone",
8615 "ActivatedIterator"};
8617 std::vector<std::string> filenames = {
8618 ConfigurationManager::LAST_CONFIGURED_CONFIG_GROUP_FILE,
8619 ConfigurationManager::LAST_STARTED_CONFIG_GROUP_FILE,
8620 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
8621 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
8622 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
8623 ConfigurationManager::LAST_ACTIVATED_ITERATE_GROUP_FILE};
8625 std::string userPath =
8626 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8628 std::string cmdResult;
8629 for(
unsigned int i = 0; i < filenames.size(); ++i)
8631 filename = userDataPath +
"/ServiceData/RunControlData/" + filenames[i];
8632 __SUP_COUTV__(filename);
8634 std::string tmpSubsystemFilename =
8635 ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" + filenames[i] +
8636 "." + subsystem.first;
8637 __SUP_COUTV__(tmpSubsystemFilename);
8639 if(splitPath.size() == 2)
8643 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + username +
8644 "@" + hostname +
":" + filename +
" " + tmpSubsystemFilename +
8645 " 2>&1; cat " + tmpSubsystemFilename +
" 2>&1")
8649 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + hostname +
8650 ":" + filename +
" " + tmpSubsystemFilename +
" 2>&1; cat " +
8651 tmpSubsystemFilename +
" 2>&1")
8654 else if(splitPath.size() == 1)
8657 " 2>/dev/null; cp " + filename +
" " +
8658 tmpSubsystemFilename +
" 2>&1; cat " +
8659 tmpSubsystemFilename +
" 2>&1")
8663 __SUP_COUTV__(cmdResult);
8664 std::string timeString;
8667 filenames[i] +
"." + subsystem.first, timeString);
8671 "Last" + filenameTypes[i] +
"GroupName", theGroup.first, parent);
8673 theGroup.second.toString(),
8676 "Last" + filenameTypes[i] +
"GroupTime", timeString, parent);
8681 catch(
const std::runtime_error& e)
8684 <<
"An error occurred handling subsystem active groups (Please check the "
8685 "subsystem user data path information map setup in the Context group table "
8686 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8687 <<
") -- here is the error: \n"
8688 << e.what() << __E__;
8694 void ConfigurationGUISupervisor::handleGroupDiff(
8697 const std::string& groupName,
8700 const std::string& diffGroupNameInput )
8706 std::string diffGroupName;
8709 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8710 <<
") with the active group." << __E__;
8713 if(diffGroupNameInput ==
"")
8714 diffGroupName = groupName;
8716 diffGroupName = diffGroupNameInput;
8718 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8719 <<
") with group " << diffGroupName <<
"(" << diffKey <<
")"
8725 std::map<std::string ,
TableVersion > memberMap, diffMemberMap;
8726 std::string groupType, accumulateErrors;
8727 std::stringstream diffReport;
8728 bool noDifference =
true;
8747 std::map<std::string , std::pair<std::string, TableGroupKey>>
8754 __SUP_COUTV__(groupType);
8756 if(activeGroups.find(groupType) == activeGroups.end() ||
8757 activeGroups.at(groupType).first ==
"" ||
8758 activeGroups.at(groupType).second.isInvalid())
8760 __SUP_SS__ <<
"Could not find an active group of type '" << groupType
8761 <<
".' Please check the expected active configuration groups "
8762 "for errors (going to 'System View' of the Config App may "
8768 __SUP_COUT__ <<
"active " << groupType <<
" group is "
8769 << activeGroups.at(groupType).first <<
"("
8770 << activeGroups.at(groupType).second <<
")" << __E__;
8772 diffReport <<
"This difference report is between " << groupType
8773 <<
" group <b>'" << groupName <<
"(" << groupKey <<
")'</b>"
8774 <<
" and active group <b>'" << activeGroups.at(groupType).first
8775 <<
"(" << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8778 activeGroups.at(groupType).second,
8788 diffReport <<
"\n\n"
8789 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8790 << memberMap.size() <<
" member tables</b>, and "
8791 <<
"'" << activeGroups.at(groupType).first <<
"("
8792 << activeGroups.at(groupType).second <<
")' has <b>"
8793 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8797 diffReport <<
"This difference report is between group <b>'" << groupName
8798 <<
"(" << groupKey <<
")'</b>"
8799 <<
" and group <b>'" << diffGroupName <<
"(" << diffKey
8800 <<
")'</b>." << __E__;
8813 diffReport <<
"\n\n"
8814 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8815 << memberMap.size() <<
" member tables</b>, and "
8816 <<
"'" << diffGroupName <<
"(" << diffKey <<
")' has <b>"
8817 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8822 diffReport <<
"<INDENT><ol>";
8824 unsigned int tableDifferences = 0;
8826 for(
auto& member : memberMap)
8828 if(diffMemberMap.find(member.first) == diffMemberMap.end())
8830 diffReport <<
"\n\n<li>"
8831 <<
"Table <b>" << member.first <<
"-v" << member.second
8832 <<
"</b> not found in active group."
8833 <<
"</li>" << __E__;
8834 noDifference =
false;
8839 __SUP_COUTT__ <<
"Comparing " << member.first <<
"-v" << member.second
8840 <<
" ... " << member.first <<
"-v"
8841 << diffMemberMap.at(member.first) << __E__;
8843 if(member.second == diffMemberMap.at(member.first))
8846 diffReport <<
"\n\n<li>"
8847 <<
"Table <b>" << member.first <<
" v" << member.second
8848 <<
"</b> in " << groupName <<
"(" << groupKey <<
")' ...vs... "
8849 <<
" <b>v" << diffMemberMap.at(member.first) <<
"</b> in "
8850 << diffGroupName <<
"(" << diffKey <<
")':" << __E__;
8854 diffReport <<
"<ul>";
8855 std::map<std::string , std::vector<std::string >>
8857 if(!table->diffTwoVersions(member.second,
8858 diffMemberMap.at(member.first),
8863 noDifference =
false;
8866 xmlOut.addTextElementToData(
"TableWithDiff", member.first);
8867 for(
auto& modifiedRecord : modifiedRecords)
8870 "RecordWithDiff", modifiedRecord.first, parentEl);
8871 for(
auto& modifiedColumn : modifiedRecord.second)
8873 "ColNameWithDiff", modifiedColumn, recordParentEl);
8876 diffReport <<
"</ul></li>";
8880 for(
auto& diffMember : diffMemberMap)
8882 if(memberMap.find(diffMember.first) == memberMap.end())
8885 diffReport <<
"\n\n<li>"
8886 <<
"Active Group Table <b>" << diffMember.first <<
"-v"
8887 << diffMember.second <<
"</b> not found in '" << groupName
8888 <<
"(" << groupKey <<
")'."
8889 <<
"</li>" << __E__;
8891 diffReport <<
"\n\n<li>" << diffGroupName <<
"(" << diffKey
8892 <<
") Table <b>" << diffMember.first <<
"-v"
8893 << diffMember.second <<
"</b> not found in '" << groupName
8894 <<
"(" << groupKey <<
")'."
8895 <<
"</li>" << __E__;
8897 noDifference =
false;
8902 diffReport <<
"\n</ol></INDENT>";
8907 diffReport <<
"\n\nNo difference found between "
8908 <<
"<b>'" << groupName <<
"(" << groupKey
8909 <<
")'</b> and active group "
8910 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8911 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8913 diffReport <<
"\n\n<b>" << tableDifferences
8914 <<
"</b> member table differences identified between "
8915 <<
"<b>'" << groupName <<
"(" << groupKey
8916 <<
")'</b> and active group "
8917 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8918 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8923 diffReport <<
"\n\nNo difference found between "
8924 <<
"<b>'" << groupName <<
"(" << groupKey
8925 <<
")'</b> and group "
8926 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8929 diffReport <<
"\n\n<b>" << tableDifferences
8930 <<
"</b> member table differences identified between "
8931 <<
"<b>'" << groupName <<
"(" << groupKey
8932 <<
")'</b> and group "
8933 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8937 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8938 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8940 catch(
const std::runtime_error& e)
8942 __SUP_COUT_ERR__ <<
"Caught error while differencing group " << groupName <<
"("
8943 << groupKey <<
") with group " << diffGroupName <<
"(" << diffKey
8944 <<
")" << __E__ << e.what() << __E__;
8951 void ConfigurationGUISupervisor::handleTableDiff(
HttpXmlDocument& xmlOut,
8953 const std::string& tableName,
8957 __SUP_COUT__ <<
"Differencing tableName " << tableName <<
" v" << vA <<
" with v"
8967 std::string localAccumulatedErrors =
"";
8971 &localAccumulatedErrors,
8974 if(localAccumulatedErrors !=
"")
8975 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8977 catch(std::runtime_error& e)
8979 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vA;
8980 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8981 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8983 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8987 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vA << __E__;
8992 catch(
const std::exception& e)
8994 ss <<
"Exception message: " << e.what();
9000 __SUP_COUT_ERR__ <<
"\n" << ss.str();
9001 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
9007 std::string localAccumulatedErrors =
"";
9011 &localAccumulatedErrors,
9014 if(localAccumulatedErrors !=
"")
9015 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
9017 catch(std::runtime_error& e)
9019 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vB;
9020 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
9021 __SUP_COUT_ERR__ <<
"\n" << ss.str();
9023 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
9027 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vB << __E__;
9032 catch(
const std::exception& e)
9034 ss <<
"Exception message: " << e.what();
9040 __SUP_COUT_ERR__ <<
"\n" << ss.str();
9041 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
9044 bool noDifference =
true;
9045 std::stringstream diffReport;
9047 diffReport <<
"This difference report is between table " << tableName <<
" v" << vA
9048 <<
" and v" << vB <<
"</b>." << __E__;
9050 diffReport <<
"<INDENT>";
9051 diffReport <<
"<ul>";
9052 std::map<std::string , std::vector<std::string >>
9054 if(!table->diffTwoVersions(vA, vB, &diffReport))
9055 noDifference =
false;
9056 diffReport <<
"</ul></INDENT>";
9058 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
9059 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
9065 void ConfigurationGUISupervisor::testXDAQContext()
9069 __COUT_INFO__ <<
"Hello0!";
9071 __COUT_INFO__ <<
"Hello1!";
9073 __COUT_INFO__ <<
"Hello2!";
9075 __COUT_INFO__ <<
"Hello3!";
9081 __SUP_COUT_INFO__ <<
"Attempting test activation of the context group." << __E__;
9085 catch(
const std::runtime_error& e)
9088 <<
"The test activation of the context group failed. Ignoring error: \n"
9089 << e.what() << __E__;
9094 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
9099 __SUP_COUT_INFO__ <<
"Completed test activation of the context group." << __E__;
static void setAndActivateARTDAQSystem(ConfigurationManagerRW *cfgMgr, const std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, const std::map< std::string, std::string > &subsystemObjectMap)
static const ARTDAQInfo & getARTDAQSystem(ConfigurationManagerRW *cfgMgr, std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, std::map< std::string, std::string > &subsystemObjectMap, std::vector< std::string > &artdaqSupervisoInfo)
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
virtual void setSupervisorPropertyDefaults(void) override
ConfigurationGUISupervisor(xdaq::ApplicationStub *s)
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)
TableVersion saveNewTable(const std::string &tableName, TableVersion temporaryVersion=TableVersion(), bool makeTemporary=false)
void testXDAQContext(void)
const GroupInfo & getGroupInfo(const std::string &groupName, bool attemptToReloadKeys=false)
void clearAllCachedVersions(void)
const std::map< std::string, TableInfo > & getAllTableInfo(bool refresh=false, std::string *accumulatedWarnings=0, const std::string &errorFilterName="", bool getGroupKeys=false, bool getGroupInfo=false, bool initializeActiveGroups=false)
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType groupTypeToLoad=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
TableVersion copyViewToCurrentColumns(const std::string &tableName, TableVersion sourceVersion)
TableGroupKey saveNewTableGroup(const std::string &groupName, std::map< std::string, TableVersion > &groupMembers, const std::string &groupComment=TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT, std::map< std::string, std::string > *groupAliases=0)
void activateTableGroup(const std::string &tableGroupName, TableGroupKey tableGroupKey, std::string *accumulatedTreeErrors=0, std::string *groupTypeString=0)
void clearCachedVersions(const std::string &tableName)
const std::string & getUsername(void) const
std::map< std::string, std::map< std::string, TableVersion > > getVersionAliases(void) const
void eraseTemporaryVersion(const std::string &tableName, TableVersion targetVersion=TableVersion())
static void loadTableGroupThread(ConfigurationManagerRW *cfgMgr, std::string groupName, ots::TableGroupKey groupKey, std::shared_ptr< ots::GroupInfo > theGroupInfo, std::shared_ptr< std::atomic< bool >> theThreadDone)
TableBase * getVersionedTableByName(const std::string &tableName, TableVersion version, bool looseColumnMatching=false, std::string *accumulatedErrors=0, bool getRawData=false)
static const unsigned int PROCESSOR_COUNT
void restoreActiveTableGroups(bool throwErrors=false, const std::string &pathToActiveGroupsFile="", ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, std::string *accumulatedWarnings=0)
std::map< std::string, std::pair< std::string, TableGroupKey > > getActiveTableGroups(void) const
std::map< std::string, TableVersion > getActiveVersions(void) const
void copyTableGroupFromCache(const ConfigurationManager &cacheConfigMgr, const std::map< std::string, TableVersion > &groupMembers, const std::string &configGroupName="", const TableGroupKey &tableGroupKey=TableGroupKey(TableGroupKey::INVALID), bool doActivate=false, bool ignoreVersionTracking=false)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
void init(std::string *accumulatedErrors=0, bool initForWriteAccess=false, std::string *accumulatedWarnings=0)
static const std::string & getTypeNameOfGroup(const std::map< std::string, TableVersion > &memberMap)
void destroyTableGroup(const std::string &theGroup="", bool onlyDeactivate=false)
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
static std::vector< std::map< std::string, std::string > > loadGroupHistory(const std::string &groupAction, const std::string &groupType, bool formatTime=false)
TableGroupKey loadConfigurationBackbone(void)
const TableBase * getTableByName(const std::string &configurationName) const
static std::pair< std::string, TableGroupKey > loadGroupNameAndKey(const std::string &fileName, std::string &returnedTimeString)
static void getConfigurationStatusXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &username)
static void handleGetTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, TableGroupKey groupKey, bool ignoreWarnings=false, bool cacheOnly=false)
static TableVersion saveModifiedVersionXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion originalVersion, bool makeTemporary, TableBase *config, TableVersion temporaryModifiedVersion, bool ignoreDuplicates=false, bool lookForEquivalent=false)
static void handleCreateTableXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion version, bool makeTemporary, const std::string &data, const int &dataOffset, const std::string &author, const std::string &comment, bool sourceTableAsIs, bool lookForEquivalent)
static void handleCreateTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, const std::string &configList, bool allowDuplicates=false, bool ignoreWarnings=false, const std::string &groupComment="", bool lookForEquivalent=false)
bool isUIDNode(void) const
const TableVersion & getTableVersion(void) const
bool isDisconnected(void) const
const std::string & getAuthor(void) const
const std::string & getComment(void) const
std::vector< std::string > getChildrenNames(bool byPriority=false, bool onlyStatusTrue=false) const
bool isEnabled(void) const
const std::string & getTableName(void) const
const unsigned int & getFieldRow(void) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
const std::string & getValueName(void) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const std::string & getChildLinkIndex(void) const
const std::string & getDisconnectedTableName(void) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::vector< std::string > getFixedChoices(void) const
bool isLinkNode(void) const
std::vector< ConfigurationTree::RecordField > getCommonFields(const std::vector< std::string > &recordList, const std::vector< std::string > &fieldAcceptList, const std::vector< std::string > &fieldRejectList, unsigned int depth=-1, bool autoSelectFilterFields=false) const
bool isValueNode(void) const
std::set< std::string > getUniqueValuesForField(const std::vector< std::string > &recordList, const std::string &fieldName, std::string *fieldGroupIDChildLinkIndex=0) const
const std::string & getValueType(void) const
bool isGroupLinkNode(void) const
const std::string & getFieldTableName(void) const
const std::string & getDisconnectedLinkID(void) const
const std::string & getParentTableName(void) const
bool isUIDLinkNode(void) const
const unsigned int & getFieldColumn(void) const
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)
static const std::string & getDefaultDefaultValue(const std::string &type, const std::string &dataType)
static const std::string & getMaxDefaultValue(const std::string &dataType)
static const std::string & getMinDefaultValue(const std::string &dataType)
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
bool isEntryInGroup(const unsigned int &row, const std::string &childLinkIndex, const std::string &groupNeedle) const
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
unsigned int getColStatus(void) const
unsigned int getLinkGroupIDColumn(const std::string &childLinkIndex) const
bool removeRowFromGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID, bool deleteRowIfNoGroupLeft=false)
bool getChildLink(const unsigned int &col, bool &isGroup, std::pair< unsigned int, unsigned int > &linkPair) const
void addRowToGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID)
std::string getValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true) const
void getValue(T &value, unsigned int row, unsigned int col, bool doConvertEnvironmentVariables=true) const
unsigned int getColUID(void) const
bool setURIEncodedValue(const std::string &value, const unsigned int &row, const unsigned int &col, const std::string &author="")
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
void setURIEncodedComment(const std::string &uriComment)
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void INIT_MF(const char *name)
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
static std::string escapeString(std::string inString, bool allowWhiteSpace=false, 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)