1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
2 #include "otsdaq-core/ConfigurationPluginDataFormats/IterateConfiguration.h"
3 #include "otsdaq-core/MessageFacility/MessageFacility.h"
4 #include "otsdaq-core/Macros/CoutMacros.h"
5 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
6 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
8 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
9 #include <boost/stacktrace.hpp>
12 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
14 #include <xdaq/NamespaceURI.h>
25 #define __MF_SUBJECT__ "CfgGUI"
27 #define CONFIG_INFO_PATH std::string(getenv("CONFIGURATION_INFO_PATH")) + "/"
28 #define CONFIG_INFO_EXT std::string("Info.xml")
40 ConfigurationGUISupervisor::ConfigurationGUISupervisor(xdaq::ApplicationStub* stub)
41 : CoreSupervisorBase (stub)
43 __SUP_COUT__ <<
"Constructor started." << __E__;
45 INIT_MF(
"ConfigurationGUI");
48 __SUP_COUT__ <<
"Constructor complete." << __E__;
52 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void)
58 void ConfigurationGUISupervisor::init(
void)
60 __SUP_COUT__ <<
"Initializing..." << std::endl;
62 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..." << std::endl;
69 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, will not launch when this test fails. " <<
70 "Check the active context group from within Wizard Mode." << __E__;
76 void ConfigurationGUISupervisor::destroy(
void)
79 for (std::map<std::string, ConfigurationManagerRW* > ::iterator it=userConfigurationManagers_.begin(); it!=userConfigurationManagers_.end(); ++it)
84 userConfigurationManagers_.clear();
87 if( ConfigurationInterface::getInstance(
true) != 0 )
88 delete ConfigurationInterface::getInstance(
true);
92 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out )
94 cgicc::Cgicc cgiIn(in);
95 std::string configName = CgiDataUtilities::getData(cgiIn,
"configWindowName");
96 if(configName ==
"tableEditor")
97 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/ConfigurationTableEditor.html?urn=" <<
98 this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
99 if(configName ==
"iterate")
100 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/Iterate.html?urn=" <<
101 this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
103 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/ConfigurationGUI.html?urn=" <<
104 this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
111 void ConfigurationGUISupervisor::setSupervisorPropertyDefaults(
void)
113 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
114 "*=10 | deleteTreeNodeRecords=255 | saveConfigurationInfo=255 | deleteConfigurationInfo=255");
115 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
122 void ConfigurationGUISupervisor::forceSupervisorPropertyValues()
124 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
126 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
131 void ConfigurationGUISupervisor::request(
const std::string& requestType, cgicc::Cgicc& cgiIn,
132 HttpXmlDocument& xmlOut,
const WebUsers::RequestUserInfo& userInfo)
188 std::string refresh = CgiDataUtilities::getData(cgiIn,
"refresh");
192 ConfigurationManagerRW* cfgMgr = refreshUserSession(userInfo.username_,
193 userInfo.activeUserSessionIndex_,
196 if(requestType ==
"saveConfigurationInfo")
198 std::string configName = CgiDataUtilities::getData (cgiIn,
"configName");
199 std::string columnCSV = CgiDataUtilities::postData(cgiIn,
"columnCSV");
200 std::string allowOverwrite = CgiDataUtilities::getData (cgiIn,
"allowOverwrite");
201 std::string tableDescription = CgiDataUtilities::postData(cgiIn,
"tableDescription");
202 std::string columnChoicesCSV = CgiDataUtilities::postData(cgiIn,
"columnChoicesCSV");
207 __SUP_COUT__ <<
"configName: " << configName << std::endl;
208 __SUP_COUT__ <<
"columnCSV: " << columnCSV << std::endl;
209 __SUP_COUT__ <<
"tableDescription: " << tableDescription << std::endl;
210 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << std::endl;
211 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << std::endl;
213 if(!allSupervisorInfo_.isWizardMode())
215 __SUP_SS__ <<
"Improper permissions for saving configuration info." << std::endl;
216 xmlOut.addTextElementToData(
"Error", ss.str());
219 handleSaveConfigurationInfoXML(xmlOut,cfgMgr,configName,columnCSV,tableDescription,
220 columnChoicesCSV,allowOverwrite==
"1");
222 else if(requestType ==
"deleteConfigurationInfo")
224 std::string configName = CgiDataUtilities::getData(cgiIn,
"configName");
225 __SUP_COUT__ <<
"configName: " << configName << std::endl;
226 handleDeleteConfigurationInfoXML(xmlOut,cfgMgr,configName);
228 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
229 requestType ==
"flattenToSystemAliases")
232 __SUP_COUT_WARN__ << requestType <<
" command received! " << std::endl;
233 __MOUT_WARN__ << requestType <<
" command received! " << std::endl;
236 __SUP_COUT_INFO__ <<
"Launching... " << std::endl;
238 __SUP_COUT__ <<
"Extracting target context hostnames... " << std::endl;
239 std::vector<std::string> hostnames;
244 const XDAQContextConfiguration* contextConfiguration = cfgMgr->__GET_CONFIG__(XDAQContextConfiguration);
246 auto contexts = contextConfiguration->getContexts();
248 for(
const auto& context: contexts)
250 if(!context.status_)
continue;
254 for(i=0;i<context.address_.size();++i)
255 if(context.address_[i] ==
'/')
257 hostnames.push_back(context.address_.substr(j));
258 __SUP_COUT__ <<
"hostname = " << hostnames.back() << std::endl;
263 __SUP_SS__ <<
"\nTransition to Configuring interrupted! " <<
264 "The Configuration Manager could not be initialized." << std::endl;
266 __SUP_COUT_ERR__ <<
"\n" << ss.str();
270 for(
const auto& hostname: hostnames)
272 std::string fn = (std::string(getenv(
"SERVICE_DATA_PATH")) +
273 "/StartOTS_action_" + hostname +
".cmd");
274 FILE* fp = fopen(fn.c_str(),
"w");
277 if(requestType ==
"gatewayLaunchOTS")
278 fprintf(fp,
"LAUNCH_OTS");
279 else if(requestType ==
"gatewayLaunchWiz")
280 fprintf(fp,
"LAUNCH_WIZ");
281 else if(requestType ==
"flattenToSystemAliases")
283 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
291 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << std::endl;
340 else if(requestType ==
"versionTracking")
342 std::string type = CgiDataUtilities::getData(cgiIn,
"Type");
343 __SUP_COUT__ <<
"type: " << type << std::endl;
346 xmlOut.addTextElementToData(
"versionTrackingStatus",
347 ConfigurationInterface::isVersionTrackingEnabled()?
"ON":
"OFF");
348 else if(type ==
"ON")
350 ConfigurationInterface::setVersionTrackingEnabled(
true);
351 xmlOut.addTextElementToData(
"versionTrackingStatus",
352 ConfigurationInterface::isVersionTrackingEnabled()?
"ON":
"OFF");
354 else if(type ==
"OFF")
356 ConfigurationInterface::setVersionTrackingEnabled(
false);
357 xmlOut.addTextElementToData(
"versionTrackingStatus",
358 ConfigurationInterface::isVersionTrackingEnabled()?
"ON":
"OFF");
361 else if(requestType ==
"getColumnTypes")
364 std::vector<std::string> allTypes = ViewColumnInfo::getAllTypesForGUI();
365 std::vector<std::string> allDataTypes = ViewColumnInfo::getAllDataTypesForGUI();
366 std::map<std::pair<std::string,std::string>,std::string> allDefaults =
367 ViewColumnInfo::getAllDefaultsForGUI();
369 for(
const auto& type:allTypes)
370 xmlOut.addTextElementToData(
"columnTypeForGUI",
372 for(
const auto& dataType:allDataTypes)
373 xmlOut.addTextElementToData(
"columnDataTypeForGUI",
376 for(
const auto& colDefault:allDefaults)
378 xmlOut.addTextElementToData(
"columnDefaultDataType",
379 colDefault.first.first);
380 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
381 colDefault.first.second);
382 xmlOut.addTextElementToData(
"columnDefaultValue",
386 else if(requestType ==
"getGroupAliases")
390 bool reloadActive = 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
392 __SUP_COUT__ <<
"reloadActive: " << reloadActive << std::endl;
393 bool wasError =
false;
398 cfgMgr->clearAllCachedVersions();
399 cfgMgr->restoreActiveConfigurationGroups(
true);
401 catch(std::runtime_error& e)
403 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what())) << std::endl;
404 __SUP_COUT_ERR__ <<
"\n" << ss.str();
405 xmlOut.addTextElementToData(
"Error", ss.str());
410 __SUP_SS__ << (
"Error loading active groups!\n\n") << std::endl;
411 __SUP_COUT_ERR__ <<
"\n" << ss.str();
412 xmlOut.addTextElementToData(
"Error", ss.str());
419 handleGroupAliasesXML(xmlOut,cfgMgr);
421 else if(requestType ==
"setGroupAliasInActiveBackbone")
423 std::string groupAlias = CgiDataUtilities::getData(cgiIn,
"groupAlias");
424 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
425 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
427 __SUP_COUT__ <<
"groupAlias: " << groupAlias << std::endl;
428 __SUP_COUT__ <<
"groupName: " << groupName << std::endl;
429 __SUP_COUT__ <<
"groupKey: " << groupKey << std::endl;
431 handleSetGroupAliasInBackboneXML(xmlOut,cfgMgr,groupAlias,groupName,
432 ConfigurationGroupKey(groupKey),userInfo.username_);
434 else if(requestType ==
"setVersionAliasInActiveBackbone")
436 std::string versionAlias = CgiDataUtilities::getData(cgiIn,
"versionAlias");
437 std::string configName = CgiDataUtilities::getData(cgiIn,
"configName");
438 std::string version = CgiDataUtilities::getData(cgiIn,
"version");
440 __SUP_COUT__ <<
"versionAlias: " << versionAlias << std::endl;
441 __SUP_COUT__ <<
"configName: " << configName << std::endl;
442 __SUP_COUT__ <<
"version: " << version << std::endl;
444 handleSetVersionAliasInBackboneXML(xmlOut,cfgMgr,versionAlias,
446 ConfigurationVersion(version),userInfo.username_);
448 else if(requestType ==
"setAliasOfGroupMembers")
450 std::string versionAlias = CgiDataUtilities::getData(cgiIn,
"versionAlias");
451 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
452 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
454 __SUP_COUT__ <<
"versionAlias: " << versionAlias << std::endl;
455 __SUP_COUT__ <<
"groupName: " << groupName << std::endl;
456 __SUP_COUT__ <<
"groupKey: " << groupKey << std::endl;
458 handleAliasGroupMembersInBackboneXML(xmlOut,cfgMgr,versionAlias,
460 ConfigurationGroupKey(groupKey),userInfo.username_);
462 else if(requestType ==
"getVersionAliases")
464 handleVersionAliasesXML(xmlOut,cfgMgr);
466 else if(requestType ==
"getConfigurationGroups")
468 bool doNotReturnMembers = CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1?
true:
false;
470 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << std::endl;
471 handleConfigurationGroupsXML(xmlOut,cfgMgr,!doNotReturnMembers);
473 else if(requestType ==
"getConfigurationGroupType")
475 std::string configList = CgiDataUtilities::postData(cgiIn,
"configList");
476 __SUP_COUT__ <<
"configList: " << configList << std::endl;
478 handleGetConfigurationGroupTypeXML(xmlOut,cfgMgr,configList);
480 else if(requestType ==
"getConfigurations")
482 std::string allowIllegalColumns = CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
484 __SUP_COUT__ <<
"allowIllegalColumns: " << allowIllegalColumns << std::endl;
486 handleConfigurationsXML(xmlOut,cfgMgr, allowIllegalColumns ==
"1");
488 else if(requestType ==
"getContextMemberNames")
490 std::set<std::string> members = cfgMgr->getContextMemberNames();
492 for(
auto& member:members)
493 xmlOut.addTextElementToData(
"ContextMember", member);
495 else if(requestType ==
"getBackboneMemberNames")
497 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
499 for(
auto& member:members)
500 xmlOut.addTextElementToData(
"BackboneMember", member);
502 else if(requestType ==
"getIterateMemberNames")
504 std::set<std::string> members = cfgMgr->getIterateMemberNames();
506 for(
auto& member:members)
507 xmlOut.addTextElementToData(
"IterateMember", member);
509 else if(requestType ==
"getSpecificConfigurationGroup")
511 std::string groupName = CgiDataUtilities::getData (cgiIn,
"groupName");
512 std::string groupKey = CgiDataUtilities::getData (cgiIn,
"groupKey");
514 __SUP_COUT__ <<
"groupName: " << groupName << std::endl;
515 __SUP_COUT__ <<
"groupKey: " << groupKey << std::endl;
517 handleGetConfigurationGroupXML(xmlOut,cfgMgr,groupName,ConfigurationGroupKey(groupKey));
519 else if(requestType ==
"saveNewConfigurationGroup")
521 std::string groupName = CgiDataUtilities::getData (cgiIn,
"groupName");
522 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
523 bool allowDuplicates = CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
524 bool lookForEquivalent = CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
525 std::string configList = CgiDataUtilities::postData (cgiIn,
"configList");
526 std::string comment = CgiDataUtilities::getData (cgiIn,
"groupComment");
528 __SUP_COUT__ <<
"saveNewConfigurationGroup: " << groupName << std::endl;
529 __SUP_COUT__ <<
"configList: " << configList << std::endl;
530 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << std::endl;
531 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << std::endl;
532 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << std::endl;
533 __SUP_COUT__ <<
"comment: " << comment << std::endl;
535 handleCreateConfigurationGroupXML(xmlOut,cfgMgr,groupName,configList,
536 allowDuplicates,ignoreWarnings,comment,lookForEquivalent);
538 else if(requestType ==
"getSpecificConfiguration")
540 std::string configName = CgiDataUtilities::getData (cgiIn,
"configName");
541 std::string versionStr = CgiDataUtilities::getData (cgiIn,
"version");
542 int dataOffset = CgiDataUtilities::getDataAsInt (cgiIn,
"dataOffset");
543 int chunkSize = CgiDataUtilities::getDataAsInt (cgiIn,
"chunkSize");
545 std::string allowIllegalColumns = CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
546 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns==
"1") << std::endl;
548 __SUP_COUT__ <<
"getSpecificConfiguration: " << configName <<
" versionStr: " << versionStr
549 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset << std::endl;
551 ConfigurationVersion version;
552 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo();
553 std::string versionAlias;
555 if(allCfgInfo.find(configName) != allCfgInfo.end())
557 if(versionStr ==
"" &&
558 allCfgInfo.at(configName).versions_.size())
559 version =* (allCfgInfo.at(configName).versions_.rbegin());
560 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
563 std::map<std::string , std::map<
564 std::string ,ConfigurationVersion> > versionAliases =
565 cfgMgr->getVersionAliases();
567 versionAlias = versionStr.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
574 if(versionAliases.find(configName) != versionAliases.end() &&
575 versionAliases[configName].find(versionStr.substr(
576 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())) !=
577 versionAliases[configName].end())
579 version = versionAliases[configName][versionStr.substr(
580 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())];
581 __SUP_COUT__ <<
"version alias translated to: " << version << std::endl;
584 __SUP_COUT_WARN__ <<
"version alias '" << versionStr.substr(
585 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size()) <<
586 "'was not found in active version aliases!" << std::endl;
589 version = atoi(versionStr.c_str());
592 __SUP_COUT__ <<
"version: " << version << std::endl;
594 handleGetConfigurationXML(xmlOut,cfgMgr,configName,ConfigurationVersion(version),
595 (allowIllegalColumns==
"1"));
597 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
599 else if(requestType ==
"saveSpecificConfiguration")
601 std::string configName = CgiDataUtilities::getData (cgiIn,
"configName");
602 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
603 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
604 bool sourceTableAsIs = CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
605 bool lookForEquivalent = CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
606 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
607 std::string comment = CgiDataUtilities::getData (cgiIn,
"tableComment");
609 std::string data = CgiDataUtilities::postData(cgiIn,
"data");
613 __SUP_COUT__ <<
"configName: " << configName <<
" version: " << version
614 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset << std::endl;
615 __SUP_COUT__ <<
"comment: " << comment << std::endl;
616 __SUP_COUT__ <<
"data: " << data << std::endl;
617 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << std::endl;
618 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << std::endl;
620 handleCreateConfigurationXML(xmlOut,cfgMgr,configName,ConfigurationVersion(version),
621 temporary,data,dataOffset,userInfo.username_,comment,sourceTableAsIs,lookForEquivalent);
623 else if(requestType ==
"clearConfigurationTemporaryVersions")
625 std::string configName = CgiDataUtilities::getData (cgiIn,
"configName");
626 __SUP_COUT__ <<
"configName: " << configName << std::endl;
628 try { cfgMgr->eraseTemporaryVersion(configName);}
629 catch(std::runtime_error& e)
631 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
632 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views!\n " +
633 std::string(e.what()));
637 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
638 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
641 else if(requestType ==
"clearConfigurationCachedVersions")
643 std::string configName = CgiDataUtilities::getData (cgiIn,
"configName");
644 __SUP_COUT__ <<
"configName: " << configName << std::endl;
646 try { cfgMgr->clearCachedVersions(configName);}
647 catch(std::runtime_error& e)
649 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
650 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views!\n " +
651 std::string(e.what()));
655 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
656 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
659 else if(requestType ==
"getTreeView")
661 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
662 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
663 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
664 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
665 std::string filterList = CgiDataUtilities::postData(cgiIn,
"filterList");
666 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
667 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
669 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
670 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
671 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
672 __SUP_COUT__ <<
"depth: " << depth << std::endl;
673 __SUP_COUT__ <<
"hideStatusFalse: " << hideStatusFalse << std::endl;
674 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
675 __SUP_COUT__ <<
"filterList: " << filterList << std::endl;
677 handleFillTreeViewXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
678 startPath,depth,hideStatusFalse,modifiedTables,filterList);
680 else if(requestType ==
"getTreeNodeCommonFields")
682 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
683 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
684 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
685 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
686 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
687 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
688 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
690 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
691 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
692 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
693 __SUP_COUT__ <<
"depth: " << depth << std::endl;
694 __SUP_COUT__ <<
"fieldList: " << fieldList << std::endl;
695 __SUP_COUT__ <<
"recordList: " << recordList << std::endl;
696 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
698 handleFillTreeNodeCommonFieldsXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
699 startPath,depth,modifiedTables,recordList,fieldList);
702 else if(requestType ==
"getUniqueFieldValuesForRecords")
704 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
705 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
706 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
707 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
708 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
709 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
711 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
712 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
713 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
714 __SUP_COUT__ <<
"fieldList: " << fieldList << std::endl;
715 __SUP_COUT__ <<
"recordList: " << recordList << std::endl;
716 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
718 handleFillUniqueFieldValuesForRecordsXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
719 startPath,modifiedTables,recordList,fieldList);
722 else if(requestType ==
"getTreeNodeFieldValues")
724 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
725 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
726 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
727 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
728 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
729 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
731 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
732 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
733 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
734 __SUP_COUT__ <<
"fieldList: " << fieldList << std::endl;
735 __SUP_COUT__ <<
"recordList: " << recordList << std::endl;
736 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
738 handleFillGetTreeNodeFieldValuesXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
739 startPath,modifiedTables,recordList,fieldList);
741 else if(requestType ==
"setTreeNodeFieldValues")
743 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
744 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
745 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
746 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
747 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
748 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
749 std::string valueList = CgiDataUtilities::postData(cgiIn,
"valueList");
751 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
752 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
753 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
754 __SUP_COUT__ <<
"fieldList: " << fieldList << std::endl;
755 __SUP_COUT__ <<
"valueList: " << valueList << std::endl;
756 __SUP_COUT__ <<
"recordList: " << recordList << std::endl;
757 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
759 handleFillSetTreeNodeFieldValuesXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
760 startPath,modifiedTables,recordList,fieldList,valueList,userInfo.username_);
763 else if(requestType ==
"addTreeNodeRecords")
765 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
766 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
767 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
768 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
769 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
771 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
772 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
773 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
774 __SUP_COUT__ <<
"recordList: " << recordList << std::endl;
775 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
777 handleFillCreateTreeNodeRecordsXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
778 startPath,modifiedTables,recordList,userInfo.username_);
780 else if(requestType ==
"deleteTreeNodeRecords")
782 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
783 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
784 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
785 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
786 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
788 __SUP_COUT__ <<
"configGroup: " << configGroup << std::endl;
789 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << std::endl;
790 __SUP_COUT__ <<
"startPath: " << startPath << std::endl;
791 __SUP_COUT__ <<
"recordList: " << recordList << std::endl;
792 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
794 handleFillDeleteTreeNodeRecordsXML(xmlOut,cfgMgr,configGroup,ConfigurationGroupKey(configGroupKey),
795 startPath,modifiedTables,recordList);
797 else if(requestType ==
"getAffectedActiveGroups")
799 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
800 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
801 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
802 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
803 __SUP_COUT__ <<
"groupName: " << groupName << std::endl;
804 __SUP_COUT__ <<
"groupKey: " << groupKey << std::endl;
806 handleGetAffectedGroupsXML(xmlOut,cfgMgr,groupName,ConfigurationGroupKey(groupKey),
809 else if(requestType ==
"saveTreeNodeEdit")
811 std::string editNodeType = CgiDataUtilities::getData(cgiIn,
"editNodeType");
812 std::string targetTable = CgiDataUtilities::getData(cgiIn,
"targetTable");
813 std::string targetTableVersion = CgiDataUtilities::getData(cgiIn,
"targetTableVersion");
814 std::string targetUID = CgiDataUtilities::getData(cgiIn,
"targetUID");
815 std::string targetColumn = CgiDataUtilities::getData(cgiIn,
"targetColumn");
816 std::string newValue = CgiDataUtilities::postData(cgiIn,
"newValue");
818 __SUP_COUT__ <<
"editNodeType: " << editNodeType << std::endl;
819 __SUP_COUT__ <<
"targetTable: " << targetTable << std::endl;
820 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << std::endl;
821 __SUP_COUT__ <<
"targetUID: " << targetUID << std::endl;
822 __SUP_COUT__ <<
"targetColumn: " << targetColumn << std::endl;
823 __SUP_COUT__ <<
"newValue: " << newValue << std::endl;
825 handleSaveTreeNodeEditXML(xmlOut,cfgMgr,targetTable,ConfigurationVersion(targetTableVersion),
827 CgiDataUtilities::decodeURIComponent(targetUID),
828 CgiDataUtilities::decodeURIComponent(targetColumn),
829 newValue,userInfo.username_);
831 else if(requestType ==
"getLinkToChoices")
833 std::string linkToTableName = CgiDataUtilities::getData(cgiIn,
"linkToTableName");
834 std::string linkToTableVersion = CgiDataUtilities::getData(cgiIn,
"linkToTableVersion");
835 std::string linkIdType = CgiDataUtilities::getData(cgiIn,
"linkIdType");
836 std::string linkIndex = CgiDataUtilities::getData(cgiIn,
"linkIndex");
837 std::string linkInitId = CgiDataUtilities::getData(cgiIn,
"linkInitId");
839 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << std::endl;
840 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << std::endl;
841 __SUP_COUT__ <<
"linkIdType: " << linkIdType << std::endl;
842 __SUP_COUT__ <<
"linkIndex: " << linkIndex << std::endl;
843 __SUP_COUT__ <<
"linkInitId: " << linkInitId << std::endl;
845 handleGetLinkToChoicesXML(xmlOut,cfgMgr,linkToTableName,
846 ConfigurationVersion(linkToTableVersion),linkIdType,linkIndex,linkInitId);
848 else if(requestType ==
"activateConfigGroup")
850 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
851 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
852 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
854 __SUP_COUT__ <<
"Activating config: " << groupName <<
855 "(" << groupKey <<
")" << std::endl;
856 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << std::endl;
859 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
860 xmlOut.addTextElementToData(
"AttemptedGroupActivationName",groupName);
861 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey",groupKey);
863 std::string accumulatedTreeErrors;
866 cfgMgr->activateConfigurationGroup(groupName, ConfigurationGroupKey(groupKey),
867 ignoreWarnings?0:&accumulatedTreeErrors);
869 catch(std::runtime_error& e)
874 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
875 xmlOut.addTextElementToData(
"Error",
"Error activating config group '" +
876 groupName +
"(" + groupKey +
")" +
".' Please see details below:\n\n" +
877 std::string(e.what()));
878 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " <<
879 groupName <<
" (" << groupKey <<
")" << std::endl;
881 { cfgMgr->destroyConfigurationGroup(groupName,
true); }
884 catch(cet::exception& e)
890 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
891 xmlOut.addTextElementToData(
"Error",
"Error activating config group '" +
892 groupName +
"(" + groupKey +
")" +
"!'\n\n" +
893 std::string(e.what()));
894 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " <<
895 groupName <<
" (" << groupKey <<
")" << std::endl;
897 { cfgMgr->destroyConfigurationGroup(groupName,
true); }
902 __SUP_COUT__ <<
"Error detected!" << std::endl;
906 if(accumulatedTreeErrors !=
"")
907 xmlOut.addTextElementToData(
"Error",
"Warnings were found when activating group '" +
908 groupName +
"(" + groupKey +
")" +
"'! Please see details below:\n\n" +
909 accumulatedTreeErrors);
911 else if(requestType ==
"getActiveConfigGroups");
912 else if(requestType ==
"copyViewToCurrentColumns")
914 std::string configName = CgiDataUtilities::getData(cgiIn,
"configName");
915 std::string sourceVersion = CgiDataUtilities::getData(cgiIn,
"sourceVersion");
917 __SUP_COUT__ <<
"configName: " << configName << std::endl;
918 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << std::endl;
919 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << std::endl;
922 ConfigurationVersion newTemporaryVersion;
926 newTemporaryVersion = cfgMgr->copyViewToCurrentColumns(configName,
927 ConfigurationVersion(sourceVersion));
940 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << std::endl;
942 catch(std::runtime_error& e)
944 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
945 xmlOut.addTextElementToData(
"Error",
"Error copying view from '" +
946 configName +
"_v" + sourceVersion +
"'! " +
947 std::string(e.what()));
951 __SUP_COUT__ <<
"Error detected!\n\n " << std::endl;
952 xmlOut.addTextElementToData(
"Error",
"Error copying view from '" +
953 configName +
"_v" + sourceVersion +
"'! ");
956 handleGetConfigurationXML(xmlOut,cfgMgr,configName,newTemporaryVersion);
958 else if(requestType ==
"getLastConfigGroups")
960 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* gatewaySupervisor =
961 allSupervisorInfo_.isWizardMode()?
962 allSupervisorInfo_.getWizardDescriptor():
963 allSupervisorInfo_.getGatewayDescriptor();
965 std::string timeString;
966 std::pair<std::string , ConfigurationGroupKey> theGroup =
967 theRemoteWebUsers_.getLastConfigGroup(gatewaySupervisor,
968 "Configured",timeString);
969 xmlOut.addTextElementToData(
"LastConfiguredGroupName",theGroup.first);
970 xmlOut.addTextElementToData(
"LastConfiguredGroupKey",theGroup.second.toString());
971 xmlOut.addTextElementToData(
"LastConfiguredGroupTime",timeString);
972 theGroup = theRemoteWebUsers_.getLastConfigGroup(gatewaySupervisor,
973 "Started",timeString);
974 xmlOut.addTextElementToData(
"LastStartedGroupName",theGroup.first);
975 xmlOut.addTextElementToData(
"LastStartedGroupKey",theGroup.second.toString());
976 xmlOut.addTextElementToData(
"LastStartedGroupTime",timeString);
978 else if(requestType ==
"savePlanCommandSequence")
980 std::string planName = CgiDataUtilities::getData(cgiIn,
"planName");
981 std::string commands = CgiDataUtilities::postData(cgiIn,
"commands");
982 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
983 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
984 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
986 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << std::endl;
987 __SUP_COUT__ <<
"planName: " << planName << std::endl;
988 __SUP_COUT__ <<
"commands: " << commands << std::endl;
989 __SUP_COUT__ <<
"groupName: " << groupName << std::endl;
990 __SUP_COUT__ <<
"groupKey: " << groupKey << std::endl;
992 handleSavePlanCommandSequenceXML(xmlOut,cfgMgr,groupName,ConfigurationGroupKey(groupKey),
993 modifiedTables,userInfo.username_,planName,commands);
995 else if(requestType ==
"mergeGroups")
997 std::string groupANameContext = CgiDataUtilities::getData(cgiIn,
"groupANameContext");
998 std::string groupAKeyContext = CgiDataUtilities::getData(cgiIn,
"groupAKeyContext");
999 std::string groupBNameContext = CgiDataUtilities::getData(cgiIn,
"groupBNameContext");
1000 std::string groupBKeyContext = CgiDataUtilities::getData(cgiIn,
"groupBKeyContext");
1001 std::string groupANameConfig = CgiDataUtilities::getData(cgiIn,
"groupANameConfig");
1002 std::string groupAKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupAKeyConfig");
1003 std::string groupBNameConfig = CgiDataUtilities::getData(cgiIn,
"groupBNameConfig");
1004 std::string groupBKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupBKeyConfig");
1005 std::string mergeApproach = CgiDataUtilities::getData(cgiIn,
"mergeApproach");
1007 __SUP_COUTV__(groupANameContext);
1008 __SUP_COUTV__(groupAKeyContext);
1009 __SUP_COUTV__(groupBNameContext);
1010 __SUP_COUTV__(groupBKeyContext);
1011 __SUP_COUTV__(groupANameConfig);
1012 __SUP_COUTV__(groupAKeyConfig);
1013 __SUP_COUTV__(groupBNameConfig);
1014 __SUP_COUTV__(groupBKeyConfig);
1015 __SUP_COUTV__(mergeApproach);
1017 handleMergeGroupsXML(xmlOut,cfgMgr,
1018 groupANameContext,ConfigurationGroupKey(groupAKeyContext),
1019 groupBNameContext,ConfigurationGroupKey(groupBKeyContext),
1020 groupANameConfig,ConfigurationGroupKey(groupAKeyConfig),
1021 groupBNameConfig,ConfigurationGroupKey(groupBKeyConfig),
1022 userInfo.username_,mergeApproach);
1026 __SUP_SS__ <<
"requestType '" << requestType <<
"' request not recognized." << std::endl;
1027 __SUP_COUT__ <<
"\n" << ss.str();
1028 xmlOut.addTextElementToData(
"Error", ss.str());
1034 std::map<std::string ,
1037 ConfigurationGroupKey> > activeGroupMap =
1038 cfgMgr->getActiveConfigurationGroups();
1040 for(
auto& type:activeGroupMap)
1042 xmlOut.addTextElementToData(type.first +
"-ActiveGroupName",
1044 xmlOut.addTextElementToData(type.first +
"-ActiveGroupKey",
1045 type.second.second.toString());
1050 xmlOut.addTextElementToData(
"versionTracking",
1051 ConfigurationInterface::isVersionTrackingEnabled()?
"ON":
"OFF");
1058 catch(
const std::runtime_error& e)
1060 __SS__ <<
"A fatal error occurred while handling the request '" <<
1061 requestType <<
".' Error: " <<
1063 __COUT_ERR__ <<
"\n" << ss.str();
1064 xmlOut.addTextElementToData(
"Error", ss.str());
1069 xmlOut.addTextElementToData(
"versionTracking",
1070 ConfigurationInterface::isVersionTrackingEnabled()?
"ON":
"OFF");
1074 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1079 __SS__ <<
"A fatal error occurred while handling the request '" <<
1080 requestType <<
".'" << __E__;
1081 __COUT_ERR__ <<
"\n" << ss.str();
1082 xmlOut.addTextElementToData(
"Error", ss.str());
1087 xmlOut.addTextElementToData(
"versionTracking",
1088 ConfigurationInterface::isVersionTrackingEnabled()?
"ON":
"OFF");
1092 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1105 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(HttpXmlDocument& xmlOut,
1106 ConfigurationManagerRW* cfgMgr,
1107 const std::string& rootGroupName,
const ConfigurationGroupKey& rootGroupKey,
1108 const std::string& modifiedTables)
1121 std::map<std::string, std::pair<std::string, ConfigurationGroupKey>> consideredGroups =
1122 cfgMgr->getActiveConfigurationGroups();
1126 if(consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT].second.isInvalid())
1128 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1129 if(cfgMgr->getFailedConfigurationGroups().find(
1130 ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT) !=
1131 cfgMgr->getFailedConfigurationGroups().end())
1133 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1134 cfgMgr->getFailedConfigurationGroups().at(ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT);
1136 else if(cfgMgr->getFailedConfigurationGroups().find(
1137 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN) !=
1138 cfgMgr->getFailedConfigurationGroups().end())
1140 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1141 cfgMgr->getFailedConfigurationGroups().at(ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN);
1144 if(consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION].second.isInvalid())
1146 __SUP_COUT__ <<
"Finding a configuration group to consider..." << __E__;
1147 if(cfgMgr->getFailedConfigurationGroups().find(
1148 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION) !=
1149 cfgMgr->getFailedConfigurationGroups().end())
1151 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1152 cfgMgr->getFailedConfigurationGroups().at(ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION);
1154 else if(cfgMgr->getFailedConfigurationGroups().find(
1155 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN) !=
1156 cfgMgr->getFailedConfigurationGroups().end())
1158 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1159 cfgMgr->getFailedConfigurationGroups().at(ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN);
1163 __SUP_COUTV__(StringMacros::mapToString(consideredGroups));
1169 std::map<std::string , ConfigurationVersion > rootGroupMemberMap;
1171 cfgMgr->loadConfigurationGroup(rootGroupName,rootGroupKey,
1172 0,&rootGroupMemberMap,0,0,0,0,0,
1175 const std::string& groupType = cfgMgr->getTypeNameOfGroup(rootGroupMemberMap);
1177 consideredGroups[groupType] = std::pair<std::string, ConfigurationGroupKey>(
1178 rootGroupName,rootGroupKey);
1180 catch(
const std::runtime_error& e)
1183 if(rootGroupName.size())
1185 __SUP_SS__ <<
"Failed to determine type of configuration group for " << rootGroupName <<
"(" <<
1186 rootGroupKey <<
")! " << e.what() << std::endl;
1187 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1192 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group name - assuming this was intentional." << std::endl;
1197 if(rootGroupName.size())
1199 __SUP_COUT_ERR__ <<
"Failed to determine type of configuration group for " << rootGroupName <<
"(" <<
1200 rootGroupKey <<
")!" << std::endl;
1205 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group name - assuming this was intentional." << std::endl;
1209 std::map<std::string , ConfigurationVersion > modifiedTablesMap;
1210 std::map<std::string , ConfigurationVersion >::iterator modifiedTablesMapIt;
1212 std::istringstream f(modifiedTables);
1213 std::string table,version;
1214 while (getline(f, table,
','))
1216 getline(f, version,
',');
1217 modifiedTablesMap.insert(
1218 std::pair<std::string ,
1219 ConfigurationVersion >(
1220 table, ConfigurationVersion(version)));
1222 __SUP_COUT__ << modifiedTables << std::endl;
1223 for(
auto& pair:modifiedTablesMap)
1224 __SUP_COUT__ <<
"modified table " <<
1225 pair.first <<
":" <<
1226 pair.second << std::endl;
1230 DOMElement* parentEl;
1231 std::string groupComment;
1232 for(
auto group : consideredGroups)
1234 if(group.second.second.isInvalid())
continue;
1236 __SUP_COUT__ <<
"Considering " << group.first <<
" group " <<
1237 group.second.first <<
" (" << group.second.second <<
")" << std::endl;
1241 std::map<std::string , ConfigurationVersion > memberMap;
1242 cfgMgr->loadConfigurationGroup(group.second.first,group.second.second,
1243 0,&memberMap,0,0,&groupComment,0,0,
1246 __SUP_COUT__ <<
"groupComment = " << groupComment << std::endl;
1248 for(
auto& table: memberMap)
1250 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1251 modifiedTablesMap.end() &&
1252 table.second != (*modifiedTablesMapIt).second)
1254 __SUP_COUT__ <<
"Affected by " <<
1255 (*modifiedTablesMapIt).first <<
":" <<
1256 (*modifiedTablesMapIt).second << std::endl;
1258 memberMap[table.first] = (*modifiedTablesMapIt).second;
1265 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1266 xmlOut.addTextElementToParent(
"GroupName", group.second.first, parentEl);
1267 xmlOut.addTextElementToParent(
"GroupKey",
1268 group.second.second.toString(), parentEl);
1269 xmlOut.addTextElementToParent(
"GroupComment", groupComment, parentEl);
1272 for(
auto& table: memberMap)
1274 xmlOut.addTextElementToParent(
"MemberName",
1275 table.first, parentEl);
1276 xmlOut.addTextElementToParent(
"MemberVersion",
1277 table.second.toString(), parentEl);
1282 catch(std::runtime_error& e)
1284 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
1285 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! " + std::string(e.what()));
1289 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
1290 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1302 void ConfigurationGUISupervisor::setupActiveTablesXML(
1303 HttpXmlDocument& xmlOut,
1304 ConfigurationManagerRW* cfgMgr,
1305 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
1306 const std::string& modifiedTables,
1307 bool refreshAll,
bool doGetGroupInfo,
1308 std::map<std::string /*name*/, ConfigurationVersion /*version*/>* returnMemberMap,
1309 bool outputActiveTables,
1310 std::string* accumulatedErrors)
1313 if(accumulatedErrors)* accumulatedErrors =
"";
1315 xmlOut.addTextElementToData(
"configGroup", groupName);
1316 xmlOut.addTextElementToData(
"configGroupKey", groupKey.toString());
1318 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
1321 if(usingActiveGroups || refreshAll)
1322 cfgMgr->getAllConfigurationInfo(
true,accumulatedErrors);
1324 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo(
false);
1326 std::map<std::string , ConfigurationVersion > modifiedTablesMap;
1327 std::map<std::string , ConfigurationVersion >::iterator modifiedTablesMapIt;
1329 if(usingActiveGroups)
1332 __SUP_COUT__ <<
"Using active groups." << std::endl;
1336 __SUP_COUT__ <<
"Loading group '" << groupName <<
1337 "(" << groupKey <<
")'" << std::endl;
1339 std::string groupComment, groupAuthor, configGroupCreationTime;
1342 cfgMgr->loadConfigurationGroup(groupName,groupKey,
1346 doGetGroupInfo?&groupComment:0,
1347 doGetGroupInfo?&groupAuthor:0,
1348 doGetGroupInfo?&configGroupCreationTime:0);
1352 xmlOut.addTextElementToData(
"configGroupComment", groupComment);
1353 xmlOut.addTextElementToData(
"configGroupAuthor", groupAuthor);
1354 xmlOut.addTextElementToData(
"configGroupCreationTime", configGroupCreationTime);
1360 std::istringstream f(modifiedTables);
1361 std::string table,version;
1362 while (getline(f, table,
','))
1364 getline(f, version,
',');
1365 modifiedTablesMap.insert(
1366 std::pair<std::string ,
1367 ConfigurationVersion >(
1368 table, ConfigurationVersion(version)));
1371 for(
auto& pair:modifiedTablesMap)
1372 __SUP_COUT__ <<
"modified table " <<
1373 pair.first <<
":" <<
1374 pair.second << std::endl;
1378 std::map<std::string, ConfigurationVersion> allActivePairs = cfgMgr->getActiveVersions();
1379 xmlOut.addTextElementToData(
"DefaultNoLink", ViewColumnInfo::DATATYPE_LINK_DEFAULT);
1380 for(
auto& activePair: allActivePairs)
1382 if(outputActiveTables)
1383 xmlOut.addTextElementToData(
"ActiveTableName", activePair.first);
1387 if((modifiedTablesMapIt = modifiedTablesMap.find(activePair.first)) !=
1388 modifiedTablesMap.end())
1390 __SUP_COUT__ <<
"Found modified table " <<
1391 (*modifiedTablesMapIt).first <<
": trying... " <<
1392 (*modifiedTablesMapIt).second << std::endl;
1396 allCfgInfo.at(activePair.first).configurationPtr_->setActiveView(
1397 (*modifiedTablesMapIt).second);
1401 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second <<
1402 " failed. Reverting to v" <<
1403 allCfgInfo.at(activePair.first).configurationPtr_->getView().getVersion() <<
1406 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << std::endl;
1407 xmlOut.addTextElementToData(
"Warning",
"Error setting up active tables!\n\n" +
1408 std::string(ss.str()));
1412 if(outputActiveTables)
1414 xmlOut.addTextElementToData(
"ActiveTableVersion",
1415 allCfgInfo.at(activePair.first).configurationPtr_->getView().getVersion().toString());
1416 xmlOut.addTextElementToData(
"ActiveTableComment",
1417 allCfgInfo.at(activePair.first).configurationPtr_->getView().getComment());
1426 catch(std::runtime_error& e)
1428 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what())) << std::endl;
1429 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1430 xmlOut.addTextElementToData(
"Error", ss.str());
1434 __SUP_SS__ << (
"Error setting up active tables!\n\n") << std::endl;
1435 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1436 xmlOut.addTextElementToData(
"Error", ss.str());
1455 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(HttpXmlDocument& xmlOut,
1456 ConfigurationManagerRW* cfgMgr,
1457 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
1458 const std::string& startPath,
1459 const std::string& modifiedTables,
const std::string& recordList,
1460 const std::string& author)
1463 setupActiveTablesXML(
1466 groupName, groupKey,
1474 ConfigurationTree targetNode =
1475 cfgMgr->getNode(startPath);
1476 ConfigurationBase* config = cfgMgr->getConfigurationByName(
1477 targetNode.getConfigurationName());
1479 __SUP_COUT__ << config->getConfigurationName() << std::endl;
1480 ConfigurationVersion temporaryVersion;
1489 bool firstSave =
true;
1493 ConfigurationView backupView;
1498 std::istringstream f(recordList);
1499 std::string recordUID;
1502 while (getline(f, recordUID,
','))
1504 recordUID = StringMacros::decodeURIComponent(recordUID);
1506 __SUP_COUT__ <<
"recordUID " <<
1507 recordUID << std::endl;
1511 if(!(temporaryVersion =
1512 targetNode.getConfigurationVersion()).isTemporaryVersion())
1514 __SUP_COUT__ <<
"Start version " << temporaryVersion << std::endl;
1516 temporaryVersion = config->createTemporaryView(temporaryVersion);
1517 cfgMgr->saveNewConfiguration(
1518 targetNode.getConfigurationName(),
1519 temporaryVersion,
true);
1521 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << std::endl;
1524 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << std::endl;
1529 backupView.copy(config->getView(),temporaryVersion,author);
1537 unsigned int row = config->getViewP()->addRow(author,
1543 unsigned int col = config->getViewP()->getColStatus();
1544 config->getViewP()->setURIEncodedValue(
"1",row,col);
1549 config->getViewP()->setURIEncodedValue(recordUID,row,
1550 config->getViewP()->getColUID());
1559 config->getViewP()->init();
1563 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
1564 __SUP_COUT__ <<
"Before:" << __E__;
1565 config->getViewP()->print();
1566 config->getViewP()->copy(backupView,temporaryVersion,author);
1567 __SUP_COUT__ <<
"After:" << __E__;
1568 config->getViewP()->print();
1574 handleFillModifiedTablesXML(xmlOut,cfgMgr);
1576 catch(std::runtime_error& e)
1578 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what())) << std::endl;
1579 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1580 xmlOut.addTextElementToData(
"Error", ss.str());
1584 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << std::endl;
1585 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1586 xmlOut.addTextElementToData(
"Error", ss.str());
1593 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(HttpXmlDocument& xmlOut,
1594 ConfigurationManagerRW* cfgMgr)
1598 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo();
1599 std::map<std::string, ConfigurationVersion> allActivePairs = cfgMgr->getActiveVersions();
1600 for(
auto& activePair: allActivePairs)
1602 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
1603 xmlOut.addTextElementToData(
"NewActiveTableVersion",
1604 allCfgInfo.at(activePair.first).configurationPtr_->getView().getVersion().toString());
1605 xmlOut.addTextElementToData(
"NewActiveTableComment",
1606 allCfgInfo.at(activePair.first).configurationPtr_->getView().getComment());
1609 catch(std::runtime_error& e)
1611 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << std::endl;
1612 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1613 xmlOut.addTextElementToData(
"Error", ss.str());
1617 __SUP_SS__ << (
"Error!\n\n") << std::endl;
1618 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1619 xmlOut.addTextElementToData(
"Error", ss.str());
1637 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(HttpXmlDocument& xmlOut,
1638 ConfigurationManagerRW* cfgMgr,
1639 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
1640 const std::string& startPath,
1641 const std::string& modifiedTables,
const std::string& recordList)
1644 setupActiveTablesXML(
1647 groupName, groupKey,
1655 ConfigurationTree targetNode =
1656 cfgMgr->getNode(startPath);
1657 ConfigurationBase* config = cfgMgr->getConfigurationByName(
1658 targetNode.getConfigurationName());
1660 __SUP_COUT__ << config->getConfigurationName() << std::endl;
1661 ConfigurationVersion temporaryVersion;
1670 bool firstSave =
true;
1676 std::istringstream f(recordList);
1677 std::string recordUID;
1680 while (getline(f, recordUID,
','))
1682 recordUID = StringMacros::decodeURIComponent(recordUID);
1684 __SUP_COUT__ <<
"recordUID " <<
1685 recordUID << std::endl;
1689 if(!(temporaryVersion =
1690 targetNode.getConfigurationVersion()).isTemporaryVersion())
1692 __SUP_COUT__ <<
"Start version " << temporaryVersion << std::endl;
1694 temporaryVersion = config->createTemporaryView(temporaryVersion);
1695 cfgMgr->saveNewConfiguration(
1696 targetNode.getConfigurationName(),
1697 temporaryVersion,
true);
1699 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << std::endl;
1702 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << std::endl;
1710 unsigned int row = config->getViewP()->findRow(
1711 config->getViewP()->getColUID(),
1714 config->getViewP()->deleteRow(row);
1719 config->getViewP()->init();
1721 handleFillModifiedTablesXML(xmlOut,cfgMgr);
1723 catch(std::runtime_error& e)
1725 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << std::endl;
1726 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1727 xmlOut.addTextElementToData(
"Error", ss.str());
1731 __SUP_SS__ << (
"Error removing record(s)!\n\n") << std::endl;
1732 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1733 xmlOut.addTextElementToData(
"Error", ss.str());
1755 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(HttpXmlDocument& xmlOut,
1756 ConfigurationManagerRW* cfgMgr,
1757 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
1758 const std::string& startPath,
1759 const std::string& modifiedTables,
const std::string& recordList,
1760 const std::string& fieldList,
const std::string& valueList,
1761 const std::string& author)
1764 setupActiveTablesXML(
1767 groupName, groupKey,
1777 std::vector<std::string > fieldPaths;
1780 std::istringstream f(fieldList);
1781 std::string fieldPath;
1782 while (getline(f, fieldPath,
','))
1784 fieldPaths.push_back(
1785 StringMacros::decodeURIComponent(fieldPath));
1787 __SUP_COUT__ << fieldList << std::endl;
1788 for(
const auto& field:fieldPaths)
1789 __SUP_COUT__ <<
"fieldPath " <<
1793 std::vector<std::string > fieldValues;
1796 std::istringstream f(valueList);
1797 std::string fieldValue;
1798 while (getline(f, fieldValue,
','))
1800 fieldValues.push_back(fieldValue);
1805 if(valueList.size() &&
1806 valueList[valueList.size()-1] ==
',')
1807 fieldValues.push_back(
"");
1809 __SUP_COUT__ << valueList << std::endl;
1810 for(
const auto& value:fieldValues)
1811 __SUP_COUT__ <<
"fieldValue " <<
1815 if(fieldPaths.size() != fieldValues.size())
1816 {__SUP_SS__; __THROW__(ss.str()+
"Mismatch in fields and values array size!");}
1820 ConfigurationBase* config;
1821 ConfigurationVersion temporaryVersion;
1822 std::istringstream f(recordList);
1823 std::string recordUID;
1826 while (getline(f, recordUID,
','))
1828 recordUID = StringMacros::decodeURIComponent(recordUID);
1832 DOMElement* parentEl = xmlOut.addTextElementToData(
"fieldValues", recordUID);
1835 for(i=0;i<fieldPaths.size();++i)
1837 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << std::endl;
1838 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << std::endl;
1841 ConfigurationTree targetNode =
1842 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
1876 __SUP_COUT__ <<
"Getting table " <<
1877 targetNode.getFieldConfigurationName() << std::endl;
1880 config = cfgMgr->getConfigurationByName(
1881 targetNode.getFieldConfigurationName());
1882 if(!(temporaryVersion =
1883 config->getViewP()->getVersion()).isTemporaryVersion())
1886 temporaryVersion = config->createTemporaryView(
1887 config->getViewP()->getVersion());
1888 cfgMgr->saveNewConfiguration(
1889 config->getConfigurationName(),
1890 temporaryVersion,
true);
1892 __SUP_COUT__ <<
"Created temporary version " <<
1893 config->getConfigurationName() <<
"-v" << temporaryVersion << std::endl;
1896 __SUP_COUT__ <<
"Using temporary version " <<
1897 config->getConfigurationName() <<
"-v" << temporaryVersion << std::endl;
1900 config->getViewP()->setURIEncodedValue(
1902 targetNode.getFieldRow(),
1903 targetNode.getFieldColumn(),
1906 config->getViewP()->init();
1911 handleFillModifiedTablesXML(xmlOut,cfgMgr);
1914 catch(std::runtime_error& e)
1916 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what())) << std::endl;
1917 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1918 xmlOut.addTextElementToData(
"Error", ss.str());
1922 __SUP_SS__ << (
"Error setting field values!\n\n") << std::endl;
1923 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1924 xmlOut.addTextElementToData(
"Error", ss.str());
1943 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr,
1944 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
1945 const std::string& startPath,
1946 const std::string& modifiedTables,
const std::string& recordList,
1947 const std::string& fieldList)
1950 setupActiveTablesXML(
1953 groupName, groupKey,
1961 std::vector<std::string > fieldPaths;
1964 std::istringstream f(fieldList);
1965 std::string fieldPath;
1966 while (getline(f, fieldPath,
','))
1968 fieldPaths.push_back(
1969 StringMacros::decodeURIComponent(fieldPath));
1971 __SUP_COUT__ << fieldList << std::endl;
1972 for(
auto& field:fieldPaths)
1973 __SUP_COUT__ <<
"fieldPath " <<
1979 std::istringstream f(recordList);
1980 std::string recordUID;
1981 while (getline(f, recordUID,
','))
1983 recordUID = StringMacros::decodeURIComponent(recordUID);
1985 __SUP_COUT__ <<
"recordUID " <<
1986 recordUID << std::endl;
1988 DOMElement* parentEl = xmlOut.addTextElementToData(
"fieldValues", recordUID);
1991 for(
const auto& fieldPath:fieldPaths)
1993 __SUP_COUT__ <<
"fieldPath " << fieldPath << std::endl;
1995 xmlOut.addTextElementToParent(
"FieldPath",
1998 xmlOut.addTextElementToParent(
"FieldValue",
1999 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPath).getValueAsString(),
2005 catch(std::runtime_error& e)
2007 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what())) << std::endl;
2008 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2009 xmlOut.addTextElementToData(
"Error", ss.str());
2013 __SUP_SS__ << (
"Error getting field values!\n\n") << std::endl;
2014 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2015 xmlOut.addTextElementToData(
"Error", ss.str());
2037 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(HttpXmlDocument& xmlOut,
2038 ConfigurationManagerRW* cfgMgr,
2039 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
2040 const std::string& startPath,
unsigned int depth,
2041 const std::string& modifiedTables,
const std::string& recordList,
2042 const std::string& fieldList)
2045 setupActiveTablesXML(
2048 groupName, groupKey,
2054 DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
2058 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
2059 __SUP_COUT__ << ss.str();
2068 std::vector<ConfigurationTree::RecordField> retFieldList;
2072 ConfigurationTree startNode = cfgMgr->getNode(startPath);
2073 if(startNode.isLinkNode() && startNode.isDisconnected())
2075 __SUP_SS__ <<
"Start path was a disconnected link node!" << std::endl;
2076 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2082 std::vector<std::string > fieldAcceptList, fieldRejectList;
2087 std::istringstream f(fieldList);
2088 std::string fieldPath, decodedFieldPath;
2089 while (getline(f, fieldPath,
','))
2091 decodedFieldPath = StringMacros::decodeURIComponent(fieldPath);
2093 if(decodedFieldPath[0] ==
'!')
2094 fieldRejectList.push_back(decodedFieldPath.substr(1));
2096 fieldAcceptList.push_back(decodedFieldPath);
2098 __SUP_COUT__ << fieldList << std::endl;
2099 for(
auto& field:fieldAcceptList)
2100 __SUP_COUT__ <<
"fieldAcceptList " <<
2102 for(
auto& field:fieldRejectList)
2103 __SUP_COUT__ <<
"fieldRejectList " <<
2108 std::vector<std::string > records;
2109 if(recordList ==
"*")
2112 records = startNode.getChildrenNames();
2113 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
2114 for(
auto& record:records)
2115 __SUP_COUT__ <<
"recordList " <<
2116 record << std::endl;
2118 else if(recordList !=
"")
2122 std::istringstream f(recordList);
2123 std::string recordStr;
2124 while (getline(f, recordStr,
','))
2127 StringMacros::decodeURIComponent(recordStr));
2129 __SUP_COUT__ << recordList << std::endl;
2130 for(
auto& record:records)
2131 __SUP_COUT__ <<
"recordList " <<
2132 record << std::endl;
2136 retFieldList = startNode.getCommonFields(
2137 records,fieldAcceptList,fieldRejectList,depth);
2140 DOMElement* parentTypeEl;
2141 for(
const auto& fieldInfo:retFieldList)
2143 xmlOut.addTextElementToParent(
"FieldTableName",
2144 fieldInfo.tableName_,
2146 xmlOut.addTextElementToParent(
"FieldColumnName",
2147 fieldInfo.columnName_,
2149 xmlOut.addTextElementToParent(
"FieldRelativePath",
2150 fieldInfo.relativePath_,
2152 xmlOut.addTextElementToParent(
"FieldColumnType",
2153 fieldInfo.columnInfo_->getType(),
2155 xmlOut.addTextElementToParent(
"FieldColumnDataType",
2156 fieldInfo.columnInfo_->getDataType(),
2158 xmlOut.addTextElementToParent(
"FieldColumnDefaultValue",
2159 fieldInfo.columnInfo_->getDefaultValue(),
2162 parentTypeEl = xmlOut.addTextElementToParent(
"FieldColumnDataChoices",
2166 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
2167 xmlOut.addTextElementToParent(
"FieldColumnDataChoice",
2168 fieldInfo.columnInfo_->getDefaultValue(),
2170 for(
const auto& dataChoice : dataChoices)
2171 xmlOut.addTextElementToParent(
"FieldColumnDataChoice",
2176 catch(std::runtime_error& e)
2178 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what())) << std::endl;
2179 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2180 xmlOut.addTextElementToData(
"Error", ss.str());
2184 __SUP_SS__ << (
"Error getting common fields!\n\n") << std::endl;
2185 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2186 xmlOut.addTextElementToData(
"Error", ss.str());
2216 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(HttpXmlDocument& xmlOut,
2217 ConfigurationManagerRW* cfgMgr,
2218 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
2219 const std::string& startPath,
2220 const std::string& modifiedTables,
const std::string& recordList,
2221 const std::string& fieldList)
2224 setupActiveTablesXML(
2227 groupName, groupKey,
2235 if(startPath ==
"/")
2238 std::vector<std::string > fieldsToGet;
2243 std::istringstream f(fieldList);
2244 std::string fieldPath;
2245 while (getline(f, fieldPath,
','))
2247 fieldsToGet.push_back(
2248 StringMacros::decodeURIComponent(fieldPath));
2250 __SUP_COUT__ << fieldList << std::endl;
2251 for(
auto& field:fieldsToGet)
2252 __SUP_COUT__ <<
"fieldsToGet " <<
2259 ConfigurationTree startNode = cfgMgr->getNode(startPath);
2260 if(startNode.isLinkNode() && startNode.isDisconnected())
2262 __SUP_SS__ <<
"Start path was a disconnected link node!" << std::endl;
2263 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2267 std::vector<std::string > records;
2268 if(recordList ==
"*")
2271 records = startNode.getChildrenNames();
2272 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
2273 for(
auto& record:records)
2274 __SUP_COUT__ <<
"recordList " <<
2275 record << std::endl;
2277 else if(recordList !=
"")
2281 std::istringstream f(recordList);
2282 std::string recordStr;
2283 while (getline(f, recordStr,
','))
2286 StringMacros::decodeURIComponent(recordStr));
2288 __SUP_COUT__ << recordList << std::endl;
2289 for(
auto& record:records)
2290 __SUP_COUT__ <<
"recordList " <<
2291 record << std::endl;
2298 for(
auto& field:fieldsToGet)
2300 __SUP_COUT__ <<
"fieldsToGet " <<
2303 DOMElement* parentEl = xmlOut.addTextElementToData(
"field", field);
2307 std::set<std::string > uniqueValues;
2309 uniqueValues = cfgMgr->getNode(startPath).getUniqueValuesForField(
2312 for(
auto& uniqueValue:uniqueValues)
2314 __SUP_COUT__ <<
"uniqueValue " <<
2315 uniqueValue << std::endl;
2317 xmlOut.addTextElementToParent(
"uniqueValue",
2323 catch(std::runtime_error& e)
2325 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what())) << std::endl;
2326 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2327 xmlOut.addTextElementToData(
"Error", ss.str());
2331 __SUP_SS__ << (
"Error getting common fields!\n\n") << std::endl;
2332 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2333 xmlOut.addTextElementToData(
"Error", ss.str());
2357 void ConfigurationGUISupervisor::handleFillTreeViewXML(HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr,
2358 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
2359 const std::string& startPath,
unsigned int depth,
bool hideStatusFalse,
2360 const std::string& modifiedTables,
const std::string& filterList)
2394 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
2395 std::map<std::string , ConfigurationVersion > memberMap;
2397 std::string accumulatedErrors;
2398 setupActiveTablesXML(
2401 groupName, groupKey,
2409 if(accumulatedErrors !=
"")
2410 xmlOut.addTextElementToData(
"Warning",
2413 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors <<
"'" << std::endl;
2417 DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
2419 if(depth == 0)
return;
2421 std::vector<std::pair<std::string,ConfigurationTree> > rootMap;
2423 if(startPath ==
"/")
2427 std::string accumulateTreeErrs;
2429 if(usingActiveGroups)
2430 rootMap = cfgMgr->getChildren(0,&accumulateTreeErrs);
2432 rootMap = cfgMgr->getChildren(&memberMap,&accumulateTreeErrs);
2434 __SUP_COUT__ <<
"accumulateTreeErrs = " << accumulateTreeErrs << std::endl;
2435 if(accumulateTreeErrs !=
"")
2436 xmlOut.addTextElementToData(
"TreeErrors",
2437 accumulateTreeErrs);
2441 ConfigurationTree startNode = cfgMgr->getNode(startPath,
2443 if(startNode.isLinkNode() && startNode.isDisconnected())
2445 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
2450 std::map<std::string , std::string > filterMap;
2451 StringMacros::getMapFromString(filterList,filterMap,
2452 std::set<char>({
';'}),
2453 std::set<char>({
'='}));
2455 __COUTV__(StringMacros::mapToString(filterMap));
2457 rootMap = cfgMgr->getNode(startPath).getChildren(filterMap);
2460 for(
auto& treePair:rootMap)
2461 recursiveTreeToXML(treePair.second,depth-1,xmlOut,parentEl,hideStatusFalse);
2463 catch(std::runtime_error& e)
2465 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << std::endl;
2466 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2467 xmlOut.addTextElementToData(
"Error", ss.str());
2471 __SUP_SS__ <<
"Error detected generating XML tree!" << std::endl;
2472 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2473 xmlOut.addTextElementToData(
"Error", ss.str());
2483 void ConfigurationGUISupervisor::recursiveTreeToXML(
const ConfigurationTree& t,
unsigned int depth, HttpXmlDocument& xmlOut,
2484 DOMElement* parentEl,
bool hideStatusFalse)
2490 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
2491 xmlOut.addTextElementToParent(
"value", t.getValueAsString(), parentEl);
2492 parentEl = xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
2496 if(t.getValueType() == ViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
2497 t.getValueType() == ViewColumnInfo::TYPE_BITMAP_DATA)
2501 std::vector<std::string> choices = t.getFixedChoices();
2502 for(
const auto& choice:choices)
2503 xmlOut.addTextElementToParent(
"fixedChoice", choice, parentEl);
2513 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
2515 if(t.isDisconnected())
2517 __COUT__ << t.getValueName() << std::endl;
2522 xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
2525 xmlOut.addTextElementToParent(
2526 (t.isGroupLinkNode()?
"Group":
"U") + std::string(
"ID"),
2527 t.getDisconnectedLinkID(),
2529 xmlOut.addTextElementToParent(
"LinkConfigurationName",
2530 t.getDisconnectedTableName(),
2532 xmlOut.addTextElementToParent(
"LinkIndex",
2533 t.getChildLinkIndex(),
2538 DOMElement* choicesParentEl = xmlOut.addTextElementToParent(
"fixedChoices",
"",
2543 std::vector<std::string> choices = t.getFixedChoices();
2544 __COUT__ <<
"choices.size() " << choices.size() << std::endl;
2546 for(
const auto& choice:choices)
2547 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
2559 xmlOut.addTextElementToParent(
2560 (t.isGroupLinkNode()?
"Group":
"U") + std::string(
"ID"),
2561 t.getValueAsString(), parentEl);
2563 xmlOut.addTextElementToParent(
"LinkConfigurationName", t.getConfigurationName(),
2566 xmlOut.addTextElementToParent(
"LinkIndex", t.getChildLinkIndex(),
2571 DOMElement* choicesParentEl = xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
2572 std::vector<std::string> choices = t.getFixedChoices();
2576 for(
const auto& choice:choices)
2577 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
2582 bool returnNode =
true;
2588 t.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue(returnNode);
2593 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueAsString(), parentEl);
2602 auto C = t.getChildren();
2604 recursiveTreeToXML(c.second,depth-1,xmlOut,parentEl,hideStatusFalse);
2618 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(HttpXmlDocument& xmlOut,
2619 ConfigurationManagerRW* cfgMgr,
const std::string& linkToTableName,
2620 const ConfigurationVersion& linkToTableVersion,
2621 const std::string& linkIdType,
const std::string& linkIndex,
2622 const std::string& linkInitId)
2636 const std::string& configName = linkToTableName;
2637 const ConfigurationVersion& version = linkToTableVersion;
2638 ConfigurationBase* config = cfgMgr->getConfigurationByName(configName);
2641 config->setActiveView(version);
2645 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: " <<
2646 version << std::endl;
2647 cfgMgr->getVersionedConfigurationByName(
2648 configName, version);
2651 if(version != config->getViewVersion())
2653 __SUP_SS__ <<
"Target table version (" << version <<
2654 ") is not the currently active version (" << config->getViewVersion()
2655 <<
". Try refreshing the tree." << std::endl;
2656 __SUP_COUT_WARN__ << ss.str();
2660 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << std::endl;
2662 if(linkIdType ==
"UID")
2665 unsigned int col = config->getView().getColUID();
2666 for(
unsigned int row = 0; row < config->getView().getNumberOfRows(); ++row)
2667 xmlOut.addTextElementToData(
"linkToChoice",
2668 config->getView().getDataView()[row][col]);
2670 else if(linkIdType ==
"GroupID")
2676 std::set<std::string> setOfGroupIDs =
2677 config->getView().getSetOfGroupIDs(linkIndex);
2682 bool foundInitId =
false;
2683 for(
const auto& groupID : setOfGroupIDs)
2686 linkInitId == groupID)
2689 xmlOut.addTextElementToData(
"linkToChoice",
2694 xmlOut.addTextElementToData(
"linkToChoice",
2698 unsigned int col = config->getView().getColUID();
2699 for(
unsigned int row = 0; row < config->getView().getNumberOfRows(); ++row)
2701 xmlOut.addTextElementToData(
"groupChoice",
2702 config->getView().getDataView()[row][col]);
2703 if(config->getView().isEntryInGroup(row,linkIndex,linkInitId))
2704 xmlOut.addTextElementToData(
"groupMember",
2705 config->getView().getDataView()[row][col]);
2710 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType
2711 <<
".'" << std::endl;
2717 catch(std::runtime_error& e)
2719 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << std::endl;
2720 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
2721 xmlOut.addTextElementToData(
"Error", ss.str());
2725 __SUP_SS__ <<
"Error detected saving tree node!\n\n "<< std::endl;
2726 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
2727 xmlOut.addTextElementToData(
"Error", ss.str());
2733 void ConfigurationGUISupervisor::handleMergeGroupsXML(HttpXmlDocument& xmlOut,
2734 ConfigurationManagerRW* cfgMgr,
2735 const std::string& groupANameContext,
const ConfigurationGroupKey& groupAKeyContext,
2736 const std::string& groupBNameContext,
const ConfigurationGroupKey& groupBKeyContext,
2737 const std::string& groupANameConfig,
const ConfigurationGroupKey& groupAKeyConfig,
2738 const std::string& groupBNameConfig,
const ConfigurationGroupKey& groupBKeyConfig,
2739 const std::string& author,
const std::string& mergeApproach)
2742 __SUP_COUT__ <<
"Merging context group pair " <<
2743 groupANameContext <<
" (" << groupAKeyContext <<
") & " <<
2744 groupBNameContext <<
" (" << groupBKeyContext <<
") and config group pair " <<
2745 groupANameConfig <<
" (" << groupAKeyConfig <<
") & " <<
2746 groupBNameConfig <<
" (" << groupBKeyConfig <<
") with approach '" <<
2747 mergeApproach << __E__;
2761 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" || mergeApproach ==
"Skip"))
2763 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
2767 std::map<std::string , ConfigurationVersion > memberMapAContext, memberMapBContext,
2768 memberMapAConfig, memberMapBConfig;
2772 bool skippingContextPair =
false;
2773 bool skippingConfigPair =
false;
2774 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
2775 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
2777 skippingContextPair =
true;
2778 __SUP_COUTV__(skippingContextPair);
2780 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
2781 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
2783 skippingConfigPair =
true;
2784 __SUP_COUTV__(skippingConfigPair);
2788 if(!skippingContextPair)
2790 cfgMgr->loadConfigurationGroup(groupANameContext,groupAKeyContext,
2791 false ,&memberMapAContext,0 ,0 ,
2795 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
2797 cfgMgr->loadConfigurationGroup(groupBNameContext,groupBKeyContext,
2798 false ,&memberMapBContext,0 ,0 ,
2803 __SUP_COUTV__(StringMacros::mapToString(memberMapBContext));
2807 if(!skippingConfigPair)
2809 cfgMgr->loadConfigurationGroup(groupANameConfig,groupAKeyConfig,
2810 false ,&memberMapAConfig,0 ,0 ,
2814 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
2816 cfgMgr->loadConfigurationGroup(groupBNameConfig,groupBKeyConfig,
2817 false ,&memberMapBConfig,0 ,0 ,
2822 __SUP_COUTV__(StringMacros::mapToString(memberMapBConfig));
2829 std::map< std::pair<std::string ,std::string >,
2830 std::string > uidConversionMap;
2831 std::map< std::pair<std::string ,std::pair<std::string ,std::string >>,
2832 std::string > groupidConversionMap;
2835 for(
unsigned int i=0;i<2;++i)
2837 if(i==0 && mergeApproach !=
"Rename")
continue;
2840 for(
unsigned int j=0;j<2;++j)
2842 if(j == 0 && skippingContextPair)
2844 __COUT__ <<
"Skipping context pair..." << __E__;
2847 else if(j == 1 && skippingConfigPair)
2849 __COUT__ <<
"Skipping config pair..." << __E__;
2853 std::map<std::string , ConfigurationVersion >& memberMapAref =
2854 j == 0?memberMapAContext:memberMapAConfig;
2856 std::map<std::string , ConfigurationVersion >& memberMapBref =
2857 j == 0?memberMapBContext:memberMapBConfig;
2860 __COUT__ <<
"Context pair..." << __E__;
2862 __COUT__ <<
"Config pair..." << __E__;
2864 __COUT__ <<
"Starting member map B scan." << __E__;
2865 for(
const auto bkey : memberMapBref)
2867 __SUP_COUTV__(bkey.first);
2869 if(memberMapAref.find(bkey.first) == memberMapAref.end())
2872 memberMapAref[bkey.first] = bkey.second;
2874 else if(memberMapAref[bkey.first] != bkey.second)
2877 __SUP_COUTV__(memberMapAref[bkey.first]);
2878 __SUP_COUTV__(bkey.second);
2881 ConfigurationBase* config = cfgMgr->getConfigurationByName(bkey.first);
2883 __SUP_COUT__ <<
"Got configuration." << __E__;
2885 ConfigurationVersion newVersion = config->mergeViews(
2886 cfgMgr->getVersionedConfigurationByName(bkey.first,
2887 memberMapAref[bkey.first])->getView(),
2888 cfgMgr->getVersionedConfigurationByName(bkey.first,bkey.second)->getView(),
2889 ConfigurationVersion() ,
2892 uidConversionMap, groupidConversionMap,
2895 config->getConfigurationName() ==
2896 ConfigurationManager::XDAQ_APPLICATION_CONFIG_NAME
2901 __SUP_COUTV__(newVersion);
2907 newVersion = saveModifiedVersionXML(xmlOut,cfgMgr,
2909 ConfigurationVersion() ,
2916 catch(std::runtime_error& e)
2918 __SUP_SS__ <<
"There was an error saving the '" <<
2919 config->getConfigurationName() <<
"' merge result to a persistent table version. " <<
2920 "Perhaps you can modify this table in one of the groups to resolve this issue, and then re-merge." <<
2925 __SUP_COUTV__(newVersion);
2928 memberMapAref[bkey.first] = newVersion;
2937 if(!skippingContextPair)
2939 __SUP_COUT__ <<
"New context member map complete." << __E__;
2940 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
2943 ConfigurationGroupKey newKeyContext =
2944 cfgMgr->saveNewConfigurationGroup(groupANameContext,memberMapAContext,
2945 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.toString() +
") and " +
2946 groupBNameContext +
" (" + groupBKeyContext.toString() +
").");
2949 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
2950 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.toString());
2952 if(!skippingConfigPair)
2954 __SUP_COUT__ <<
"New config member map complete." << __E__;
2955 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
2957 ConfigurationGroupKey newKeyConfig =
2958 cfgMgr->saveNewConfigurationGroup(groupANameConfig,memberMapAConfig,
2959 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.toString() +
") and " +
2960 groupBNameConfig +
" (" + groupBKeyConfig.toString() +
").");
2963 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
2964 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.toString());
2970 catch(std::runtime_error& e)
2972 __SUP_SS__ <<
"Error merging context group pair " <<
2973 groupANameContext <<
" (" << groupAKeyContext <<
") & " <<
2974 groupBNameContext <<
" (" << groupBKeyContext <<
") and config group pair " <<
2975 groupANameConfig <<
" (" << groupAKeyConfig <<
") & " <<
2976 groupBNameConfig <<
" (" << groupBKeyConfig <<
") with approach '" <<
2977 mergeApproach <<
"': \n\n" <<
2978 e.what() << std::endl;
2979 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
2980 xmlOut.addTextElementToData(
"Error", ss.str());
2984 __SUP_SS__ <<
"Unknown error merging context group pair " <<
2985 groupANameContext <<
" (" << groupAKeyContext <<
") & " <<
2986 groupBNameContext <<
" (" << groupBKeyContext <<
") and config group pair " <<
2987 groupANameConfig <<
" (" << groupAKeyConfig <<
") & " <<
2988 groupBNameConfig <<
" (" << groupBKeyConfig <<
") with approach '" <<
2989 mergeApproach <<
".' \n\n";
2990 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
2991 xmlOut.addTextElementToData(
"Error", ss.str());
2996 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(HttpXmlDocument& xmlOut,
2997 ConfigurationManagerRW* cfgMgr,
2998 const std::string& groupName,
const ConfigurationGroupKey& groupKey,
2999 const std::string& modifiedTables,
const std::string& author,
3000 const std::string& planName,
3001 const std::string& commandString)
3004 __MOUT__ <<
"handleSavePlanCommandSequenceXML" << std::endl;
3007 setupActiveTablesXML(
3010 groupName, groupKey,
3017 TableEditStruct planTable(IterateConfiguration::PLAN_TABLE,cfgMgr);
3018 TableEditStruct targetTable(IterateConfiguration::TARGET_TABLE,cfgMgr);
3021 std::map<std::string, TableEditStruct> commandTypeToCommandTableMap;
3022 for(
const auto& commandPair : IterateConfiguration::commandToTableMap_)
3023 if(commandPair.second !=
"")
3024 commandTypeToCommandTableMap.emplace(std::pair<std::string,TableEditStruct>(
3026 TableEditStruct(commandPair.second,cfgMgr)));
3044 std::string groupName = planName +
"-Plan";
3045 __SUP_COUT__ <<
"Handling commands for group " << groupName << std::endl;
3047 unsigned int groupIdCol = planTable.cfgView_->findCol(IterateConfiguration::planTableCols_.GroupID_);
3048 unsigned int cmdTypeCol = planTable.cfgView_->findCol(IterateConfiguration::planTableCols_.CommandType_);
3051 unsigned int targetGroupIdCol = targetTable.cfgView_->findCol(IterateConfiguration::targetCols_.GroupID_);
3052 unsigned int targetTableCol = targetTable.cfgView_->findCol(IterateConfiguration::targetCols_.TargetLink_);
3053 unsigned int targetUIDCol = targetTable.cfgView_->findCol(IterateConfiguration::targetCols_.TargetLinkUID_);
3055 std::string groupLinkIndex = planTable.cfgView_->getColumnInfo(groupIdCol).getChildLinkIndex();
3056 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << std::endl;
3058 std::pair<
unsigned int ,
unsigned int > commandUidLink;
3061 planTable.cfgView_->getChildLink(
3062 planTable.cfgView_->findCol(
3063 IterateConfiguration::planTableCols_.CommandLink_),
3064 isGroup,commandUidLink);
3067 unsigned int cmdRow, cmdCol;
3068 std::string targetGroupName;
3072 std::string targetUID, cmdType;
3074 for(
unsigned int row=0;row < planTable.cfgView_->getNumberOfRows(); ++row)
3076 targetUID = planTable.cfgView_->getDataView()[row][planTable.cfgView_->getColUID()];
3077 __SUP_COUT__ <<
"targetUID: " << targetUID << std::endl;
3080 if(planTable.cfgView_->isEntryInGroup(row,
3081 groupLinkIndex,groupName))
3083 __SUP_COUT__ <<
"Removing." << std::endl;
3088 cmdType = planTable.cfgView_->getDataView()[row][cmdTypeCol];
3089 if(commandTypeToCommandTableMap.find(cmdType) !=
3090 commandTypeToCommandTableMap.end())
3092 cmdRow = commandTypeToCommandTableMap[cmdType].cfgView_->findRow(
3093 commandTypeToCommandTableMap[cmdType].cfgView_->getColUID(),
3094 planTable.cfgView_->getDataView()[row][commandUidLink.second]);
3101 cmdCol = commandTypeToCommandTableMap[cmdType].cfgView_->findCol(
3102 IterateConfiguration::commandTargetCols_.TargetsLinkGroupID_);
3104 commandTypeToCommandTableMap[cmdType].cfgView_->getDataView()
3108 for(
unsigned int trow=0;
3109 trow < targetTable.cfgView_->getNumberOfRows();
3113 if(targetTable.cfgView_->isEntryInGroup(
3115 commandTypeToCommandTableMap[cmdType].cfgView_->getColumnInfo(cmdCol).getChildLinkIndex(),
3118 __SUP_COUT__ <<
"Removing target." << std::endl;
3120 if(targetTable.cfgView_->removeRowFromGroup(trow,
3122 targetGroupName,
true ))
3129 __SUP_COUT__ <<
"No targets." << std::endl;
3134 commandTypeToCommandTableMap[cmdType].cfgView_->deleteRow(cmdRow);
3136 commandTypeToCommandTableMap[cmdType].modified_ =
true;
3140 if(planTable.cfgView_->removeRowFromGroup(row,groupIdCol,
3151 std::vector<IterateConfiguration::Command> commands;
3156 std::istringstream f(commandString);
3157 std::string commandSubString, paramSubString, paramValue;
3159 while (getline(f, commandSubString,
';'))
3162 std::istringstream g(commandSubString);
3165 while (getline(g, paramSubString,
','))
3170 if(paramSubString !=
"type")
3172 __SUP_SS__ <<
"Invalid command sequence" << std::endl;
3176 commands.push_back(IterateConfiguration::Command());
3178 getline(g, paramValue,
','); ++i;
3180 commands.back().type_ = paramValue;
3184 getline(g, paramValue,
','); ++i;
3187 commands.back().params_.emplace(
3192 StringMacros::decodeURIComponent(paramValue)
3202 __SUP_COUT__ <<
"commands size " << commands.size() << std::endl;
3210 unsigned int row, tgtRow;
3211 unsigned int targetIndex;
3212 std::string targetStr, cmdUID;
3214 for(
auto& command:commands)
3217 __SUP_COUT__ <<
"command " <<
3218 command.type_ << std::endl;
3219 __SUP_COUT__ <<
"table " <<
3220 IterateConfiguration::commandToTableMap_.at(command.type_) << std::endl;
3223 row = planTable.cfgView_->addRow(author,
"planCommand");
3224 planTable.cfgView_->addRowToGroup(row,groupIdCol,groupName);
3227 planTable.cfgView_->setURIEncodedValue(
3233 planTable.cfgView_->setValueAsString(
3236 planTable.cfgView_->getColStatus());
3239 if(commandTypeToCommandTableMap.find(command.type_) !=
3240 commandTypeToCommandTableMap.end())
3242 __SUP_COUT__ <<
"table " << commandTypeToCommandTableMap[command.type_].configName_ << std::endl;
3247 cmdRow = commandTypeToCommandTableMap[command.type_].cfgView_->addRow(
3248 author,
true ,command.type_ +
"_COMMAND_");
3255 for(
auto& param:command.params_)
3257 __SUP_COUT__ <<
"\t param " <<
3258 param.first <<
" : " <<
3259 param.second << std::endl;
3262 IterateConfiguration::targetParams_.Tables_)
3264 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
3265 std::istringstream f(param.second);
3268 while (getline(f, targetStr,
'='))
3270 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
3271 if(!command.targets_.size() ||
3272 command.targets_.back().table_ !=
"")
3274 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr << __E__;
3276 command.addTarget();
3277 command.targets_.back().table_ = targetStr;
3280 command.targets_[targetIndex++].table_ = targetStr;
3287 IterateConfiguration::targetParams_.UIDs_)
3289 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
3290 std::istringstream f(param.second);
3293 while (getline(f, targetStr,
'='))
3295 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
3296 if(!command.targets_.size() ||
3297 command.targets_.back().UID_ !=
"")
3299 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr << __E__;
3301 command.addTarget();
3302 command.targets_.back().UID_ = targetStr;
3305 command.targets_[targetIndex++].UID_ = targetStr;
3310 cmdCol = commandTypeToCommandTableMap[command.type_].cfgView_->findCol(
3313 __SUP_COUT__ <<
"param col " << cmdCol << std::endl;
3315 commandTypeToCommandTableMap[command.type_].cfgView_->setURIEncodedValue(
3316 param.second,cmdRow,cmdCol);
3319 cmdUID = commandTypeToCommandTableMap[command.type_].cfgView_->getDataView()
3320 [cmdRow][commandTypeToCommandTableMap[command.type_].cfgView_->getColUID()];
3322 if(command.targets_.size())
3326 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
3329 cmdCol = commandTypeToCommandTableMap[command.type_].cfgView_->findCol(
3330 IterateConfiguration::commandTargetCols_.TargetsLink_);
3331 commandTypeToCommandTableMap[command.type_].cfgView_->setValueAsString(
3332 IterateConfiguration::TARGET_TABLE,
3336 cmdCol = commandTypeToCommandTableMap[command.type_].cfgView_->findCol(
3337 IterateConfiguration::commandTargetCols_.TargetsLinkGroupID_);
3338 commandTypeToCommandTableMap[command.type_].cfgView_->setValueAsString(
3339 cmdUID +
"_Targets",
3345 for(
const auto& target:command.targets_)
3347 __SUP_COUT__ << target.table_ <<
" " << target.UID_ << __E__;
3350 tgtRow = targetTable.cfgView_->addRow(author,
"commandTarget");
3351 targetTable.cfgView_->addRowToGroup(
3354 cmdUID +
"_Targets");
3357 targetTable.cfgView_->setValueAsString(
3363 targetTable.cfgView_->setValueAsString(
3372 planTable.cfgView_->setValueAsString(
3373 commandTypeToCommandTableMap[command.type_].configName_,
3375 commandUidLink.first);
3376 planTable.cfgView_->setValueAsString(
3379 commandUidLink.second);
3381 __SUP_COUT__ <<
"linked to uid = " <<
3382 cmdUID << std::endl;
3384 commandTypeToCommandTableMap[command.type_].modified_ =
true;
3393 planTable.cfgView_->print();
3394 planTable.cfgView_->init();
3396 __SUP_COUT__ <<
"requestType tables:" << std::endl;
3398 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3400 modifiedConfig.second.cfgView_->print();
3401 modifiedConfig.second.cfgView_->init();
3404 targetTable.cfgView_->print();
3405 targetTable.cfgView_->init();
3410 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly created versions." << std::endl;
3414 if(planTable.createdTemporaryVersion_)
3416 __SUP_COUT__ <<
"Erasing temporary version " << planTable.configName_ <<
3417 "-v" << planTable.temporaryVersion_ << std::endl;
3419 cfgMgr->eraseTemporaryVersion(planTable.configName_,planTable.temporaryVersion_);
3422 if(targetTable.createdTemporaryVersion_)
3424 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.configName_ <<
3425 "-v" << targetTable.temporaryVersion_ << std::endl;
3427 cfgMgr->eraseTemporaryVersion(targetTable.configName_,targetTable.temporaryVersion_);
3430 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3432 if(modifiedConfig.second.createdTemporaryVersion_)
3434 __SUP_COUT__ <<
"Erasing temporary version " << modifiedConfig.second.configName_ <<
3435 "-v" << modifiedConfig.second.temporaryVersion_ << std::endl;
3437 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.configName_,
3438 modifiedConfig.second.temporaryVersion_);
3449 ConfigurationVersion finalVersion = saveModifiedVersionXML(xmlOut,cfgMgr,
3450 planTable.configName_,
3451 planTable.originalVersion_,
true ,
3452 planTable.config_,planTable.temporaryVersion_,
true );
3454 __SUP_COUT__ <<
"Final plan version is " << planTable.configName_ <<
"-v" <<
3455 finalVersion << std::endl;
3457 finalVersion = saveModifiedVersionXML(xmlOut,cfgMgr,
3458 targetTable.configName_,
3459 targetTable.originalVersion_,
true ,
3460 targetTable.config_,targetTable.temporaryVersion_,
true );
3462 __SUP_COUT__ <<
"Final target version is " << targetTable.configName_ <<
"-v" <<
3463 finalVersion << std::endl;
3465 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3467 if(!modifiedConfig.second.modified_)
3469 if(modifiedConfig.second.createdTemporaryVersion_)
3471 __SUP_COUT__ <<
"Erasing unmodified temporary version " << modifiedConfig.second.configName_ <<
3472 "-v" << modifiedConfig.second.temporaryVersion_ << std::endl;
3474 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.configName_,
3475 modifiedConfig.second.temporaryVersion_);
3480 finalVersion = saveModifiedVersionXML(xmlOut,cfgMgr,
3481 modifiedConfig.second.configName_,
3482 modifiedConfig.second.originalVersion_,
true ,
3483 modifiedConfig.second.config_,
3484 modifiedConfig.second.temporaryVersion_,
true );
3486 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.configName_ <<
"-v" <<
3487 finalVersion << std::endl;
3490 handleFillModifiedTablesXML(xmlOut,cfgMgr);
3492 catch(std::runtime_error& e)
3494 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << std::endl;
3495 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
3496 xmlOut.addTextElementToData(
"Error", ss.str());
3500 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n "<< std::endl;
3501 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
3502 xmlOut.addTextElementToData(
"Error", ss.str());
3515 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(HttpXmlDocument& xmlOut,
3516 ConfigurationManagerRW* cfgMgr,
const std::string& configName,
3517 ConfigurationVersion version,
const std::string& type,
3518 const std::string& uid,
const std::string& colName,
const std::string& newValue,
3519 const std::string& author)
3522 __SUP_COUT__ <<
"table " <<
3523 configName <<
"(" << version <<
")" << std::endl;
3532 ConfigurationBase* config = cfgMgr->getConfigurationByName(configName);
3535 config->setActiveView(version);
3539 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: " <<
3540 version << std::endl;
3541 cfgMgr->getVersionedConfigurationByName(
3542 configName, version);
3545 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << std::endl;
3547 if(version != config->getViewVersion())
3549 __SUP_SS__ <<
"Target table version (" << version <<
3550 ") is not the currently active version (" << config->getViewVersion()
3551 <<
". Try refreshing the tree." << std::endl;
3555 unsigned int col = -1;
3556 if(type ==
"uid" || type ==
"delete-uid")
3557 col = config->getView().getColUID();
3559 type ==
"link-UID" ||
3560 type ==
"link-GroupID" ||
3562 type ==
"value-groupid" ||
3563 type ==
"value-bool"||
3564 type ==
"value-bitmap")
3565 col = config->getView().findCol(colName);
3568 type ==
"link-comment" ||
3569 type ==
"table-newGroupRow" ||
3570 type ==
"table-newUIDRow" ||
3571 type ==
"table-newRow");
3574 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << std::endl;
3579 if(type ==
"table" ||
3580 type ==
"link-comment")
3583 if(config->getView().isURIEncodedCommentTheSame(newValue))
3585 __SUP_SS__ <<
"Comment '" << newValue <<
3586 "' is the same as the current comment. No need to save change." <<
3604 ConfigurationVersion temporaryVersion = config->createTemporaryView(version);
3606 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << std::endl;
3608 ConfigurationView* cfgView = config->getTemporaryView(temporaryVersion);
3614 if(type ==
"table" ||
3615 type ==
"link-comment")
3618 cfgView->setURIEncodedComment(newValue);
3620 else if(type ==
"table-newRow" ||
3621 type ==
"table-newUIDRow")
3624 unsigned int row = cfgView->addRow(author,
true );
3629 col = cfgView->getColStatus();
3630 cfgView->setValueAsString(
"1",row,col);
3635 cfgView->setURIEncodedValue(newValue,row,cfgView->getColUID());
3637 else if(type ==
"table-newGroupRow")
3640 unsigned int row = cfgView->addRow(author,
true );
3643 unsigned int csvIndex = newValue.find(
',');
3645 std::string linkIndex = newValue.substr(0,csvIndex);
3646 std::string groupId = newValue.substr(csvIndex+1);
3649 csvIndex = groupId.find(
',');
3650 std::string newRowUID = groupId.substr(csvIndex+1);
3651 groupId = groupId.substr(0,csvIndex);
3653 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," <<
3655 newRowUID << std::endl;
3658 cfgView->setURIEncodedValue(newRowUID,row,cfgView->getColUID());
3661 col = cfgView->getColLinkGroupID(linkIndex);
3664 cfgView->setURIEncodedValue(groupId,row,col);
3669 col = cfgView->getColStatus();
3670 cfgView->setValueAsString(
"1",row,col);
3675 else if(type ==
"delete-uid")
3678 unsigned int row = cfgView->findRow(col,uid);
3679 cfgView->deleteRow(row);
3681 else if(type ==
"uid" ||
3683 type ==
"value-groupid" ||
3684 type ==
"value-bool" ||
3685 type ==
"value-bitmap")
3687 unsigned int row = cfgView->findRow(cfgView->getColUID(),uid);
3688 if(!cfgView->setURIEncodedValue(newValue,row,col,author))
3691 __SUP_SS__ <<
"Value '" << newValue <<
3692 "' is the same as the current value. No need to save change to tree node." <<
3697 else if(type ==
"link-UID" || type ==
"link-GroupID")
3700 std::pair<
unsigned int ,
unsigned int > linkPair;
3701 if(!cfgView->getChildLink(col,isGroup,linkPair))
3704 __SUP_SS__ <<
"Col '" << colName <<
3705 "' is not a link column." <<
3710 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," <<
3711 linkPair.second << std::endl;
3713 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
3715 __SUP_COUT__ <<
"linkIndex " << linkIndex << std::endl;
3718 unsigned int csvIndexStart = 0,csvIndex = newValue.find(
',');
3720 std::string newTable = newValue.substr(csvIndexStart,csvIndex);
3721 csvIndexStart = csvIndex + 1;
3722 csvIndex = newValue.find(
',',csvIndexStart);
3723 std::string newLinkId =
3724 newValue.substr(csvIndexStart,csvIndex-csvIndexStart);
3726 __SUP_COUT__ <<
"newValue " << newTable <<
"," <<
3727 newLinkId << std::endl;
3730 unsigned int row = cfgView->findRow(cfgView->getColUID(),uid);
3731 bool changed =
false;
3732 if(!cfgView->setURIEncodedValue(newTable,row,
3733 linkPair.first,author))
3736 __SUP_COUT__ <<
"Value '" << newTable <<
3737 "' is the same as the current value." <<
3743 if(!cfgView->setURIEncodedValue(newLinkId,row,
3744 linkPair.second,author))
3747 __SUP_COUT__ <<
"Value '" << newLinkId <<
3748 "' is the same as the current value." <<
3759 if(type ==
"link-GroupID")
3761 bool secondaryChanged =
false;
3766 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table." << std::endl;
3767 config->eraseView(temporaryVersion);
3775 saveModifiedVersionXML(xmlOut,cfgMgr,configName,version,
true ,
3776 config,temporaryVersion,
true );
3778 catch(std::runtime_error& e)
3780 __SUP_COUT__ <<
"Caught error while editing main table. Erasing temporary version." << std::endl;
3781 config->eraseView(temporaryVersion);
3785 xmlOut.addTextElementToData(
"Warning",
"Error saving primary tree node! " + std::string(e.what()));
3795 csvIndexStart = csvIndex + 1;
3796 csvIndex = newValue.find(
',',csvIndexStart);
3797 version = ConfigurationVersion(
3798 newValue.substr(csvIndexStart,csvIndex-csvIndexStart));
3801 if(newTable == ViewColumnInfo::DATATYPE_LINK_DEFAULT)
3809 config = cfgMgr->getConfigurationByName(newTable);
3812 config->setActiveView(version);
3816 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: " <<
3817 version << std::endl;
3818 cfgMgr->getVersionedConfigurationByName(
3822 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << std::endl;
3824 if(version != config->getViewVersion())
3826 __SUP_SS__ <<
"Target table version (" << version <<
3827 ") is not the currently active version (" << config->getViewVersion()
3828 <<
". Try refreshing the tree." << std::endl;
3834 temporaryVersion = config->createTemporaryView(version);
3836 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << std::endl;
3838 cfgView = config->getTemporaryView(temporaryVersion);
3840 col = cfgView->getColLinkGroupID(linkIndex);
3842 __SUP_COUT__ <<
"target col " << col << std::endl;
3846 std::vector<std::string> memberUIDs;
3849 csvIndexStart = csvIndex + 1;
3850 csvIndex = newValue.find(
',',csvIndexStart);
3851 memberUIDs.push_back(newValue.substr(csvIndexStart,csvIndex-csvIndexStart));
3852 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << std::endl;
3853 }
while(csvIndex != (
unsigned int)std::string::npos);
3864 std::string targetUID;
3865 bool shouldBeInGroup;
3866 bool defaultIsInGroup =
false;
3869 for(
unsigned int row=0;row<cfgView->getNumberOfRows();++row)
3871 targetUID = cfgView->getDataView()[row][cfgView->getColUID()];
3872 __SUP_COUT__ <<
"targetUID: " << targetUID << std::endl;
3874 shouldBeInGroup =
false;
3875 for(
unsigned int i=0;i<memberUIDs.size();++i)
3876 if(targetUID == memberUIDs[i])
3879 shouldBeInGroup =
true;
3883 isInGroup = cfgView->isEntryInGroup(row,linkIndex,newLinkId);
3886 if(shouldBeInGroup && !isInGroup)
3889 __SUP_COUT__ <<
"Changed YES: " << row << std::endl;
3890 secondaryChanged =
true;
3892 cfgView->addRowToGroup(row,col,newLinkId);
3895 else if(!shouldBeInGroup && isInGroup)
3898 __SUP_COUT__ <<
"Changed NO: " << row << std::endl;
3899 secondaryChanged =
true;
3901 cfgView->removeRowFromGroup(row,col,newLinkId);
3903 else if(targetUID ==
3904 cfgView->getDefaultRowValues()[cfgView->getColUID()] &&
3908 defaultIsInGroup =
true;
3914 if(!secondaryChanged)
3916 __SUP_COUT__ <<
"No changes to secondary view. Erasing temporary table." << std::endl;
3917 config->eraseView(temporaryVersion);
3925 saveModifiedVersionXML(xmlOut,cfgMgr,newTable,version,
true ,
3926 config,temporaryVersion,
true );
3928 catch(std::runtime_error& e)
3930 __SUP_COUT__ <<
"Caught error while editing secondary table. Erasing temporary version." << std::endl;
3931 config->eraseView(temporaryVersion);
3932 secondaryChanged =
false;
3935 xmlOut.addTextElementToData(
"Warning",
"Error saving secondary tree node! " + std::string(e.what()));
3941 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
3943 __SUP_SS__ <<
"Link to table '" << newTable <<
3944 "', linkID '" << newLinkId <<
3945 "', and selected group members are the same as the current value. " <<
3946 "No need to save changes to tree." <<
3953 else if(0 && !changed)
3955 __SUP_SS__ <<
"Link to table '" << newTable <<
3956 "' and linkID '" << newLinkId <<
3957 "' are the same as the current values. No need to save change to tree node." <<
3967 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << std::endl;
3968 config->eraseView(temporaryVersion);
3972 saveModifiedVersionXML(xmlOut,cfgMgr,configName,version,
true ,
3973 config,temporaryVersion,
true );
3975 catch(std::runtime_error& e)
3977 __SUP_SS__ <<
"Error saving tree node! " << std::string(e.what()) << std::endl;
3978 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
3979 xmlOut.addTextElementToData(
"Error", ss.str());
3983 __SUP_SS__ <<
"Error saving tree node! " << std::endl;
3984 __SUP_COUT_ERR__ <<
"\n" << ss.str() << std::endl;
3985 xmlOut.addTextElementToData(
"Error", ss.str());
4011 void ConfigurationGUISupervisor::handleGetConfigurationGroupXML(HttpXmlDocument& xmlOut,
4012 ConfigurationManagerRW* cfgMgr,
const std::string& groupName,
4013 ConfigurationGroupKey groupKey)
4016 char tmpIntStr[100];
4017 DOMElement* parentEl,* configEl;
4041 const GroupInfo& groupInfo = cfgMgr->getGroupInfo(groupName);
4042 const std::set<ConfigurationGroupKey>& sortedKeys = groupInfo.keys_;
4044 if(groupKey.isInvalid() ||
4045 sortedKeys.find(groupKey) == sortedKeys.end())
4047 if(sortedKeys.size())
4048 groupKey =* sortedKeys.rbegin();
4049 __SUP_COUT__ <<
"Group key requested was invalid or not found, going with latest " <<
4050 groupKey << std::endl;
4055 xmlOut.addTextElementToData(
"ConfigurationGroupName", groupName);
4056 xmlOut.addTextElementToData(
"ConfigurationGroupKey", groupKey.toString());
4059 for(
auto& keyInOrder:sortedKeys)
4060 xmlOut.addTextElementToData(
"HistoricalConfigurationGroupKey", keyInOrder.toString());
4063 parentEl = xmlOut.addTextElementToData(
"ConfigurationGroupMembers",
"");
4067 std::map<std::string , ConfigurationVersion > memberMap;
4068 std::map<std::string , std::string > groupMemberAliases;
4070 __SUP_COUT__ <<
"groupName=" << groupName << std::endl;
4071 __SUP_COUT__ <<
"groupKey=" << groupKey << std::endl;
4073 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo();
4074 std::map<std::string, ConfigurationInfo>::const_iterator it;
4080 std::string groupAuthor, groupComment, groupCreationTime, groupTypeString;
4081 std::string accumulateErrors;
4083 cfgMgr->loadConfigurationGroup(groupName,groupKey,
4084 false ,&memberMap,0 ,
4086 &groupComment, &groupAuthor, &groupCreationTime,
4087 false , &groupTypeString, &groupMemberAliases);
4089 if(accumulateErrors !=
"")
4091 __SUP_SS__ << accumulateErrors;
4095 xmlOut.addTextElementToData(
"ConfigurationGroupAuthor", groupAuthor);
4096 xmlOut.addTextElementToData(
"ConfigurationGroupComment", groupComment);
4097 xmlOut.addTextElementToData(
"ConfigurationGroupCreationTime", groupCreationTime);
4098 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupTypeString);
4100 catch(
const std::runtime_error& e)
4102 __SUP_SS__ <<
"Configuration group \"" +
4103 groupName +
"(" + groupKey.toString() +
")" +
4104 "\" members can not be loaded!\n\n" + e.what();
4105 __SUP_COUT_ERR__ << ss.str();
4106 xmlOut.addTextElementToData(
"Error",ss.str());
4111 __SUP_SS__ <<
"Configuration group \"" +
4112 groupName +
"(" + groupKey.toString() +
")" +
4113 "\" members can not be loaded!" << __E__;
4114 __SUP_COUT_ERR__ << ss.str();
4115 xmlOut.addTextElementToData(
"Error",ss.str());
4119 __COUTV__(StringMacros::mapToString(groupMemberAliases));
4121 std::map<std::string,std::map<std::string,ConfigurationVersion> > versionAliases =
4122 cfgMgr->getVersionAliases();
4124 __SUP_COUT__ <<
"# of table version aliases: " << versionAliases.size() << std::endl;
4129 for(
auto& memberPair:memberMap)
4131 xmlOut.addTextElementToParent(
"MemberName", memberPair.first, parentEl);
4134 if(groupMemberAliases.find(memberPair.first) != groupMemberAliases.end())
4135 configEl = xmlOut.addTextElementToParent(
"MemberVersion",
4136 ConfigurationManager::ALIAS_VERSION_PREAMBLE +
4137 groupMemberAliases[memberPair.first],
4140 configEl = xmlOut.addTextElementToParent(
"MemberVersion", memberPair.second.toString(),
4143 it = allCfgInfo.find(memberPair.first);
4144 if(it == allCfgInfo.end())
4146 xmlOut.addTextElementToData(
"Error",
"Configuration \"" +
4148 "\" can not be retrieved!");
4152 if(versionAliases.find(it->first) != versionAliases.end())
4153 for (
auto& aliasVersion:versionAliases[it->first])
4154 xmlOut.addTextElementToParent(
"ConfigurationExistingVersion",
4155 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
4158 for (
auto& version:it->second.versions_)
4161 xmlOut.addTextElementToParent(
"ConfigurationExistingVersion", version.toString(), configEl);
4164 for(
auto& memberPair:memberMap)
4171 xmlOut.addTextElementToParent(
"MemberComment",
4172 allCfgInfo.at(memberPair.first).configurationPtr_->getView().getComment(),
4209 catch(std::runtime_error& e)
4211 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << std::endl;
4212 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4213 xmlOut.addTextElementToData(
"Error", ss.str());
4217 __SUP_SS__ << (
"Error!\n\n") << std::endl;
4218 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4219 xmlOut.addTextElementToData(
"Error", ss.str());
4262 void ConfigurationGUISupervisor::handleGetConfigurationXML(HttpXmlDocument& xmlOut,
4263 ConfigurationManagerRW* cfgMgr,
const std::string& tableName,
4264 ConfigurationVersion version,
bool allowIllegalColumns)
4267 char tmpIntStr[100];
4268 DOMElement *parentEl, *subparentEl;
4270 std::string accumulatedErrors =
"";
4272 const std::map<std::string, ConfigurationInfo>& allCfgInfo =
4273 cfgMgr->getAllConfigurationInfo(allowIllegalColumns,
4274 allowIllegalColumns?&accumulatedErrors:0,tableName);
4276 ConfigurationBase* config = cfgMgr->getConfigurationByName(tableName);
4280 xmlOut.addTextElementToData(
"ExistingConfigurationNames", ViewColumnInfo::DATATYPE_LINK_DEFAULT);
4281 for(
auto& configPair:allCfgInfo)
4283 xmlOut.addTextElementToData(
"ExistingConfigurationNames",
4285 if(configPair.first == tableName &&
4286 configPair.second.versions_.find(version) ==
4287 configPair.second.versions_.end())
4289 __SUP_COUT__ <<
"Version not found, so using mockup." << std::endl;
4290 version = ConfigurationVersion();
4294 xmlOut.addTextElementToData(
"ConfigurationName", tableName);
4295 xmlOut.addTextElementToData(
"ConfigurationDescription",
4296 config->getConfigurationDescription());
4302 std::map<std::string ,std::map<
4303 std::string ,ConfigurationVersion > > versionAliases;
4307 versionAliases = cfgMgr->getVersionAliases();
4308 for(
const auto& aliases:versionAliases)
4309 for(
const auto& alias:aliases.second)
4310 __SUP_COUT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first <<
" ==> " << alias.second << std::endl;
4312 catch(
const std::runtime_error& e)
4314 __SUP_COUT__ <<
"Could not get backbone information for version aliases: " << e.what() << __E__;
4317 auto tableIterator = versionAliases.find(tableName);
4319 parentEl = xmlOut.addTextElementToData(
"ConfigurationVersions",
"");
4320 for(
const ConfigurationVersion& v:allCfgInfo.at(tableName).versions_)
4322 subparentEl = xmlOut.addTextElementToParent(
"Version", v.toString(), parentEl);
4324 if(tableIterator != versionAliases.end())
4327 for(
const auto& aliasPair : tableIterator->second)
4331 if(v == aliasPair.second)
4333 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> " <<
4334 aliasPair.first << __E__;
4335 xmlOut.addTextElementToParent(
"VersionAlias", aliasPair.first, subparentEl);
4346 ConfigurationView* cfgViewPtr;
4347 if(version.isInvalid())
4349 cfgViewPtr = config->getMockupViewP();
4355 cfgViewPtr = cfgMgr->getVersionedConfigurationByName(tableName,version)->getViewP();
4357 catch(std::runtime_error& e)
4359 __SUP_SS__ <<
"Failed to get table " << tableName <<
4360 " version " << version <<
4361 "... defaulting to mock-up! " <<
4363 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << std::endl;
4365 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4366 version = ConfigurationVersion();
4367 cfgViewPtr = config->getMockupViewP();
4369 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
4373 __SUP_SS__ <<
"Failed to get table " << tableName <<
4374 " version: " << version <<
4375 "... defaulting to mock-up! " <<
4376 "(You may want to try again to see what was partially loaded into cache before failure. " <<
4377 "If you think, the failure is due to a column name change, " <<
4378 "you can also try to Copy the failing view to the new column names using " <<
4379 "'Copy and Move' functionality.)" <<
4382 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4383 version = ConfigurationVersion();
4384 cfgViewPtr = config->getMockupViewP();
4386 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
4389 xmlOut.addTextElementToData(
"ConfigurationVersion", version.toString());
4392 DOMElement* choicesParentEl;
4393 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
4395 std::vector<ViewColumnInfo> colInfo = cfgViewPtr->getColumnsInfo();
4397 for(
int i=0;i<(int)colInfo.size();++i)
4403 xmlOut.addTextElementToParent(
"ColumnHeader", colInfo[i].getName(), parentEl);
4404 xmlOut.addTextElementToParent(
"ColumnType", colInfo[i].getType(), parentEl);
4405 xmlOut.addTextElementToParent(
"ColumnDataType", colInfo[i].getDataType(), parentEl);
4408 xmlOut.addTextElementToParent(
"ColumnChoices",
"", parentEl);
4410 if(colInfo[i].getType() == ViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
4411 colInfo[i].getType() == ViewColumnInfo::TYPE_BITMAP_DATA ||
4412 colInfo[i].isChildLink())
4414 for(
auto& choice:colInfo[i].getDataChoices())
4415 xmlOut.addTextElementToParent(
"ColumnChoice", choice, choicesParentEl);
4422 if(version.isInvalid())
4425 catch(std::runtime_error& e)
4428 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
4435 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
4437 for(
int r=0;r<(int)cfgViewPtr->getNumberOfRows();++r)
4441 sprintf(tmpIntStr,
"%d",r);
4442 DOMElement* tmpParentEl = xmlOut.addTextElementToParent(
"Row", tmpIntStr, parentEl);
4444 for(
int c=0;c<(int)cfgViewPtr->getNumberOfColumns();++c)
4446 if(colInfo[c].getDataType() == ViewColumnInfo::DATATYPE_TIME)
4448 std::string timeAsString;
4449 cfgViewPtr->getValue(timeAsString,r,c);
4450 xmlOut.addTextElementToParent(
"Entry", timeAsString, tmpParentEl);
4453 xmlOut.addTextElementToParent(
"Entry", cfgViewPtr->getDataView()[r][c], tmpParentEl);
4458 xmlOut.addTextElementToData(
"TableComment", cfgViewPtr->getComment());
4459 xmlOut.addTextElementToData(
"TableAuthor", cfgViewPtr->getAuthor());
4460 xmlOut.addTextElementToData(
"TableCreationTime", std::to_string(cfgViewPtr->getCreationTime()));
4461 xmlOut.addTextElementToData(
"TableLastAccessTime", std::to_string(cfgViewPtr->getLastAccessTime()));
4464 std::vector<std::string> defaultRowValues =
4465 cfgViewPtr->getDefaultRowValues();
4467 for(
unsigned int c = 0; c<defaultRowValues.size()-2; ++c)
4472 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
4476 if(accumulatedErrors !=
"")
4478 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so maybe you can ignore this, ") +
4479 "but please note the following errors:\n" + accumulatedErrors) << std::endl;
4480 __SUP_COUT_ERR__ << ss.str();
4481 xmlOut.addTextElementToData(
"Error", ss.str());
4483 else if(!version.isTemporaryVersion() &&
4484 (cfgViewPtr->getDataColumnSize() !=
4485 cfgViewPtr->getNumberOfColumns() ||
4486 cfgViewPtr->getSourceColumnMismatch() != 0))
4488 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " <<
4489 tableName <<
":v" << version <<
". Please see the details below:\n\n" <<
4490 "The source column size was found to be " << cfgViewPtr->getDataColumnSize() <<
4491 ", and the current number of columns for this table is " <<
4492 cfgViewPtr->getNumberOfColumns() <<
". This resulted in a count of " <<
4493 cfgViewPtr->getSourceColumnMismatch() <<
" source column mismatches, and a count of " <<
4494 cfgViewPtr->getSourceColumnMissing() <<
" table entries missing in " <<
4495 cfgViewPtr->getNumberOfRows() <<
" row(s) of data." << std::endl;
4499 const std::set<std::string> srcColNames = cfgViewPtr->getSourceColumnNames();
4500 ss <<
"\n\nSource column names in ALPHABETICAL order were as follows:\n";
4502 std::string preIndexStr =
"";
4503 for(
auto& srcColName:srcColNames)
4505 ss <<
"\n\t" << preIndexStr << index <<
". " << srcColName;
4516 std::set<std::string> destColNames = cfgViewPtr->getColumnStorageNames();
4517 ss <<
"\n\nCurrent table column names in ALPHABETICAL order are as follows:\n";
4520 for(
auto& destColName:destColNames)
4522 ss <<
"\n\t" << preIndexStr << index <<
". " << destColName;
4533 __SUP_COUT__ <<
"\n" << ss.str();
4534 xmlOut.addTextElementToData(
"TableWarnings",ss.str());
4537 catch(std::runtime_error& e)
4539 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
4540 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + std::string(e.what()));
4544 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
4545 xmlOut.addTextElementToData(
"Error",
"Error getting view! ");
4554 ConfigurationVersion ConfigurationGUISupervisor::saveModifiedVersionXML(HttpXmlDocument& xmlOut,
4555 ConfigurationManagerRW* cfgMgr,
const std::string& configName,
4556 ConfigurationVersion originalVersion,
4558 ConfigurationBase* config,
4559 ConfigurationVersion temporaryModifiedVersion,
4560 bool ignoreDuplicates,
4561 bool lookForEquivalent)
4563 bool needToEraseTemporarySource = (originalVersion.isTemporaryVersion() && !makeTemporary);
4567 if(!ignoreDuplicates)
4569 __SUP_COUT__ <<
"Checking for duplicate tables..." << std::endl;
4571 ConfigurationVersion duplicateVersion;
4577 const std::map<std::string, ConfigurationInfo>& allCfgInfo =
4578 cfgMgr->getAllConfigurationInfo();
4580 auto versionReverseIterator = allCfgInfo.at(configName).versions_.rbegin();
4581 __SUP_COUT__ <<
"Filling up cached from " <<
4582 config->getNumberOfStoredViews() <<
4583 " to max count of " << config->MAX_VIEWS_IN_CACHE << std::endl;
4584 for(;config->getNumberOfStoredViews() < config->MAX_VIEWS_IN_CACHE &&
4585 versionReverseIterator != allCfgInfo.at(configName).versions_.rend();++versionReverseIterator)
4587 __SUP_COUT__ <<
"Versions in reverse order " << *versionReverseIterator << std::endl;
4590 cfgMgr->getVersionedConfigurationByName(configName,*versionReverseIterator);
4592 catch(
const std::runtime_error& e)
4594 __SUP_COUT__ <<
"Error loadiing historical version, but ignoring: " << e.what() << __E__;
4599 __SUP_COUT__ <<
"Checking duplicate..." << std::endl;
4602 duplicateVersion = config->checkForDuplicate(temporaryModifiedVersion,
4603 (!originalVersion.isTemporaryVersion() && !makeTemporary)?
4604 ConfigurationVersion():
4607 if(lookForEquivalent && !duplicateVersion.isInvalid())
4610 __SUP_COUT__ <<
"Equivalent table found in version v" << duplicateVersion << std::endl;
4613 if(duplicateVersion.isTemporaryVersion() && !makeTemporary)
4615 __SUP_COUT__ <<
"Need persistent. Duplicate version was temporary. Abandoning duplicate." << __E__;
4616 duplicateVersion = ConfigurationVersion();
4623 cfgMgr->eraseTemporaryVersion(configName,temporaryModifiedVersion);
4626 if(needToEraseTemporarySource)
4627 cfgMgr->eraseTemporaryVersion(configName,originalVersion);
4629 xmlOut.addTextElementToData(
"savedName", configName);
4630 xmlOut.addTextElementToData(
"savedVersion", duplicateVersion.toString());
4631 xmlOut.addTextElementToData(
"foundEquivalentVersion",
"1");
4633 __SUP_COUT__ <<
"\t\t equivalent AssignedVersion: " << duplicateVersion << std::endl;
4635 return duplicateVersion;
4639 if(!duplicateVersion.isInvalid())
4641 __SUP_SS__ <<
"This version is identical to another version currently cached v" <<
4642 duplicateVersion <<
". No reason to save a duplicate." << std::endl;
4643 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4646 config->eraseView(temporaryModifiedVersion);
4650 __SUP_COUT__ <<
"Check for duplicate tables complete." << std::endl;
4655 __SUP_COUT__ <<
"\t\t**************************** Save as temporary table version" << std::endl;
4657 __SUP_COUT__ <<
"\t\t**************************** Save as new table version" << std::endl;
4661 ConfigurationVersion newAssignedVersion =
4662 cfgMgr->saveNewConfiguration(configName,temporaryModifiedVersion,
4665 if(needToEraseTemporarySource)
4666 cfgMgr->eraseTemporaryVersion(configName,originalVersion);
4668 xmlOut.addTextElementToData(
"savedName", configName);
4669 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
4671 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << std::endl;
4672 return newAssignedVersion;
4683 void ConfigurationGUISupervisor::handleCreateConfigurationXML(HttpXmlDocument& xmlOut,
4684 ConfigurationManagerRW* cfgMgr,
const std::string& configName, ConfigurationVersion version,
4685 bool makeTemporary,
const std::string& data,
const int& dataOffset,
4686 const std::string& author,
const std::string& comment,
4687 bool sourceTableAsIs,
bool lookForEquivalent)
4696 if(!version.isInvalid())
4700 cfgMgr->getVersionedConfigurationByName(configName,version);
4705 version = ConfigurationVersion();
4709 ConfigurationBase* config = cfgMgr->getConfigurationByName(configName);
4713 if(!version.isInvalid())
4716 if(config->getViewP()->getDataColumnSize() !=
4717 config->getMockupViewP()->getNumberOfColumns() ||
4718 config->getViewP()->getSourceColumnMismatch() != 0)
4720 __SUP_COUT__ <<
"config->getViewP()->getNumberOfColumns() " << config->getViewP()->getNumberOfColumns() << std::endl;
4721 __SUP_COUT__ <<
"config->getMockupViewP()->getNumberOfColumns() " << config->getMockupViewP()->getNumberOfColumns() << std::endl;
4722 __SUP_COUT__ <<
"config->getViewP()->getSourceColumnMismatch() " << config->getViewP()->getSourceColumnMismatch() << std::endl;
4723 __SUP_COUT_INFO__ <<
"Source view v" << version <<
4724 " has a mismatch in the number of columns, so using mockup as source." << std::endl;
4725 version = ConfigurationVersion();
4730 ConfigurationVersion temporaryVersion = config->createTemporaryView(version);
4732 __SUP_COUT__ <<
"\t\ttemporaryVersion: " << temporaryVersion << std::endl;
4734 ConfigurationView* cfgView = config->getTemporaryView(temporaryVersion);
4740 retVal = sourceTableAsIs?0:cfgView->fillFromCSV(data,dataOffset,author);
4744 __SUP_COUT__ <<
"Data was the same, but columns have changed!" << __E__;
4745 __SUP_COUTV__(sourceTableAsIs);
4746 lookForEquivalent =
false;
4749 cfgView->setURIEncodedComment(comment);
4750 __SUP_COUT__ <<
"Table comment was set to:\n\t" << cfgView->getComment() << std::endl;
4755 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << std::endl;
4756 config->eraseView(temporaryVersion);
4767 (!version.isTemporaryVersion() || makeTemporary) &&
4768 ConfigurationInterface::isVersionTrackingEnabled()
4771 if(!version.isInvalid() &&
4772 !version.isScratchVersion())
4774 __SUP_SS__ <<
"No rows were modified! No reason to fill a view with same content." << std::endl;
4775 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4777 config->eraseView(temporaryVersion);
4780 else if(version.isInvalid())
4781 __SUP_COUT__ <<
"This was interpreted as an attempt to create a blank table." << std::endl;
4782 else if(version.isScratchVersion())
4783 __SUP_COUT__ <<
"This was interpreted as an attempt to make a persistent version of the scratch table." << std::endl;
4785 {__SUP_SS__; __THROW__(ss.str()+
"impossible!");}
4787 else if(retVal < 0 &&
4788 (version.isTemporaryVersion() && !makeTemporary))
4790 __SUP_COUT__ <<
"Allowing the static data because this is converting from temporary to persistent version." << std::endl;
4792 else if(retVal < 0 &&
4793 !ConfigurationInterface::isVersionTrackingEnabled())
4795 __SUP_COUT__ <<
"Allowing the static data because version tracking is OFF." << std::endl;
4799 __SUP_SS__ <<
"This should not be possible! Fatal error." << std::endl;
4801 config->eraseView(temporaryVersion);
4806 saveModifiedVersionXML(xmlOut,cfgMgr,configName,version,makeTemporary,
4807 config,temporaryVersion,
false ,
4808 lookForEquivalent || sourceTableAsIs );
4810 catch(std::runtime_error& e)
4812 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
4813 xmlOut.addTextElementToData(
"Error",
"Error saving new view!\n " +
4814 std::string(e.what()));
4818 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
4819 xmlOut.addTextElementToData(
"Error",
"Error saving new view! ");
4832 ConfigurationManagerRW* ConfigurationGUISupervisor::refreshUserSession(std::string username,
4833 uint64_t activeSessionIndex,
bool refresh)
4836 activeSessionIndex = 0;
4838 std::stringstream ssMapKey;
4839 ssMapKey << username <<
":" << activeSessionIndex;
4840 std::string mapKey = ssMapKey.str();
4841 __SUP_COUT__ <<
"Config Session: " << mapKey <<
" ... out of size: " << userConfigurationManagers_.size() << std::endl;
4843 time_t now = time(0);
4846 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
4848 __SUP_COUT_INFO__ <<
"Creating new Configuration Manager." << std::endl;
4849 userConfigurationManagers_[mapKey] =
new ConfigurationManagerRW(username);
4854 userConfigurationManagers_[mapKey]->getAllConfigurationInfo(
true);
4856 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
4858 __SUP_SS__ <<
"Fatal error managing userLastUseTime_!" << std::endl;
4859 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4862 else if(refresh || (now - userLastUseTime_[mapKey]) >
4863 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
4865 __SUP_COUT_INFO__ <<
"Refreshing all configuration info." << std::endl;
4866 userConfigurationManagers_[mapKey]->getAllConfigurationInfo(
true);
4874 userLastUseTime_[mapKey] = now;
4877 for (std::map<std::string, time_t> ::iterator it=userLastUseTime_.begin(); it!=userLastUseTime_.end(); ++it)
4878 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
4880 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second << std::endl;
4881 delete userConfigurationManagers_[it->first];
4882 if(!(userConfigurationManagers_.erase(it->first)))
4884 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!" << std::endl;
4885 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4888 userLastUseTime_.erase(it);
4890 it=userLastUseTime_.begin();
4893 return userConfigurationManagers_[mapKey];
4914 void ConfigurationGUISupervisor::handleCreateConfigurationGroupXML(
4915 HttpXmlDocument& xmlOut,
4916 ConfigurationManagerRW* cfgMgr,
const std::string& groupName,
4917 const std::string& configList,
bool allowDuplicates,
bool ignoreWarnings,
4918 const std::string& groupComment,
bool lookForEquivalent)
4921 __SUP_COUT__ <<
"handleCreateConfigurationGroupXML \n";
4923 xmlOut.addTextElementToData(
"AttemptedNewGroupName",groupName);
4927 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo(
true);
4928 cfgMgr->loadConfigurationBackbone();
4930 std::map<std::string ,
4931 std::map<std::string ,
4932 ConfigurationVersion > > versionAliases =
4933 cfgMgr->getVersionAliases();
4934 for(
const auto& aliases:versionAliases)
4935 for(
const auto& alias:aliases.second)
4936 __SUP_COUT__ << aliases.first <<
" " << alias.first <<
" " << alias.second << std::endl;
4938 std::map<std::string , ConfigurationVersion > groupMembers;
4939 std::map<std::string , std::string > groupAliases;
4941 std::string name, versionStr, alias;
4942 ConfigurationVersion version;
4943 auto c = configList.find(
',',0);
4945 while(c < configList.length())
4948 name = configList.substr(i,c-i);
4950 c = configList.find(
',',i);
4951 if(c == std::string::npos)
4953 __SUP_SS__ <<
"Incomplete Configuration-Version pair!" << std::endl;
4954 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4955 xmlOut.addTextElementToData(
"Error", ss.str());
4959 versionStr = configList.substr(i,c-i);
4961 c = configList.find(
',',i);
4967 if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
4969 alias = versionStr.substr(
4970 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
4972 __SUP_COUT__ <<
"Found alias " << name <<
" " << versionStr << __E__;
4975 if(versionAliases.find(name) != versionAliases.end() &&
4976 versionAliases[name].find(alias) != versionAliases[name].end())
4979 version = versionAliases[name][alias];
4980 __SUP_COUT__ <<
"version alias '" << alias <<
4981 "'translated to: " << version << std::endl;
4983 groupAliases[name] = alias;
4987 __SUP_SS__ <<
"version alias '" << versionStr.substr(
4988 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size()) <<
4989 "' was not found in active version aliases!" << std::endl;
4990 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4991 xmlOut.addTextElementToData(
"Error",
4997 version = ConfigurationVersion(versionStr);
4999 if(version.isTemporaryVersion())
5001 __SUP_SS__ <<
"Groups can not be created using temporary member tables. " <<
5002 "Table member '" << name <<
"' with temporary version '" << version <<
5003 "' is illegal." << std::endl;
5004 xmlOut.addTextElementToData(
"Error", ss.str());
5009 if(allCfgInfo.find(name) == allCfgInfo.end())
5011 __SUP_SS__ <<
"Groups can not be created using mock-up member tables of undefined tables. " <<
5012 "Table member '" << name <<
"' is not defined." << std::endl;
5013 xmlOut.addTextElementToData(
"Error", ss.str());
5017 if(version.isMockupVersion())
5020 ConfigurationBase* config = cfgMgr->getConfigurationByName(name);
5022 ConfigurationVersion temporaryVersion = config->createTemporaryView();
5023 __SUP_COUT__ <<
"\t\ttemporaryVersion: " << temporaryVersion << std::endl;
5027 __SUP_COUT__ <<
"Creating version from mock-up for name: " << name <<
5028 " inputVersionStr: " << versionStr << std::endl;
5031 config->getTemporaryView(temporaryVersion)->setComment(
"Auto-generated from mock-up.");
5034 version = saveModifiedVersionXML(xmlOut,cfgMgr,name,
5035 ConfigurationVersion() ,
5042 __SUP_COUT__ <<
"Using mockup version: " << version << std::endl;
5047 groupMembers[name] = version;
5050 __COUTV__(StringMacros::mapToString(groupAliases));
5052 if(!allowDuplicates)
5054 __SUP_COUT__ <<
"Checking for duplicate groups..." << std::endl;
5055 ConfigurationGroupKey foundKey =
5056 cfgMgr->findConfigurationGroup(groupName,groupMembers,groupAliases);
5058 if(!foundKey.isInvalid())
5061 xmlOut.addTextElementToData(
"ConfigurationGroupName",groupName);
5062 xmlOut.addTextElementToData(
"ConfigurationGroupKey",foundKey.toString());
5064 if(lookForEquivalent)
5066 __SUP_COUT__ <<
"Found equivalent group key (" << foundKey <<
") for " <<
5067 groupName <<
"." << std::endl;
5069 xmlOut.addTextElementToData(
"foundEquivalentKey",
"1");
5072 handleGetConfigurationGroupXML(xmlOut,cfgMgr,groupName,foundKey);
5077 __SUP_COUT__ <<
"Treating duplicate group as error." << std::endl;
5078 __SUP_SS__ << (
"Failed to create configuration group: " + groupName +
5079 ". It is a duplicate of an existing group key (" + foundKey.toString() +
")");
5080 __SUP_COUT_ERR__ << ss.str() << std::endl;
5081 xmlOut.addTextElementToData(
"Error",ss.str());
5086 __SUP_COUT__ <<
"Check for duplicate groups complete." << std::endl;
5092 cfgMgr->loadMemberMap(groupMembers);
5094 std::string accumulateErrors =
"";
5095 for(
auto& groupMemberPair:groupMembers)
5097 ConfigurationView* cfgViewPtr =
5098 cfgMgr->getConfigurationByName(groupMemberPair.first)->getViewP();
5099 if(cfgViewPtr->getDataColumnSize() !=
5100 cfgViewPtr->getNumberOfColumns() ||
5101 cfgViewPtr->getSourceColumnMismatch() != 0)
5103 __SUP_SS__ <<
"\n\nThere were errors found in loading a member table " <<
5104 groupMemberPair.first <<
":v" << cfgViewPtr->getVersion() <<
5105 ". Please see the details below:\n\n" <<
5106 "The source column size was found to be " <<
5107 cfgViewPtr->getDataColumnSize() <<
5108 ", and the current number of columns for this table is " <<
5109 cfgViewPtr->getNumberOfColumns() <<
". This resulted in a count of " <<
5110 cfgViewPtr->getSourceColumnMismatch() <<
" source column mismatches, and a count of " <<
5111 cfgViewPtr->getSourceColumnMissing() <<
" table entries missing in " <<
5112 cfgViewPtr->getNumberOfRows() <<
" row(s) of data." <<
5115 const std::set<std::string> srcColNames = cfgViewPtr->getSourceColumnNames();
5116 ss <<
"\n\nSource column names were as follows:\n";
5118 for(
auto& srcColName:srcColNames)
5119 ss <<
"\n\t" <<index++ <<
". " << srcColName;
5122 std::set<std::string> destColNames = cfgViewPtr->getColumnStorageNames();
5123 ss <<
"\n\nCurrent table column names are as follows:\n";
5125 for(
auto& destColName:destColNames)
5126 ss <<
"\n\t" << index++ <<
". " << destColName;
5129 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5130 xmlOut.addTextElementToData(
"Error", ss.str());
5135 catch(std::runtime_error& e)
5137 __SUP_SS__ <<
"Failed to create config group: " << groupName <<
5138 ".\nThere were problems loading the chosen members:\n\n" <<
5139 e.what() << std::endl;
5140 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5141 xmlOut.addTextElementToData(
"Error", ss.str());
5146 __SUP_SS__ <<
"Failed to create config group: " << groupName << std::endl;
5147 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5148 xmlOut.addTextElementToData(
"Error", ss.str());
5153 std::string accumulateTreeErrs;
5154 cfgMgr->getChildren(&groupMembers,&accumulateTreeErrs);
5155 if(accumulateTreeErrs !=
"" )
5157 __SUP_COUT_WARN__ <<
"\n" << accumulateTreeErrs << std::endl;
5160 xmlOut.addTextElementToData(
"TreeErrors",
5161 accumulateTreeErrs);
5166 ConfigurationGroupKey newKey;
5169 __COUT__ <<
"Saving new group..." << __E__;
5170 newKey = cfgMgr->saveNewConfigurationGroup(groupName,groupMembers,
5171 groupComment,&groupAliases);
5173 catch(std::runtime_error& e)
5175 __SUP_COUT_ERR__ <<
"Failed to create config group: " << groupName << std::endl;
5176 __SUP_COUT_ERR__ <<
"\n\n" << e.what() << std::endl;
5177 xmlOut.addTextElementToData(
"Error",
"Failed to create configuration group: " + groupName +
5178 ".\n\n" + e.what());
5183 __SUP_COUT_ERR__ <<
"Failed to create config group: " << groupName << std::endl;
5184 xmlOut.addTextElementToData(
"Error",
"Failed to create configuration group: " + groupName);
5189 __COUT__ <<
"Loading new group..." << __E__;
5190 handleGetConfigurationGroupXML(xmlOut,cfgMgr,groupName,newKey);
5192 catch(std::runtime_error& e)
5194 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
5195 xmlOut.addTextElementToData(
"Error",
"Error saving group! " + std::string(e.what()));
5199 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
5200 xmlOut.addTextElementToData(
"Error",
"Error saving group! ");
5209 void ConfigurationGUISupervisor::handleDeleteConfigurationInfoXML(HttpXmlDocument& xmlOut,
5210 ConfigurationManagerRW* cfgMgr,
5211 std::string& configName)
5214 if ( 0 == rename( (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT).c_str() ,
5215 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused").c_str() ) )
5216 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
5217 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused")) << std::endl;
5220 __SUP_COUT_ERR__ << (
"Error renaming file to " +
5221 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused")) << std::endl;
5223 xmlOut.addTextElementToData(
"Error",
5224 (
"Error renaming Table Info File to " +
5225 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused")));
5230 cfgMgr->getAllConfigurationInfo(
true);
5240 void ConfigurationGUISupervisor::handleSaveConfigurationInfoXML(HttpXmlDocument& xmlOut,
5241 ConfigurationManagerRW* cfgMgr,
5242 std::string& configName,
const std::string& data,
5243 const std::string& tableDescription,
const std::string& columnChoicesCSV,
5244 bool allowOverwrite)
5248 std::string capsName;
5251 capsName = ConfigurationBase::convertToCaps(configName,
true);
5253 catch(std::runtime_error& e)
5255 xmlOut.addTextElementToData(
"Error",e.what());
5261 FILE* fp = fopen((CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT).c_str(),
"r");
5265 xmlOut.addTextElementToData(
"ConfigurationName",
5267 xmlOut.addTextElementToData(
"OverwriteError",
5269 xmlOut.addTextElementToData(
"Error",
5270 "File already exists! ('" +
5271 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT) +
5277 __SUP_COUT__ <<
"capsName=" << capsName << std::endl;
5278 __SUP_COUT__ <<
"configName=" << configName << std::endl;
5279 __SUP_COUT__ <<
"tableDescription=" << tableDescription << std::endl;
5280 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << std::endl;
5283 std::stringstream outss;
5285 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
5286 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"ConfigurationInfo.xsd\">\n";
5287 outss <<
"\t\t<CONFIGURATION Name=\"" <<
5288 configName <<
"\">\n";
5289 outss <<
"\t\t\t<VIEW Name=\"" << capsName <<
5290 "\" Type=\"File,Database,DatabaseTest\" Description=\"" <<
5291 tableDescription <<
"\">\n";
5296 int j = data.find(
',',i);
5297 int k = data.find(
';',i);
5300 std::istringstream columnChoicesISS(columnChoicesCSV);
5301 std::string columnChoicesString;
5302 std::string columnType;
5304 while(k != (
int)(std::string::npos))
5307 columnType = data.substr(i,j-i);
5308 outss <<
"\t\t\t\t<COLUMN Type=\"";
5309 outss << columnType;
5312 j = data.find(
',',i);
5315 outss <<
"\" \t Name=\"";
5316 capsName = data.substr(i,j-i);
5318 outss <<
"\" \t StorageName=\"";
5322 outss << ConfigurationBase::convertToCaps(capsName);
5324 catch(std::runtime_error& e)
5326 xmlOut.addTextElementToData(
"Error", std::string(
"For column name '") +
5327 data.substr(i,j-i) +
"' - " + e.what());
5332 j = data.find(
',',i);
5335 outss <<
"\" \t DataType=\"";
5336 outss << data.substr(i,k-i);
5340 getline(columnChoicesISS, columnChoicesString,
';');
5342 outss <<
"\" \t DataChoices=\"";
5343 outss << columnChoicesString;
5350 j = data.find(
',',i);
5351 k = data.find(
';',i);
5354 outss <<
"\t\t\t</VIEW>\n";
5355 outss <<
"\t\t</CONFIGURATION>\n";
5356 outss <<
"\t</ROOT>\n";
5358 __SUP_COUT__ << outss.str() << std::endl;
5360 FILE* fp = fopen((CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT).c_str(),
"w");
5363 xmlOut.addTextElementToData(
"Error",
"Failed to open destination Configuration Info file:" +
5364 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT));
5368 fprintf(fp,
"%s",outss.str().c_str());
5373 std::string accumulatedErrors =
"";
5374 cfgMgr->getAllConfigurationInfo(
true,&accumulatedErrors,configName);
5377 if(accumulatedErrors !=
"")
5379 __SUP_SS__ << (
"The new version of the '" + configName +
"' table column info was saved, however errors were detected reading back the configuration '" +
5381 "' after the save attempt:\n\n" + accumulatedErrors) << std::endl;
5383 __SUP_COUT_ERR__ << ss.str() << std::endl;
5384 xmlOut.addTextElementToData(
"Error", ss.str());
5395 if ( 0 == rename( (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT).c_str() ,
5396 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused").c_str() ) )
5397 __SUP_COUT_INFO__ << (
"File successfully renamed: " +
5398 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused")) << std::endl;
5402 __SUP_COUT_ERR__ << (
"Error renaming file to " +
5403 (CONFIG_INFO_PATH + configName + CONFIG_INFO_EXT +
".unused")) << std::endl;
5406 cfgMgr->getAllConfigurationInfo(
true);
5412 handleGetConfigurationXML(xmlOut,cfgMgr,configName,ConfigurationVersion());
5416 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo();
5419 __SUP_COUT_INFO__ <<
"Looking for errors in all configuration column info..." << std::endl;
5420 for(
const auto& cfgInfo: allCfgInfo)
5424 cfgMgr->getConfigurationByName(cfgInfo.first)->getMockupViewP()->init();
5426 catch(std::runtime_error& e)
5428 __SUP_COUT_WARN__ <<
"\n\n##############################################\n" <<
5429 "Error identified in column info of configuration '" <<
5430 cfgInfo.first <<
"':\n\n" <<
5431 e.what() <<
"\n\n" << std::endl;
5444 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(HttpXmlDocument& xmlOut,
5445 ConfigurationManagerRW* cfgMgr,
const std::string& groupAlias,
5446 const std::string& groupName, ConfigurationGroupKey groupKey,
5447 const std::string& author)
5450 cfgMgr->loadConfigurationBackbone();
5451 std::map<std::string, ConfigurationVersion> activeVersions = cfgMgr->getActiveVersions();
5453 const std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_CONFIG_NAME;
5454 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
5456 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!" << std::endl;
5457 xmlOut.addTextElementToData(
"Error", ss.str());
5462 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
5463 for(
auto& memberName: backboneMembers)
5465 __SUP_COUT__ <<
"activeVersions[\"" << memberName <<
"\"]=" <<
5466 activeVersions[memberName] << std::endl;
5468 xmlOut.addTextElementToData(
"oldBackboneName",
5470 xmlOut.addTextElementToData(
"oldBackboneVersion",
5471 activeVersions[memberName].toString());
5478 ConfigurationBase* config = cfgMgr->getConfigurationByName(groupAliasesTableName);
5479 ConfigurationVersion originalVersion = activeVersions[groupAliasesTableName];
5480 ConfigurationVersion temporaryVersion = config->createTemporaryView(originalVersion);
5482 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << std::endl;
5483 bool isDifferent =
false;
5487 ConfigurationView* configView = config->getTemporaryView(temporaryVersion);
5489 unsigned int col = configView->findCol(
"GroupKeyAlias");
5494 unsigned int row = -1;
5496 try { row = configView->findRow(col,groupAlias); }
5498 if(row == (
unsigned int)-1)
5501 row = configView->addRow();
5504 col = configView->findCol(
"CommentDescription");
5505 configView->setValue(
"This Group Alias was automatically setup by the server." ,
5507 col = configView->findCol(
"GroupKeyAlias");
5508 configView->setValue(groupAlias, row, col);
5511 __SUP_COUT__ <<
"\t\t row: " << row << std::endl;
5513 col = configView->findCol(
"GroupName");
5515 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs " <<
5516 configView->getDataView()[row][col] << std::endl;
5517 if(groupName != configView->getDataView()[row][col])
5519 configView->setValue(groupName, row, col);
5523 col = configView->findCol(
"GroupKey");
5524 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs " <<
5525 configView->getDataView()[row][col] << std::endl;
5526 if(groupKey.toString() != configView->getDataView()[row][col])
5528 configView->setValue(groupKey.toString(), row, col);
5534 configView->setValue(author, row, configView->findCol(
"Author"));
5535 configView->setValue(time(0), row, configView->findCol(
"RecordInsertionTime"));
5540 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << std::endl;
5543 config->eraseView(temporaryVersion);
5548 ConfigurationVersion newAssignedVersion;
5551 __SUP_COUT__ <<
"\t\t**************************** Save as new table version" << std::endl;
5558 newAssignedVersion = saveModifiedVersionXML(xmlOut,cfgMgr,
5559 config->getConfigurationName(),originalVersion,
false ,
5560 config,temporaryVersion,
false ,
true );
5565 __SUP_COUT__ <<
"\t\t**************************** Using the existing table version" << std::endl;
5568 config->eraseView(temporaryVersion);
5569 newAssignedVersion = activeVersions[groupAliasesTableName];
5571 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
5572 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
5575 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << std::endl;
5579 catch(std::runtime_error& e)
5581 __SUP_COUT_ERR__ <<
"Error detected!\n\n " << e.what() << std::endl;
5582 xmlOut.addTextElementToData(
"Error",
"Error saving new Group Alias view!\n " +
5583 std::string(e.what()));
5587 __SUP_COUT_ERR__ <<
"Error detected!\n\n "<< std::endl;
5588 xmlOut.addTextElementToData(
"Error",
"Error saving new Group Alias view! ");
5599 void ConfigurationGUISupervisor::handleSetVersionAliasInBackboneXML(HttpXmlDocument& xmlOut,
5600 ConfigurationManagerRW* cfgMgr,
5601 const std::string& versionAlias,
5602 const std::string& configName, ConfigurationVersion version,
const std::string& author)
5605 cfgMgr->loadConfigurationBackbone();
5606 std::map<std::string, ConfigurationVersion> activeVersions = cfgMgr->getActiveVersions();
5608 const std::string versionAliasesTableName = ConfigurationManager::VERSION_ALIASES_CONFIG_NAME;
5609 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
5611 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!" << std::endl;
5612 xmlOut.addTextElementToData(
"Error", ss.str());
5617 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
5618 for(
auto& memberName: backboneMembers)
5620 __SUP_COUT__ <<
"activeVersions[\"" << memberName <<
"\"]=" <<
5621 activeVersions[memberName] << std::endl;
5623 xmlOut.addTextElementToData(
"oldBackboneName",
5625 xmlOut.addTextElementToData(
"oldBackboneVersion",
5626 activeVersions[memberName].toString());
5633 ConfigurationBase* config = cfgMgr->getConfigurationByName(versionAliasesTableName);
5634 ConfigurationVersion originalVersion = activeVersions[versionAliasesTableName];
5635 ConfigurationVersion temporaryVersion = config->createTemporaryView(originalVersion);
5637 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << std::endl;
5639 bool isDifferent =
false;
5643 ConfigurationView* configView = config->getTemporaryView(temporaryVersion);
5646 unsigned int col2 = configView->findCol(
"VersionAlias");
5647 unsigned int col3 = configView->findCol(
"ConfigurationName");
5652 unsigned int row = -1;
5656 unsigned int tmpRow = -1;
5659 tmpRow = configView->findRow(col3,configName,tmpRow+1);
5660 }
while (configView->getDataView()[tmpRow][col2] != versionAlias);
5665 if(row == (
unsigned int)-1)
5668 row = configView->addRow();
5671 col = configView->findCol(
"CommentDescription");
5672 configView->setValue(std::string(
"Entry was added by server in ") +
5673 "ConfigurationGUISupervisor::setVersionAliasInActiveBackbone()." ,
5676 col = configView->findCol(
"VersionAliasUID");
5677 configView->setValue(configName.substr(0,configName.rfind(
"Configuration")) +
5678 versionAlias, row, col);
5680 configView->setValue(versionAlias, row, col2);
5681 configView->setValue(configName, row, col3);
5684 __SUP_COUT__ <<
"\t\t row: " << row << std::endl;
5686 col = configView->findCol(
"Version");
5687 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs " <<
5688 configView->getDataView()[row][col] << std::endl;
5689 if(version.toString() != configView->getDataView()[row][col])
5691 configView->setValue(version.toString(), row, col);
5697 configView->setValue(author, row, configView->findCol(
"Author"));
5698 configView->setValue(time(0), row, configView->findCol(
"RecordInsertionTime"));
5703 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << std::endl;
5706 config->eraseView(temporaryVersion);
5710 ConfigurationVersion newAssignedVersion;
5713 __SUP_COUT__ <<
"\t\t**************************** Save as new table version" << std::endl;
5718 newAssignedVersion = saveModifiedVersionXML(xmlOut,cfgMgr,
5719 config->getConfigurationName(),originalVersion,
false ,
5720 config,temporaryVersion,
false ,
true );
5724 __SUP_COUT__ <<
"\t\t**************************** Using existing table version" << std::endl;
5727 config->eraseView(temporaryVersion);
5728 newAssignedVersion = activeVersions[versionAliasesTableName];
5730 xmlOut.addTextElementToData(
"savedAlias", versionAliasesTableName);
5731 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
5734 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << std::endl;
5736 catch(std::runtime_error& e)
5738 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
5739 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view!\n " +
5740 std::string(e.what()));
5744 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
5745 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view! ");
5754 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(HttpXmlDocument& xmlOut,
5755 ConfigurationManagerRW* cfgMgr,
5756 const std::string& versionAlias,
5757 const std::string& groupName, ConfigurationGroupKey groupKey,
const std::string& author)
5760 cfgMgr->loadConfigurationBackbone();
5761 std::map<std::string, ConfigurationVersion> activeVersions = cfgMgr->getActiveVersions();
5763 const std::string versionAliasesTableName = ConfigurationManager::VERSION_ALIASES_CONFIG_NAME;
5764 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
5766 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!" << std::endl;
5767 xmlOut.addTextElementToData(
"Error", ss.str());
5772 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
5773 for(
auto& memberName: backboneMembers)
5775 __SUP_COUT__ <<
"activeVersions[\"" << memberName <<
"\"]=" <<
5776 activeVersions[memberName] << std::endl;
5778 xmlOut.addTextElementToData(
"oldBackboneName",
5780 xmlOut.addTextElementToData(
"oldBackboneVersion",
5781 activeVersions[memberName].toString());
5789 ConfigurationBase* config = cfgMgr->getConfigurationByName(versionAliasesTableName);
5790 ConfigurationVersion temporaryVersion = config->
5791 createTemporaryView(activeVersions[versionAliasesTableName]);
5793 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << std::endl;
5795 ConfigurationView* configView = config->getTemporaryView(temporaryVersion);
5799 bool isDifferent =
false;
5802 std::map<std::string , ConfigurationVersion > memberMap;
5805 cfgMgr->loadConfigurationGroup(groupName,groupKey,
5806 false ,&memberMap,0,0,0,0,0,
5811 xmlOut.addTextElementToData(
"Error",
"Configuration group \"" +
5812 ConfigurationGroupKey::getFullGroupString(groupName,groupKey) +
5813 "\" can not be retrieved!");
5818 unsigned int col2 = configView->findCol(
"VersionAlias");
5819 unsigned int col3 = configView->findCol(
"ConfigurationName");
5821 for(
auto& memberPair:memberMap)
5823 bool thisMemberIsDifferent =
false;
5824 unsigned int row = -1;
5826 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
5827 "_v" << memberPair.second << std::endl;
5832 unsigned int tmpRow = -1;
5835 tmpRow = configView->findRow(col3,memberPair.first,tmpRow+1);
5836 __SUP_COUT__ << configView->getDataView()[tmpRow][col2] << std::endl;
5837 }
while (configView->getDataView()[tmpRow][col2] != versionAlias);
5842 if(row == (
unsigned int)-1)
5844 thisMemberIsDifferent =
true;
5845 row = configView->addRow();
5848 col = configView->findCol(
"CommentDescription");
5849 configView->setValue(std::string(
"Entry was added by server in ") +
5850 "ConfigurationGUISupervisor::setVersionAliasInActiveBackbone()." ,
5853 col = configView->getColUID();
5854 configView->setValue(memberPair.first.substr(
5855 0,memberPair.first.rfind(
"Configuration")) +
5856 versionAlias, row, col);
5858 configView->setValue(versionAlias, row, col2);
5859 configView->setValue(memberPair.first, row, col3);
5862 __SUP_COUT__ <<
"\t\t row: " << row << std::endl;
5864 col = configView->findCol(
"Version");
5865 __SUP_COUT__ <<
"\t\t col: " << col << std::endl;
5866 __SUP_COUT__ <<
"\t\t version: " << memberPair.second <<
" vs " <<
5867 configView->getDataView()[row][col] << std::endl;
5868 if(memberPair.second.toString() !=
5869 configView->getDataView()[row][col])
5871 configView->setValue(memberPair.second.toString(), row, col);
5872 thisMemberIsDifferent =
true;
5875 if(thisMemberIsDifferent)
5877 configView->setValue(author, row, configView->findCol(
"Author"));
5878 configView->setValue(time(0), row, configView->findCol(
"RecordInsertionTime"));
5881 if(thisMemberIsDifferent)
5887 ConfigurationVersion newAssignedVersion;
5890 __SUP_COUT__ <<
"\t\t**************************** Save as new table version" << std::endl;
5892 newAssignedVersion =
5893 cfgMgr->saveNewConfiguration(versionAliasesTableName,temporaryVersion);
5897 __SUP_COUT__ <<
"\t\t**************************** Using existing table version" << std::endl;
5900 config->eraseView(temporaryVersion);
5901 newAssignedVersion = activeVersions[versionAliasesTableName];
5904 xmlOut.addTextElementToData(
"savedAlias", versionAliasesTableName);
5905 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
5906 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << std::endl;
5908 catch(std::runtime_error& e)
5910 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << std::endl;
5911 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view!\n " +
5912 std::string(e.what()));
5916 __SUP_COUT__ <<
"Error detected!\n\n "<< std::endl;
5917 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view! ");
5931 void ConfigurationGUISupervisor::handleGroupAliasesXML(HttpXmlDocument& xmlOut,
5932 ConfigurationManagerRW* cfgMgr)
5934 cfgMgr->loadConfigurationBackbone();
5935 std::map<std::string, ConfigurationVersion> activeVersions = cfgMgr->getActiveVersions();
5937 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_CONFIG_NAME;
5938 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
5940 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! " <<
5941 groupAliasesTableName <<
" is a required member of the Backbone configuration group." <<
5942 "\n\nLikely you need to activate a valid Backbone group." <<
5944 xmlOut.addTextElementToData(
"Error", ss.str());
5947 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName <<
"\"]=" <<
5948 activeVersions[groupAliasesTableName] << std::endl;
5949 xmlOut.addTextElementToData(
"GroupAliasesConfigurationName",
5950 groupAliasesTableName);
5951 xmlOut.addTextElementToData(
"GroupAliasesConfigurationVersion",
5952 activeVersions[groupAliasesTableName].toString());
5954 std::vector<std::pair<std::string,ConfigurationTree> > aliasNodePairs =
5955 cfgMgr->getNode(groupAliasesTableName).getChildren();
5957 std::string groupName, groupKey, groupComment, groupType;
5958 for(
auto& aliasNodePair:aliasNodePairs)
5960 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
5961 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
5963 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
5964 xmlOut.addTextElementToData(
"GroupName", groupName);
5965 xmlOut.addTextElementToData(
"GroupKey", groupKey);
5966 xmlOut.addTextElementToData(
"AliasComment",
5967 aliasNodePair.second.getNode(
"CommentDescription").getValueAsString());
5971 groupType =
"Invalid";
5974 cfgMgr->loadConfigurationGroup(groupName,ConfigurationGroupKey(groupKey),
5975 0,0,0,0,&groupComment,0,0,
5980 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"(" << groupKey <<
5981 ")' to extract group comment and type." << std::endl;
5983 xmlOut.addTextElementToData(
"GroupComment", groupComment);
5984 xmlOut.addTextElementToData(
"GroupType", groupType);
5999 void ConfigurationGUISupervisor::handleVersionAliasesXML(HttpXmlDocument& xmlOut,
6000 ConfigurationManagerRW* cfgMgr)
6002 cfgMgr->loadConfigurationBackbone();
6003 std::map<std::string, ConfigurationVersion> activeVersions = cfgMgr->getActiveVersions();
6005 std::string versionAliasesTableName = ConfigurationManager::VERSION_ALIASES_CONFIG_NAME;
6006 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6008 __SUP_SS__ <<
"Active version of VersionAliases missing!" <<
6009 "Make sure you have a valid active Backbone Group." << std::endl;
6010 xmlOut.addTextElementToData(
"Error", ss.str());
6013 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName <<
"\"]=" <<
6014 activeVersions[versionAliasesTableName] << std::endl;
6015 xmlOut.addTextElementToData(
"VersionAliasesVersion",
6016 activeVersions[versionAliasesTableName].toString());
6018 std::vector<std::pair<std::string,ConfigurationTree> > aliasNodePairs =
6019 cfgMgr->getNode(versionAliasesTableName).getChildren();
6021 for(
auto& aliasNodePair:aliasNodePairs)
6025 xmlOut.addTextElementToData(
"VersionAlias",
6026 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
6027 xmlOut.addTextElementToData(
"ConfigurationName",
6028 aliasNodePair.second.getNode(
"ConfigurationName").getValueAsString());
6029 xmlOut.addTextElementToData(
"Version",
6030 aliasNodePair.second.getNode(
"Version").getValueAsString());
6031 xmlOut.addTextElementToData(
"Comment",
6032 aliasNodePair.second.getNode(
"CommentDescription").getValueAsString());
6042 void ConfigurationGUISupervisor::handleGetConfigurationGroupTypeXML(HttpXmlDocument& xmlOut,
6043 ConfigurationManagerRW* cfgMgr,
6044 const std::string& configList)
6047 std::map<std::string , ConfigurationVersion > memberMap;
6048 std::string name, versionStr;
6049 auto c = configList.find(
',',0);
6051 while(c < configList.length())
6054 name = configList.substr(i,c-i);
6056 c = configList.find(
',',i);
6057 if(c == std::string::npos)
6059 __SUP_SS__ <<
"Incomplete Configuration-Version pair!" << std::endl;
6060 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6061 xmlOut.addTextElementToData(
"Error", ss.str());
6065 versionStr = configList.substr(i,c-i);
6067 c = configList.find(
',',i);
6069 memberMap[name] = ConfigurationVersion(versionStr);
6072 std::string groupTypeString =
"";
6077 groupTypeString = cfgMgr->getTypeNameOfGroup(memberMap);
6078 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupTypeString);
6080 catch(std::runtime_error& e)
6082 __SUP_SS__ <<
"Configuration group has invalid type! " << e.what() << std::endl;
6083 __SUP_COUT__ <<
"\n" << ss.str();
6084 groupTypeString =
"Invalid";
6085 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupTypeString);
6089 __SUP_SS__ <<
"Configuration group has invalid type! " << std::endl;
6090 __SUP_COUT__ <<
"\n" << ss.str();
6091 groupTypeString =
"Invalid";
6092 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupTypeString);
6112 void ConfigurationGUISupervisor::handleConfigurationGroupsXML(HttpXmlDocument& xmlOut,
6113 ConfigurationManagerRW* cfgMgr,
bool returnMembers)
6115 DOMElement* parentEl;
6119 if(!cfgMgr->getAllGroupInfo().size())
6121 __SUP_COUT__ <<
"Cache is empty? Attempting to regenerate." << __E__;
6122 cfgMgr->getAllConfigurationInfo(
true );
6125 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
6144 ConfigurationGroupKey groupKey;
6145 std::string groupName;
6146 std::string groupString, groupTypeString, groupComment, groupCreationTime, groupAuthor;
6147 for(
auto& groupInfo:allGroupInfo)
6149 groupName = groupInfo.first;
6150 if(groupInfo.second.keys_.size() == 0)
6152 __SUP_COUT__ <<
"Group name '" << groupName <<
"' found, but no keys so ignoring." << __E__;
6156 groupKey = *(groupInfo.second.keys_.rbegin());
6158 xmlOut.addTextElementToData(
"ConfigurationGroupName", groupName);
6159 xmlOut.addTextElementToData(
"ConfigurationGroupKey", groupKey.toString());
6162 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupInfo.second.latestKeyGroupTypeString_);
6163 xmlOut.addTextElementToData(
"ConfigurationGroupComment", groupInfo.second.latestKeyGroupComment_);
6164 xmlOut.addTextElementToData(
"ConfigurationGroupAuthor", groupInfo.second.latestKeyGroupAuthor_);
6165 xmlOut.addTextElementToData(
"ConfigurationGroupCreationTime", groupInfo.second.latestKeyGroupCreationTime_);
6178 parentEl = xmlOut.addTextElementToData(
"ConfigurationGroupMembers",
"");
6213 for(
auto& memberPair:groupInfo.second.latestKeyMemberMap_)
6216 xmlOut.addTextElementToParent(
"MemberName", memberPair.first, parentEl);
6217 xmlOut.addTextElementToParent(
"MemberVersion", memberPair.second.toString(), parentEl);
6224 for(
auto& keyInSet: groupInfo.second.keys_)
6226 if(keyInSet == groupKey)
continue;
6227 xmlOut.addTextElementToData(
"ConfigurationGroupName", groupName);
6228 xmlOut.addTextElementToData(
"ConfigurationGroupKey", keyInSet.toString());
6231 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupInfo.second.latestKeyGroupTypeString_);
6232 xmlOut.addTextElementToData(
"ConfigurationGroupComment", groupInfo.second.latestKeyGroupComment_);
6233 xmlOut.addTextElementToData(
"ConfigurationGroupAuthor", groupInfo.second.latestKeyGroupAuthor_);
6234 xmlOut.addTextElementToData(
"ConfigurationGroupCreationTime", groupInfo.second.latestKeyGroupCreationTime_);
6238 xmlOut.addTextElementToData(
"ConfigurationGroupMembers",
"");
6241 bool loadingHistoricalInfo =
false;
6242 if(loadingHistoricalInfo)
6249 cfgMgr->loadConfigurationGroup(groupName,keyInSet,
6250 0,0,0,0,&groupComment,0,0,
6251 true ,&groupTypeString);
6255 groupTypeString =
"Invalid";
6256 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"(" << keyInSet <<
6257 ")' to extract group comment and type." << std::endl;
6260 xmlOut.addTextElementToData(
"ConfigurationGroupType", groupTypeString);
6261 xmlOut.addTextElementToData(
"ConfigurationGroupComment", groupComment);
6262 xmlOut.addTextElementToData(
"ConfigurationGroupAuthor", groupAuthor);
6263 xmlOut.addTextElementToData(
"ConfigurationGroupCreationTime", groupCreationTime);
6284 void ConfigurationGUISupervisor::handleConfigurationsXML(HttpXmlDocument& xmlOut,
6285 ConfigurationManagerRW* cfgMgr,
6286 bool allowIllegalColumns)
6288 DOMElement* parentEl;
6290 std::string accumulatedErrors =
"";
6291 const std::map<std::string, ConfigurationInfo>& allCfgInfo = cfgMgr->getAllConfigurationInfo(
6292 allowIllegalColumns,allowIllegalColumns?&accumulatedErrors:0);
6293 std::map<std::string, ConfigurationInfo>::const_iterator it = allCfgInfo.begin();
6295 __SUP_COUT__ <<
"# of configuration tables found: " << allCfgInfo.size() << std::endl;
6297 std::map<std::string,std::map<std::string,ConfigurationVersion> > versionAliases =
6298 cfgMgr->getVersionAliases();
6300 __SUP_COUT__ <<
"# of configuration tables w/aliases: " << versionAliases.size() << std::endl;
6303 while(it != allCfgInfo.end())
6311 xmlOut.addTextElementToData(
"ConfigurationName", it->first);
6312 parentEl = xmlOut.addTextElementToData(
"ConfigurationVersions",
"");
6315 if(versionAliases.find(it->first) != versionAliases.end())
6316 for (
auto& aliasVersion:versionAliases[it->first])
6317 if(it->second.versions_.find(aliasVersion.second) !=
6318 it->second.versions_.end())
6320 xmlOut.addTextElementToParent(
"Version",
6321 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
6336 for (
auto& version:it->second.versions_)
6337 if(!version.isScratchVersion())
6338 xmlOut.addTextElementToParent(
"Version", version.toString(), parentEl);
6343 if(accumulatedErrors !=
"")
6344 xmlOut.addTextElementToData(
"Error", std::string(
"Column errors were allowed for this request, ") +
6345 "but please note the following errors:\n" + accumulatedErrors);
6351 void ConfigurationGUISupervisor::testXDAQContext()
6356 __SUP_COUT__ <<
"Attempting test activation of the context group." << std::endl;
6357 ConfigurationManager cfgMgr;
6361 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring." << std::endl;
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)