/*############################################################################## Copyright (C) 2011 HPCC Systems. All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ############################################################################## */ #pragma warning (disable : 4786) #include "WsDeployService.hpp" #include "WsDeployEngine.hpp" #include "jwrapper.hpp" #include "daclient.hpp" #include "dadfs.hpp" #include "jencrypt.hpp" #include "build-config.h" #ifdef _WINDOWS #include #define strlwr _strlwr #endif #define STANDARD_CONFIG_BACKUPDIR CONFIG_DIR"/backup" #define STANDARD_CONFIG_SOURCEDIR CONFIG_DIR #define STANDARD_CONFIG_BUILDSETFILE "buildset.xml" #define STANDARD_CONFIG_CONFIGXML_DIR "/componentfiles/configxml/" #define DEFAULT_DIRECTORIES "\ \ \ \ \ \ \ \ \ \ \ " #include using namespace std; typedef vector IPropertyTreePtrArray; bool CCloudTaskThread::s_abort = false; bool supportedInEEOnly() { throw MakeStringException(-1, "This operation is supported in Enterprise and above editions only. Please contact HPCC Systems at http://www.hpccsystems.com/contactus"); } void substituteParameters(const IPropertyTree* pEnv, const char *xpath, IPropertyTree* pNode, StringBuffer& result) { const char* xpathorig = xpath; while (*xpath) { if (*xpath=='$') { if (strncmp(xpath, "$build", 6)==0) { result.append('\"'); result.append(pNode->queryProp(XML_ATTR_BUILD)); result.append('\"'); xpath+=6; } else if (strncmp(xpath, "$model", 6)==0) { result.append("Model"); const char *datamodel = pNode->queryProp("@dataModel"); if (datamodel) { result.append("[@name=\""); result.append(datamodel); result.append("\"]"); } xpath+=6; } else if (strncmp(xpath, "$parentmodel", 12)==0) { // Find the model that I am in - HACK result.append( "Model"); const char *datamodel = NULL; const IPropertyTree *root = pEnv; IPropertyTree *current = pNode; Owned allModels = root->getElements("Data/Model"); ForEach(*allModels) { IPropertyTree &model = allModels->query(); Owned children = model.getElements("*"); ForEach(*children) { if (&children->query()==current) { datamodel = model.queryProp("@name"); break; } } if (datamodel) break; } if (datamodel) { result.append("[@name=\""); result.append(datamodel); result.append("\"]"); } xpath+=12; } else if (strncmp(xpath, "$./*", 4) == 0) { String xpath2(xpath+4); StringBuffer sb(xpath2); String xpath3(xpathorig); String* pstr = xpath3.substring(xpath3.lastIndexOf('[', xpath3.indexOf("$./*")) + 1, xpath3.indexOf("$./*")); int pos1 = xpath2.indexOf(']'); int pos2 = xpath2.lastIndexOf('/'); if (pos1 != -1 && pos2 != -1) sb.clear().append(xpath2.substring(0, pos2)->toCharArray()); else if (pos1 != -1) sb.clear().append(xpath2.substring(0, pos1)->toCharArray()); Owned elems = pNode->getElements(sb.str()); if (pos2 != -1) sb.clear().append(xpath2.substring(pos2+ 1, pos1)->toCharArray()); ForEach(*elems) { IPropertyTree* elem = &elems->query(); result.append('\"'); result.append(elem->queryProp(sb.str())); result.append("\"").append("][").append(pstr->toCharArray()); } result.setLength(result.length() - pstr->length() - 2); delete pstr; xpath+=pos1+4; } else if (strncmp(xpath, "$./", 3) == 0) { String xpath2(xpath+3); StringBuffer sb(xpath2); int pos = xpath2.indexOf(']'); if (pos != -1) sb.clear().append(xpath2.substring(0, pos)->toCharArray()); result.append('\"'); result.append(pNode->queryProp(sb.str())); result.append('\"'); xpath+=pos+3; //skip past $./ and xpath2 } else result.append(*xpath++); } else result.append(*xpath++); } } void expandRange(IPropertyTree* pComputers) { if (pComputers && pComputers->hasProp("@hasrange")) { if(!strcmp(pComputers->queryProp("@hasrange"), "true")) { Owned rangeIter = pComputers->getElements("ComputerRange"); ForEach(*rangeIter) { StringArray ipList; IPropertyTree* pEachComp = &rangeIter->query(); formIPList(pEachComp->queryProp(XML_ATTR_NETADDRESS), ipList); for(unsigned i = 0 ; i < ipList.ordinality(); i++) { IPropertyTree* pElem = pComputers->addPropTree(XML_TAG_COMPUTER,createPTree()); pElem->addProp(XML_ATTR_NETADDRESS,ipList.item(i)); } pComputers->removeTree(pEachComp); } pComputers->removeProp("@hasrange"); } } } CConfigHelper::CConfigHelper() { } CConfigHelper::~CConfigHelper() { } void CConfigHelper::init(const IPropertyTree *cfg, const char* esp_name) { StringBuffer xpath; xpath.clear().appendf("%s/%s/%s[%s='%s']/%s",XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS, XML_TAG_ESPSERVICE, XML_ATTR_NAME, esp_name, XML_TAG_LOCALCONFFILE); m_strConfFile = cfg->queryProp(xpath.str()); xpath.clear().appendf("%s/%s/%s[%s='%s']/%s",XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS, XML_TAG_ESPSERVICE, XML_ATTR_NAME, esp_name, XML_TAG_LOCALENVCONFFILE); m_strEnvConfFile = cfg->queryProp(xpath.str()); if (m_strConfFile.length() > 0 && m_strEnvConfFile.length() > 0) { Owned pParams = createProperties(m_strConfFile); Owned pEnvParams = createProperties(m_strEnvConfFile); m_strConfigXMLDir = pEnvParams->queryProp(TAG_PATH); if ( m_strConfigXMLDir.length() == 0) { m_strConfigXMLDir = INSTALL_DIR; } m_strBuildSetFileName = pParams->queryProp(TAG_BUILDSET); m_strBuildSetFilePath.append(m_strConfigXMLDir).append(STANDARD_CONFIG_CONFIGXML_DIR).append( m_strBuildSetFileName.length() > 0 ? m_strBuildSetFileName : STANDARD_CONFIG_BUILDSETFILE); m_pDefBldSet.set(createPTreeFromXMLFile(m_strBuildSetFilePath.str())); } } bool CConfigHelper::isInBuildSet(const char* comp_process_name, const char* comp_name) const { StringBuffer xpath; xpath.appendf("./%s/%s/%s[%s=\"%s\"][%s=\"%s\"]", XML_TAG_PROGRAMS, XML_TAG_BUILD, XML_TAG_BUILDSET, XML_ATTR_PROCESS_NAME, comp_process_name, XML_ATTR_NAME, comp_name); if (strcmp(XML_TAG_DIRECTORIES,comp_name) != 0 && m_pDefBldSet->queryPropTree(xpath.str()) == NULL) { return false; } else { return true; } } CWsDeployExCE::~CWsDeployExCE() { m_pCfg.clear(); closeEnvironment(); closedownClientProcess(); HashIterator iter(m_fileInfos); ForEach(iter) { IMapping &cur = iter.query(); CWsDeployFileInfo* pInfo = m_fileInfos.mapToValue(&cur); pInfo->Release(); } m_fileInfos.kill(); } IPropertyTree* CWsDeployFileInfo::getEnvTree(IEspContext &context, IConstWsDeployReqInfo *reqInfo) { StringBuffer sbName, sbUserIp; if (reqInfo) sbName.clear().append(reqInfo->getUserId()); context.getPeer(sbUserIp); if (m_userWithLock.length() && !strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()) && m_Environment != NULL) return &m_Environment->getPTree(); else return &m_constEnvRdOnly->getPTree(); } void CWsDeployFileInfo::activeUserNotResponding() { m_activeUserNotResp = true; } void CWsDeployExCE::init(IPropertyTree *cfg, const char *process, const char *service) { if (m_lastStarted.isNull()) m_lastStarted.setNow(); if (m_pCfg.get() == NULL) m_pCfg.setown(createPTreeFromIPT(cfg)); if (m_process.length() == 0) m_process.append(process); if (m_service.length() == 0) m_service.append(service); m_bCloud = false; StringBuffer xpath; m_envFile.clear(); m_configHelper.init(cfg,service); xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvConfFile", service); const char* tmp = cfg->queryProp(xpath.str()); if (tmp && *tmp) { Owned pParams = createProperties(tmp); m_sourceDir.clear().append(pParams->queryProp("sourcedir")); if (!m_sourceDir.length()) m_sourceDir.clear().append(STANDARD_CONFIG_SOURCEDIR); m_backupDir.clear().append(m_sourceDir).append(PATHSEPSTR"backup"); } if (m_backupDir.length() == 0) m_backupDir.clear().append(STANDARD_CONFIG_BACKUPDIR); if (!m_sourceDir.length()) m_sourceDir.clear().append(STANDARD_CONFIG_SOURCEDIR); xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvFile", service); const char* pEnvFile = cfg->queryProp(xpath.str()); if (pEnvFile && *pEnvFile) { CWsDeployFileInfo* fi = m_fileInfos.getValue(pEnvFile); StringBuffer sb; if (!fi) { synchronized block(m_mutexSrv); StringBuffer filePath(pEnvFile); if (strstr(pEnvFile, m_sourceDir.str()) != pEnvFile) { filePath.clear().append(m_sourceDir); filePath.append(PATHSEPCHAR); filePath.append(pEnvFile); } fi = new CWsDeployFileInfo(this, filePath.str(), m_bCloud); const char* psz = strrchr(pEnvFile, PATHSEPCHAR); if (!psz) psz = strrchr(pEnvFile, PATHSEPCHAR == '\\' ? '/' : '\\'); if (!psz) sb.append(pEnvFile); else sb.append(psz + 1); m_fileInfos.setValue(sb.str(), fi); } try { fi->initFileInfo(false); } catch (IException* e) { m_fileInfos.remove(sb.str()); delete fi; e->Release(); } m_envFile.append(pEnvFile); } } bool CWsDeployFileInfo::navMenuEvent(IEspContext &context, IEspNavMenuEventRequest &req, IEspNavMenuEventResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), false); const char* cmd = req.getCmd(); const char* xmlArg = req.getXmlArgs(); if (!cmd || !*cmd) throw ::MakeStringException(-1, "Invalid command specified!"); if (!strcmp(cmd, "LockEnvironment")) { StringBuffer sbName, sbUserIp; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str())) throw MakeStringException(-1, "Another browser window already has write access on machine '%s'. Please use that window.", sbUserIp.str()); } else if (strcmp(cmd, "SaveEnvironmentAs")) checkForRefresh(context, &req.getReqInfo(), true); if (!stricmp(cmd, "Deploy")) { /* xmlArg for is of the form: There are one or more attributes and modules marked as @selected so enumerate these selected nodes and produce xml of the form: //deploy all instances //deploy selected instances only */ Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree(XML_TAG_SOFTWARE); Owned pDeploy = createPTree("Deploy"); IPropertyTree* pComponents = pDeploy->addPropTree("Components", createPTree()); if (pEnvSoftware) { Owned pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); IPropertyTree* pSoftwareFolder = pSrcTree->queryPropTree("Folder[@name='Environment']/Folder[@name='Software']"); if (pSoftwareFolder) { bool bSelected = pSoftwareFolder->getPropBool("@selected", false); if (bSelected) { Owned iComp = pEnvSoftware->getElements("*", iptiter_sort ); ForEach(*iComp) addDeployableComponentAndInstances(pEnvRoot, &iComp->query(), pComponents, NULL, NULL); } else { Owned iFolder = pSoftwareFolder->getElements( "*" ); ForEach (*iFolder) { IPropertyTree* pFolder = &iFolder->query(); bool bSelected = pFolder->getPropBool("@selected", false); const char* szFolderName = pFolder->queryProp(XML_ATTR_NAME); if (strstr(szFolderName, " - ") != NULL) { IPropertyTree* pCompInEnv = findComponentForFolder(pFolder, pEnvSoftware); if (pCompInEnv) addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pFolder, NULL); } else if (!strcmp(szFolderName, "ECL Servers")) { Owned iSubFolder = pFolder->getElements( "*" ); ForEach (*iSubFolder) { IPropertyTree* pSubFolder = &iSubFolder->query(); IPropertyTree* pCompInEnv = findComponentForFolder(pSubFolder, pEnvSoftware); if (pCompInEnv) addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pSubFolder, NULL); } } else { //this folder bundles multiple components and has name like "ESP Servers" // if (bSelected) { //if selected, deploy all its components like deploy all ESP servers // const char* params = pFolder->queryProp("@params"); if (params) { // pFolder's @params has string of the form: "comp=EspProcess" // Owned pParams = createProperties(); pParams->loadProps(params); const char* comp = pParams->queryProp("comp"); if (comp && *comp) { Owned iComp = pEnvSoftware->getElements(comp); ForEach(*iComp) addDeployableComponentAndInstances(pEnvRoot, &iComp->query(), pComponents, NULL, szFolderName); } } } else { //deploy only selected components under this folder // Owned iFolder = pFolder->getElements("*[@selected='true']"); ForEach(*iFolder) { IPropertyTree* pFolder = &iFolder->query(); IPropertyTree* pCompInEnv = findComponentForFolder(pFolder, pEnvSoftware); if (pCompInEnv) addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pFolder, szFolderName); } } } } }//software folder is not selected }//pSoftwareFolder }//pEnvSoftware StringBuffer xml; toXML(pDeploy, xml, false); resp.setComponent( "WsDeploy" ); resp.setCommand ( "Deploy" ); resp.setXmlArgs( xml.str() ); }//deploy else if (!stricmp(cmd, "Dependencies")) { /* xmlArg for is of the form: There are one or more attributes and modules marked as @selected so enumerate these selected nodes and produce xml of the form: //deploy all instances //deploy selected instances only */ Owned pDeploy = createPTree("Deploy"); IPropertyTree* pComponents = pDeploy->addPropTree("Components", createPTree()); if (xmlArg && *xmlArg) { Owned pSrcTree = createPTreeFromXMLString( xmlArg); IPropertyTree* pComputersFolder = pSrcTree->queryPropTree("Folder[@name='Environment']/Folder[@name='Hardware']/Folder[@name='Computers']"); if (pComputersFolder) { Owned iLink = pComputersFolder->getElements( "Link" ); ForEach (*iLink) { IPropertyTree* pLink = &iLink->query(); const bool bSelected = pLink->getPropBool("@selected", false); const char* szComputerName = pLink->queryProp(XML_ATTR_NAME); //this folder bundles multiple components and has name like "ESP Servers" // if (bSelected) { //deploy all its components like deploy all ESP servers //addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pFolder, szFolderName); } } }//pSoftwareFolder }//pEnvSoftware StringBuffer xml; toXML(pDeploy, xml, false); resp.setComponent( "WsDeploy" ); resp.setCommand ( "Deploy" ); resp.setXmlArgs( xml.str() ); }//dependencies else if (!stricmp(cmd, "LockEnvironment")) { StringBuffer xml; try { if (m_userWithLock.length() == 0 || m_activeUserNotResp) { StringBuffer sbName, sbUserIp; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if (m_pFile.get() && m_pFile->isReadOnly()) { xml.appendf("Write access to the Environment cannot be provided as %s is Read Only.", m_envFile.str()); resp.setXmlArgs(xml.str()); return true; } if (m_bCloud) { StringBuffer sbMsg; Owned pComputers = createPTreeFromXMLString(xmlArg); CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_UNLOCK_ENV, sbName.str(), "8015", pComputers); bool ret = lockCloud.start(sbMsg); if (!ret || sbMsg.length()) { xml.appendf("Write access to the Environment cannot be provided. Reason(s):\n%s", sbMsg.str()); resp.setXmlArgs(xml.str()); return true; } else if (pComputers && pComputers->numChildren()) m_lockedNodesBeforeEnv.set(pComputers); } StringBuffer sb; if (m_userWithLock.length() == 0) sb.append(sbName).append(sbUserIp); else { sb.append(m_userWithLock).append(m_userIp); m_userWithLock.clear(); m_userIp.clear(); m_Environment.clear(); m_activeUserNotResp = false; } CClientAliveThread* th = m_keepAliveHTable.getValue(sb.str()); if (th) { th->Release(); m_keepAliveHTable.remove(sb.str()); } StringBuffer sbxml; if (m_pFileIO.get()) { Owned pTree = createPTree(*m_pFileIO); toXML(pTree, sbxml); } else toXML(&m_constEnvRdOnly->getPTree(), sbxml); Owned factory = getEnvironmentFactory(); m_Environment.setown(factory->loadLocalEnvironment(sbxml.str())); m_userWithLock.clear().append(req.getReqInfo().getUserId()); context.getPeer(m_userIp.clear()); Owned pEnvRoot = &m_Environment->getPTree(); unsigned timeout = pEnvRoot->getPropInt(XML_TAG_ENVSETTINGS"/brokenconntimeout", 60); th = new CClientAliveThread(this, timeout * 60 * 1000); m_keepAliveHTable.setValue(sb.str(), th); th->init(); StringBuffer tmp; m_lastSaved.getString(tmp); resp.setLastSaved(tmp.str()); resp.setComponent( "WsDeploy" ); resp.setCommand ( "LockEnvironment" ); } else { StringBuffer sbName, sbUserIp; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if (strcmp(sbName.str(), m_userWithLock.str()) || strcmp(sbUserIp.str(), m_userIp.str())) { xml.appendf("Write access to the Environment cannot be provided as it is currently being used on machine %s.", m_userIp.str()); resp.setXmlArgs(xml.str()); } } } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); if (m_envFile.length()) { char achHost[128] = ""; const char* p = strstr(sErrMsg.str(), "\n\n"); if (p && *(p+=2)) { const char* q = strchr(p, ':'); if (q) { const int len = q-p; strncpy(achHost, p, len); achHost[len] = '\0'; } } //resolve hostname for this IP address unsigned int addr = inet_addr(achHost); struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); if (hp) { strcpy(achHost, hp->h_name); //strlwr(achHost); } StringBuffer sMsg; sMsg.appendf("Error accessing the environment definition"); if (achHost[0]) sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost); else sMsg.append(":\n\n").append(sErrMsg); throw MakeStringException(0, "%s", sMsg.str()); } else { StringBuffer sMsg; sMsg.append("Error locking environment. ").append(sErrMsg.str()); throw MakeStringException(-1, "%s", sMsg.str()); } } } else if (!stricmp(cmd, "UnlockEnvironment")) { StringBuffer xml; try { StringBuffer sbUser, sbUserIp, errMsg; context.getUserID(sbUser); sbUser.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if (!stricmp(m_userWithLock.str(), sbUser.str()) && !stricmp(sbUserIp.str(), m_userIp.str())) { Owned pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); IPropertyTree* pSaveEnv = pSrcTree->queryPropTree("SaveEnv[@flag='true']"); StringBuffer sbErrMsg; if (pSaveEnv) { StringBuffer sb; m_skipEnvUpdateFromNotification = true; saveEnvironment(&context, &req.getReqInfo(), sb); if (sb.length()) sbErrMsg.appendf("%s", sb.str()); } unlockEnvironment(&context, &req.getReqInfo(), xmlArg, sbErrMsg, pSaveEnv != NULL); if (sbErrMsg.length()) { resp.setXmlArgs(sbErrMsg.str()); return true; } m_skipEnvUpdateFromNotification = false; StringBuffer tmp; m_lastSaved.getString(tmp); resp.setLastSaved(tmp.str()); resp.setComponent( "WsDeploy" ); resp.setCommand ( "UnlockEnvironment" ); } else { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setComponent( "WsDeploy" ); resp.setCommand ( "UnlockEnvironment" ); resp.setXmlArgs( xml.str() ); } } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); if (m_envFile.length() == 0) { char achHost[128] = ""; const char* p = strstr(sErrMsg.str(), "\n\n"); if (p && *(p+=2)) { const char* q = strchr(p, ':'); if (q) { const int len = q-p; strncpy(achHost, p, len); achHost[len] = '\0'; } } //resolve hostname for this IP address unsigned int addr = inet_addr(achHost); struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); if (hp) { strcpy(achHost, hp->h_name); } StringBuffer sMsg; sMsg.appendf("The environment definition in dali server " "could not be opened for write access"); if (achHost[0]) sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost); else sMsg.append(":\n\n").append(sErrMsg); throw MakeStringException(0, "%s", sMsg.str()); } else { StringBuffer sMsg; sMsg.append("Error unlocking environment. ").append(sErrMsg.str()); throw MakeStringException(-1, "%s", sMsg.str()); } } } else if (!stricmp(cmd, "SaveEnvironment")) { StringBuffer xml; StringBuffer sbUser, sbIp, sbErrMsg; sbUser.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbIp); if (m_userWithLock.length() != 0 && m_userIp.length() != 0 && !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str()) && m_Environment != NULL) { saveEnvironment(&context, &req.getReqInfo(), sbErrMsg); if (sbErrMsg.length()) resp.setXmlArgs(sbErrMsg.str()); StringBuffer tmp; m_lastSaved.getString(tmp); resp.setLastSaved(tmp.str()); resp.setComponent( "WsDeploy" ); resp.setCommand ( "SaveEnvironment" ); } else { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setComponent( "WsDeploy" ); resp.setCommand ( "SaveEnvironment" ); resp.setXmlArgs( xml.str() ); } } else if (!stricmp(cmd, "SaveEnvironmentAs")) { StringBuffer xml; StringBuffer sbUser, sbIp; sbUser.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbIp); const char* xmlArg = req.getXmlArgs(); Owned pParamTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* envSaveAs = pParamTree->queryProp("@envSaveAs"); if (envSaveAs && *envSaveAs) { StringBuffer filePath(m_pService->getSourceDir()); StringBuffer sbErrMsg; if (filePath.charAt(filePath.length() - 1) != PATHSEPCHAR) filePath.append(PATHSEPCHAR); filePath.append(envSaveAs); if (!strcmp(filePath.str(), m_envFile.str())) { if (m_userWithLock.length() != 0 && m_userIp.length() != 0 && !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str()) && m_Environment != NULL) { saveEnvironment(&context, &req.getReqInfo(), sbErrMsg); unlockEnvironment(&context, &req.getReqInfo(), "", sbErrMsg); if (sbErrMsg.length()) { resp.setXmlArgs(sbErrMsg.str()); return true; } StringBuffer tmp; m_lastSaved.getString(tmp); resp.setLastSaved(tmp.str()); resp.setComponent("WsDeploy"); resp.setCommand ("SaveEnvironmentAs"); } else if (m_userWithLock.length() == 0 && m_userIp.length() == 0) { saveEnvironment(&context, &req.getReqInfo(), sbErrMsg, true); if (sbErrMsg.length()) resp.setXmlArgs(sbErrMsg.str()); StringBuffer tmp; m_lastSaved.getString(tmp); resp.setLastSaved(tmp.str()); resp.setComponent("WsDeploy"); resp.setCommand("SaveEnvironmentAs"); } } else { CWsDeployFileInfo* fi = m_pService->getFileInfo(envSaveAs, true); StringBuffer sbUser, sbIp, sbXml, sbErrMsg; if ((fi->isLocked(sbUser, sbIp) && m_userWithLock.length() != 0 && m_userIp.length() != 0 && !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str())) || (!fi->isLocked(sbUser, sbIp) && m_userWithLock.length() != 0 && m_userIp.length() != 0)) toXML(&m_Environment->getPTree(), sbXml); else toXML(&m_constEnvRdOnly->getPTree(), sbXml); if (fi->updateEnvironment(sbXml)) fi->saveEnvironment(NULL, &req.getReqInfo(), sbErrMsg, true); else throw MakeStringException(-1, "Environment Save as operation has failed"); if (m_userWithLock.length() != 0 && m_userIp.length() != 0) { unlockEnvironment(&context, &req.getReqInfo(), "", sbErrMsg); if (sbErrMsg.length()) { resp.setXmlArgs(sbErrMsg.str()); return true; } } if (sbErrMsg.length()) resp.setXmlArgs(sbErrMsg.str()); StringBuffer tmp; fi->getLastSaved(tmp); resp.setLastSaved(tmp.str()); resp.setComponent("WsDeploy"); resp.setCommand("SaveEnvironmentAs"); } } else throw MakeStringException(-1, "File name to save environment as cannot be empty"); } else if (!stricmp(cmd, "ValidateEnvironment")) { StringBuffer xml; StringBuffer sbUser, sbIp; sbUser.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbIp); if (m_userWithLock.length() != 0 && m_userIp.length() != 0 && !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str()) && m_Environment != NULL) { if (m_envFile.length()) validateEnv((IConstEnvironment*)m_Environment, false); resp.setComponent( "WsDeploy" ); resp.setCommand ( "ValidateEnvironment" ); } else { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setComponent( "WsDeploy" ); resp.setCommand ( "SaveEnvironment" ); resp.setXmlArgs( xml.str() ); } } else { StringBuffer url; url.append("/WsDeploy/").append(cmd).append("?form"); resp.setRedirectUrl(url.str()); } return true; }//onNavMenuEvent bool CWsDeployFileInfo::isAlphaNumeric(const char *pstr) const { RegExpr expr("[A-Za-z0-9-_]+"); return (expr.find(pstr) && expr.findlen(0) == strlen(pstr)); } bool CWsDeployFileInfo::saveSetting(IEspContext &context, IEspSaveSettingRequest &req, IEspSaveSettingResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned pEnvRoot = &m_Environment->getPTree(); IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree(XML_TAG_SOFTWARE); IPropertyTree* pEnvHardware = pEnvRoot->queryPropTree(XML_TAG_HARDWARE); Owned pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); IPropertyTree* pSoftwareFolder = pSrcTree->queryPropTree("Setting[@category='Software']"); IPropertyTree* pTopologyFolder = pSrcTree->queryPropTree("Setting[@category='Topology']"); IPropertyTree* pHardwareFolder = pSrcTree->queryPropTree("Setting[@category='Hardware']"); IPropertyTree* pEnvFolder = pSrcTree->queryPropTree("Setting[@category='Environment']"); if (pSoftwareFolder) { Owned iter = pSrcTree->getElements("Setting[@category='Software']"); ForEach (*iter) { IPropertyTree* pSetting = &iter->query(); StringBuffer decodedParams( pSetting->queryProp("@params") ); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); const char* pszAttrName = pSetting->queryProp("@attrName"); const char* rowIndex = pSetting->queryProp("@rowIndex"); const char* pszOldValue = pSetting->queryProp("@oldValue"); const char* pszNewValue = pSetting->queryProp("@newValue"); const char* pszOnChange = pSetting->queryProp("@onChange"); const char* pszViewType = pSetting->queryProp("@viewType"); StringBuffer xpath; xpath.clear().appendf("%s[@name='%s']", pszCompType, pszCompName); if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0) { if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']') xpath.appendf("/%s%s", pszSubType, pszSubTypeKey); else xpath.appendf("/%s[@name='%s']", pszSubType, pszSubTypeKey); } else if (!strcmp(pszCompType, "Topology")) xpath.appendf("[@name='%s']", pszSubTypeKey); else if (pszSubType && strlen(rowIndex) > 0) xpath.appendf("/%s[%s]", pszSubType, rowIndex); IPropertyTree* pComp = pEnvSoftware->queryPropTree(xpath.str()); if (!pComp) { //read any updates to rows that have not been posted to the tree const char* pszUpdate = NULL; const char* key = NULL; int idx = 1; StringBuffer sbUpdate; StringBuffer xpath2; while (true) { sbUpdate.clear().appendf("Update%dKey", idx); key = pParams->queryProp(sbUpdate.str()); if (!key) break; else { sbUpdate.clear().appendf("Update%dValue", idx); pszUpdate = pParams->queryProp(sbUpdate.str()); break; } idx++; } xpath2.clear().appendf("*[@name='%s']", pszCompName); Owned iter = pEnvSoftware->getElements(xpath2); ForEach (*iter) { IPropertyTree* pTmpComp = &iter->query(); const char* pProcessName = pTmpComp->queryName(); if (pProcessName && !strcmp(pProcessName, pszCompType)) { if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0) { if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']') xpath2.clear().appendf("%s%s", pszSubType, pszSubTypeKey); else xpath2.clear().appendf("%s[@name='%s']", pszSubType, pszSubTypeKey); pComp = pTmpComp->queryPropTree(xpath2.str()); if (!pComp) { if (pszUpdate && pszSubType && key) xpath2.clear().appendf("%s[@%s='%s']", pszSubType, key, pszUpdate); pComp = pTmpComp->queryPropTree(xpath2.str()); } } else if (pszSubType) { StringBuffer tmppath; tmppath.clear().appendf("%s", pszSubType); pComp = pTmpComp->queryPropTree(tmppath.str()); if (!pComp) { if (pszUpdate && key) { StringBuffer sbtmp(pszSubType); StringBuffer sb; const char* psz = strrchr(pszSubType, '/'); const char* ptmp = pszSubType; if (psz) sbtmp.clear().append(psz + 1); psz = sbtmp.str(); if (strchr(pszSubType, '[') && strchr(pszSubType, ']')) { char ch; bool copy = true; bool flag = false; while ((ch = *ptmp++) != '\0') { if (ch == '/') { flag = true; break; } else if (ch == '[') copy = false; else if (ch == ']') copy = true; else if (copy) sb.append(ch); } sb.appendf("[@%s='%s']/%s", key, pszUpdate, psz); } xpath2.clear().append(sb); } pComp = pTmpComp->queryPropTree(xpath2.str()); } if (!pComp) { if (!strcmp(pszCompName, "Directories")) tmppath.clear().append(pszCompName); else tmppath.clear().appendf("%s[@name='%s']", pszCompType, pszCompName); IPropertyTree* pTmpComp = pEnvSoftware->queryPropTree(tmppath.str()); if (!pTmpComp) continue; if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS)) tmppath.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pTmpComp->queryProp(XML_ATTR_BUILDSET)); else tmppath.clear().appendf("./Programs/Build/BuildSet[@processName=\"%s\"]", pszCompType); Owned buildSetIter = pEnvRoot->getElements(tmppath.str()); buildSetIter->first(); IPropertyTree* pBuildSet; if (buildSetIter->isValid()) pBuildSet = &buildSetIter->query(); else if (!strcmp(pszCompType, "Directories")) { pBuildSet = createPTree(XML_TAG_BUILDSET); pBuildSet->addProp(XML_ATTR_NAME, pszCompName); pBuildSet->addProp(XML_ATTR_SCHEMA, "directories.xsd"); pBuildSet->addProp(XML_ATTR_PROCESS_NAME, "Directories"); } const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); Owned pNewCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()); StringBuffer sbtmp(pszSubType); StringBuffer sb; const char* psz = strrchr(pszSubType, '/'); if (psz) sbtmp.clear().append(psz + 1); psz = sbtmp.str(); if (strchr(psz, '[') && strchr(psz, ']')) { char ch; while ((ch = *psz++) != '\0') { if (ch != '[') sb.append(ch); else break; } while ((ch = *psz++) != '\0') { if (ch == ']') break; } sb.append(psz); sbtmp.clear().append(sb); } Owned iterElems = pNewCompTree->getElements(sbtmp.str()); ForEach (*iterElems) { IPropertyTree* pElem = &iterElems->query(); if (pElem) pComp = pTmpComp->addPropTree(pszSubType, createPTreeFromIPT(pElem)); else pComp = pTmpComp->addPropTree(pszSubType, createPTree()); break; } if (!pComp) pComp = pTmpComp->addPropTree(pszSubType, createPTree()); if (pComp && !strcmp(pszAttrName, "name")) pComp->setProp(XML_ATTR_NAME, pszNewValue); } } else pComp = &iter->query(); break; } const char* pBuildSet = pTmpComp->queryProp(XML_ATTR_BUILDSET); if (pBuildSet && !strcmp(pBuildSet, pszCompType)) { if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0) { if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']') xpath2.clear().appendf("%s%s", pszSubType, pszSubTypeKey); else xpath2.clear().appendf("%s[@name='%s']", pszSubType, pszSubTypeKey); pComp = pTmpComp->queryPropTree(xpath2.str()); if (!pComp) { if (pszUpdate && pszSubType && key) xpath2.clear().appendf("%s[@%s='%s']", pszSubType, key, pszUpdate); pComp = pTmpComp->queryPropTree(xpath2.str()); } } else if (pszSubType && strlen(rowIndex) > 0) { xpath2.clear().appendf("%s[%s]", pszSubType, rowIndex); pComp = pTmpComp->queryPropTree(xpath2.str()); } else if (pszSubType) { xpath2.clear().appendf("%s", pszSubType); pComp = pTmpComp->queryPropTree(xpath2.str()); } else pComp = &iter->query(); break; } } } if (!pComp) throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", pszCompType, pszCompName); else { if (pszOnChange && !strcmp(pszOnChange, "2")) { StringBuffer xpathBSet; //get the onChange xslt and apply it. if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS)) xpathBSet.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pComp->queryProp(XML_ATTR_BUILDSET)); else xpathBSet.clear().appendf("./Programs/Build/BuildSet[@processName=\"%s\"]", pszCompType); Owned buildSetIter = pEnvRoot->getElements(xpathBSet.str()); buildSetIter->first(); IPropertyTree* pBuildSet; if (!buildSetIter->isValid()) { xpathBSet.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pszCompType); buildSetIter.setown(pEnvRoot->getElements(xpathBSet.str())); buildSetIter->first(); } if (buildSetIter->isValid()) { pBuildSet = &buildSetIter->query(); const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); StringBuffer xpathOnChg; xpathOnChg.append(".//xs:attribute[@name=\"").append(pszAttrName).append("\"]//onchange"); IPropertyTree* pAttr = pSchema->queryPropTree(xpathOnChg.str()); xpathOnChg.clear().append(".//onchange"); IPropertyTree* pOnChange = pAttr? pAttr->queryPropTree(xpathOnChg.str()) : NULL; if (pAttr) { const char* onChangeXslt = pAttr->queryProp("xslt"); if (onChangeXslt && *onChangeXslt) { StringBuffer sbAttrName("@"); sbAttrName.append(pszAttrName); pComp->setProp(sbAttrName.str(), pszNewValue); if (onChangeAttribute(pEnvRoot, m_Environment, pszAttrName, pAttr, pComp, pComp /*TBD Calc parent nodeGetParentNode()*/, 0, pszNewValue, pszOldValue, pszCompType)) { bool bRefresh = pAttr->getPropBool("refresh", true); if (bRefresh) { resp.setRefresh("true"); resp.setUpdateValue(pszNewValue); return true; } } else { pComp->setProp(sbAttrName.str(), pszOldValue); resp.setUpdateValue(pszOldValue); return true; } } } } } //perform checks if (!strcmp(pszAttrName, "name")) { ensureUniqueName(pEnvRoot, pComp, pszNewValue); if (isAlphaNumeric(pszNewValue) == false) { throw MakeStringException(-1, "Invalid Character in name '%s'.", pszNewValue); } } //Store prev settings for use further down for esp service bindings const char* sPrevDefaultPort = NULL; const char* sPrevPort = NULL; const char* sPrevResBasedn = NULL; const char* sPrevDefaultSecurePort = NULL; const char* sPrevDefaultResBasedn = NULL; if (pszSubType && !strcmp(pszSubType, XML_TAG_ESPBINDING) && (!strcmp(pszAttrName, "service") || !strcmp(pszAttrName, "protocol"))) { const char* szServiceName = xpath.clear().append("Software/EspService[@name=\""); xpath.append(pComp->queryProp(XML_ATTR_SERVICE)); xpath.append("\"]/Properties"); IPropertyTree* pPrevSvcProps = pEnvRoot->queryPropTree(xpath); if (pPrevSvcProps) { sPrevDefaultPort = pPrevSvcProps->queryProp("@defaultPort"); sPrevDefaultSecurePort= pPrevSvcProps->queryProp("@defaultSecurePort"); sPrevDefaultResBasedn = pPrevSvcProps->queryProp("@defaultResourcesBasedn"); } sPrevPort = pComp->queryProp("@port"); sPrevResBasedn = pComp->queryProp("@resourcesBasedn"); } bool isSet = false; if (pszSubType && strstr(pszSubType, "Notes") == pszSubType && !strcmp(pszAttrName, "Note")) { pComp->setProp(".", pszNewValue); isSet = true; } else if (pszCompType && !strcmp(pszCompType, XML_TAG_ESPPROCESS)) { String strXPath(xpath); if (strXPath.indexOf("CSR") != -1 || strXPath.indexOf("Certificate") != -1 || strXPath.indexOf("PrivateKey") != -1) { StringBuffer sbNewVal(pszNewValue); pEnvSoftware->setProp(xpath, sbNewVal.str()); isSet = true; } } StringBuffer encryptedText; if (!isSet) { xpath.clear().appendf("@%s", pszAttrName); if (pszViewType && *pszViewType && !strcmp(pszViewType, "password")) { encrypt(encryptedText, pszNewValue); pszNewValue = encryptedText.str(); } pComp->setProp(xpath, pszNewValue); } resp.setUpdateValue(pszNewValue); if (!strcmp(pszAttrName, "name")) { if (!pszSubType || !*pszSubType) { StringBuffer rundir; if (!getConfigurationDirectory(pEnvRoot->queryPropTree("Software/Directories"), "run", pszCompType, pszNewValue, rundir)) rundir.clear().appendf(RUNTIME_DIR"/%s", pszNewValue); Owned iterInsts = pComp->getElements(XML_TAG_INSTANCE); ForEach (*iterInsts) iterInsts->query().setProp(XML_ATTR_DIRECTORY, rundir.str()); if (!strcmp(pszCompType, XML_TAG_ROXIECLUSTER)) pComp->setProp(XML_ATTR_DIRECTORY, rundir); } StringBuffer sbold, sbnew, sbMsg; bool ret = false; if (pszSubType && !strcmp(pszSubType, "EspBinding")) { sbold.append(pszCompName).append('/').append(pszOldValue); sbnew.append(pszCompName).append('/').append(pszNewValue); ret = checkComponentReferences(pEnvRoot, pComp, sbold.str(), sbMsg, sbnew.str()); } else ret = checkComponentReferences(pEnvRoot, pComp, pszOldValue, sbMsg, pszNewValue); if (ret) resp.setRefresh("true"); } if (pszCompType && *pszCompType && pszSubType && *pszSubType && !strcmp(pszCompType, XML_TAG_ROXIECLUSTER) && !strcmp(pszSubType, XML_TAG_ROXIE_FARM) && pszAttrName && *pszAttrName) { Owned iter = pComp->getElements(XML_TAG_ROXIE_SERVER); ForEach (*iter) { IPropertyTree* pSrv = &iter->query(); const char* pszName = pSrv->queryProp(XML_ATTR_NAME); xpath.clear().appendf(XML_TAG_ROXIECLUSTER"[@name='%s']/"XML_TAG_ROXIE_SERVER"[@name='%s']/", pszCompName, pszName); IPropertyTree* pServer = pEnvSoftware->queryPropTree(xpath.str()); if (pServer) { StringBuffer sbattr("@"); sbattr.append(pszAttrName); pServer->setProp(sbattr.str(), pszNewValue); } } } //if dataDirectory for a roxie farm is being changed, also change baseDataDir for roxie if(!strcmp(pszCompType, "Directories") && !strcmp(pszSubType, "Category")) { StringBuffer sbNewValue; bool bdata = strstr(pszSubTypeKey, "[@name='data']") || strstr(pszSubTypeKey, "[@name=\"data\"]");\ bool bdata2 = strstr(pszSubTypeKey, "[@name='data2']") || strstr(pszSubTypeKey, "[@name=\"data2\"]"); bool bdata3 = strstr(pszSubTypeKey, "[@name='data3']") || strstr(pszSubTypeKey, "[@name=\"data3\"]"); if (bdata || bdata2 || bdata3) { Owned iterRoxies = pEnvSoftware->getElements("RoxieCluster"); ForEach (*iterRoxies) { IPropertyTree* pRoxie = &iterRoxies->query(); if (bdata) { getCommonDir(pEnvRoot, "data", "roxie", pRoxie->queryProp(XML_ATTR_NAME), sbNewValue.clear()); pRoxie->setProp("@baseDataDir", sbNewValue.str()); //change all farms Owned iterFarms = pRoxie->getElements(XML_TAG_ROXIE_FARM); ForEach (*iterFarms) { IPropertyTree* pTmpComp = &iterFarms->query(); if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sbNewValue.str())) pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str()); } //change all legacy Roxie servers Owned iterRoxieServers = pRoxie->getElements(XML_TAG_ROXIE_SERVER); ForEach (*iterRoxieServers) { IPropertyTree* pTmpComp = &iterRoxieServers->query(); if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sbNewValue.str())) pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str()); } //also change roxie slave primary data directory for all RoxieSlave and RoxieSlaveProcess Owned iterSlvs = pRoxie->getElements(XML_TAG_ROXIE_ONLY_SLAVE); ForEach (*iterSlvs) { IPropertyTree* pTmpComp = &iterSlvs->query(); const char* pRoxieComputer = pTmpComp->queryProp(XML_ATTR_COMPUTER); IPropertyTree* pChannel = pTmpComp->queryPropTree(XML_TAG_ROXIE_CHANNEL"[1]"); if (pChannel) { pChannel->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str()); const char* number = pChannel->queryProp("@number"); xpath.clear().appendf(XML_TAG_ROXIE_SLAVE"[@channel='%s'][@computer='%s']", number, pRoxieComputer); IPropertyTree* pSlvProc = pRoxie->queryPropTree(xpath.str()); if (pSlvProc) pSlvProc->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str()); } } } else if (bdata2 || bdata3) { getCommonDir(pEnvRoot, bdata2 ? "data2" : "data3" , "roxie", pRoxie->queryProp(XML_ATTR_NAME), sbNewValue.clear()); Owned iterSlvs = pRoxie->getElements(XML_TAG_ROXIE_ONLY_SLAVE); StringBuffer sb(XML_TAG_ROXIE_CHANNEL); sb.appendf("%s", bdata2?"[2]":"[3]"); ForEach (*iterSlvs) { IPropertyTree* pTmpComp = &iterSlvs->query(); const char* pRoxieComputer = pTmpComp->queryProp(XML_ATTR_COMPUTER); IPropertyTree* pChannel = pTmpComp->queryPropTree(sb.str()); if (pChannel) { pChannel->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str()); const char* number = pChannel->queryProp("@number"); xpath.clear().appendf(XML_TAG_ROXIE_SLAVE"[@channel='%s'][@computer='%s']", number, pRoxieComputer); IPropertyTree* pSlvProc = pRoxie->queryPropTree(xpath.str()); if (pSlvProc) pSlvProc->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str()); } } } } } } //if we are changing the eclServer field of wsattributes, set the following //extra params from that eclserver. dbPassword, dbUser, mySQL, repository if (!strcmp(pszCompType, "WsAttributes") && !strcmp(pszAttrName, "eclServer")) { xpath.clear().appendf("Software/EclServerProcess[@name='%s']", pszNewValue); IPropertyTree* pEclServer = pEnvRoot->queryPropTree(xpath.str()); if (pEclServer) { pComp->setProp("@dbPassword", pEclServer->queryProp("@dbPassword")); pComp->setProp("@dbUser", pEclServer->queryProp("@dbUser")); pComp->setProp("@mySQL", pEclServer->queryProp("@MySQL")); pComp->setProp("@repository", pEclServer->queryProp("@repository")); } } else if (!strcmp(pszCompType, "EclServerProcess") && (!strcmp(pszAttrName, "dbPassword") || !strcmp(pszAttrName, "dbUser") || !strcmp(pszAttrName, "MySQL") || !strcmp(pszAttrName, "repository"))) { xpath.clear().append("Software/EspService[@buildSet='WsAttributes']"); Owned pWsAttrsIter = pEnvRoot->getElements(xpath.str()); ForEach(*pWsAttrsIter) { IPropertyTree* wsAttr = &pWsAttrsIter->query(); if (!strcmp(wsAttr->queryProp("@eclServer"), pszCompName)) { wsAttr->setProp("@dbPassword", pComp->queryProp("@dbPassword")); wsAttr->setProp("@dbUser", pComp->queryProp("@dbUser")); wsAttr->setProp("@mySQL", pComp->queryProp("@MySQL")); wsAttr->setProp("@repository", pComp->queryProp("@repository")); } } } if (pszSubType && !strcmp(pszSubType, XML_TAG_INSTANCE) && !strcmp(pszAttrName, TAG_COMPUTER)) { xpath.clear().appendf("Hardware/Computer[@name='%s']", pszNewValue); IPropertyTree* pEnvComputer = pEnvRoot->queryPropTree(xpath); if (pEnvComputer) { const char* pszNetAddr = pEnvComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) { StringBuffer prevValue; pComp->getProp(XML_ATTR_NETADDRESS, prevValue); resp.setPrevValue(prevValue.str()); pComp->setProp(XML_ATTR_NETADDRESS, pszNetAddr); resp.setUpdateValue(pszNetAddr); resp.setUpdateAttr("netAddress"); } const char* name = pComp->queryProp(XML_ATTR_NAME); if (!name || !*name) { pComp->setProp(XML_ATTR_NAME, "s1"); StringBuffer sb; StringBuffer rundir; if (!getConfigurationDirectory(pEnvRoot->queryPropTree("Software/Directories"), "run", pszCompType, pszCompName, rundir)) sb.clear().appendf(RUNTIME_DIR"/%s", pszCompName); else sb.clear().append(rundir); pComp->setProp(XML_ATTR_DIRECTORY, sb.str()); } } } if (pszSubType && !strcmp(pszSubType, XML_TAG_ESPBINDING) && (!strcmp(pszAttrName, "service") || !strcmp(pszAttrName, "protocol"))) { bool bEspServiceChanged = !strcmp(pszAttrName, "service"); const char* szSrvName = pComp->queryProp(XML_ATTR_SERVICE); xpath.clear().append("Software/EspService[@name=\""); xpath.append(bEspServiceChanged ? pszNewValue : szSrvName ? szSrvName : ""); xpath.append("\"]/Properties"); IPropertyTree* pSvcProps = pEnvRoot->queryPropTree(xpath.str()); if (bEspServiceChanged) { IPropertyTree* pChild; while ((pChild = pComp->queryPropTree("Authenticate[1]")) != NULL) if (pChild) pComp->removeTree( pChild ); while ((pChild = pComp->queryPropTree("AuthenticateFeature[1]")) != NULL) if (pChild) pComp->removeTree( pChild ); while ((pChild = pComp->queryPropTree("AuthenticateSetting[1]")) != NULL) if (pChild) pComp->removeTree( pChild ); } if (pSvcProps) { if (bEspServiceChanged) { xpath.clear().append("./Programs/Build/BuildSet[@processName=\"EspProcess\"]"); Owned buildSetIter = pEnvRoot->getElements(xpath.str()); buildSetIter->first(); IPropertyTree* pBuildSet = &buildSetIter->query(); const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); Owned pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()); Owned i = pSvcProps->getElements("Authenticate"); ForEach(*i) { IPropertyTree* pAuthCopy = createPTreeFromIPT(&i->query()); mergeAttributes(pAuthCopy, pCompTree->queryPropTree("Authenticate")); IPropertyTree* pNewNode = pComp->addPropTree("Authenticate", pAuthCopy); } i.setown( pSvcProps->getElements("AuthenticateFeature") ); ForEach(*i) { IPropertyTree* pAuthCopy = createPTreeFromIPT(&i->query()); mergeAttributes(pAuthCopy, pCompTree->queryPropTree("AuthenticateFeature")); IPropertyTree* pNewNode = pComp->addPropTree("AuthenticateFeature", pAuthCopy); } i.setown( pSvcProps->getElements("AuthenticateSetting") ); ForEach(*i) { IPropertyTree* pAuthCopy = createPTreeFromIPT(&i->query()); mergeAttributes(pAuthCopy, pCompTree->queryPropTree("AuthenticateSetting")); IPropertyTree* pNewNode = pComp->addPropTree("AuthenticateSetting", pAuthCopy); } } const char* szProtocol = pComp->queryProp("@protocol"); bool bHttps = szProtocol && !strcmp(szProtocol, "https"); const char* szDefaultPort = pSvcProps->queryProp(bHttps ? "@defaultSecurePort" : "@defaultPort"); if (!bEspServiceChanged)//@protocol was just changed so use last one bHttps = !bHttps; const char* szPrevDefaultPort = bHttps ? sPrevDefaultSecurePort : sPrevDefaultPort; if (szDefaultPort && ((!sPrevPort || (sPrevPort && !*sPrevPort)) || (szPrevDefaultPort && !strcmp(sPrevPort, szPrevDefaultPort)))) pComp->setProp(XML_ATTR_PORT, szDefaultPort); if (bEspServiceChanged) { const char* szDefault = pSvcProps->queryProp("@defaultResourcesBasedn"); if (szDefault && ((!sPrevResBasedn || (sPrevResBasedn && !*sPrevResBasedn )) || (sPrevDefaultResBasedn && !strcmp(sPrevResBasedn, sPrevDefaultResBasedn)))) pComp->setProp("@resourcesBasedn", szDefault); } } resp.setRefresh("true"); } } resp.setIsSaved("true"); } } else if (pTopologyFolder) { Owned iter = pSrcTree->getElements("Setting[@category='Topology']"); ForEach (*iter) { IPropertyTree* pSetting = &iter->query(); StringBuffer decodedParams( pSetting->queryProp("@params") ); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); const char* pszAttrName = pSetting->queryProp("@attrName"); const char* rowIndex = pSetting->queryProp("@rowIndex"); const char* pszOldValue = pSetting->queryProp("@oldValue"); const char* pszNewValue = pSetting->queryProp("@newValue"); StringBuffer xpath_key; xpath_key.appendf("%s/%s/%s[%s='%s']", XML_TAG_SOFTWARE, XML_TAG_TOPOLOGY, XML_TAG_CLUSTER, XML_ATTR_NAME, pszNewValue); //Check to see if the cluster name is already in use IPropertyTree* pEnvCluster = pEnvRoot->queryPropTree(xpath_key); if (pEnvCluster != NULL) throw MakeStringException(-1, "Cluster - %s is already in use. Please enter a unique name for the Cluster.", pszNewValue); StringBuffer buf("Topology"); for (int i = 3; i >= 0; i--) { StringBuffer sb; sb.appendf("inner%d_name", i); const char* sbName = pParams->queryProp(sb.str()); if (sbName) { if (strstr(sbName, "EclCCServerProcess") == sbName || strstr(sbName, "EclServerProcess") == sbName || strstr(sbName, "EclAgentProcess") == sbName || strstr(sbName, "EclSchedulerProcess") == sbName) { StringBuffer sbEcl(sbName); if (strstr(sbName, " - ")) sbEcl.replaceString(" - ", "[@process='").append("']"); else if (strstr(sbName, " -")) sbEcl.replaceString(" -", "[@process='").append("']"); buf.append("/").append(sbEcl); } else if (strstr(sbName, "Cluster") == sbName) { StringBuffer sbCl(sbName); if (strstr(sbName, " - ")) sbCl.replaceString(" - ", "[@name='").append("']"); else if (strstr(sbName, " -")) sbCl.replaceString(" -", "[@name='").append("']"); buf.append("/").append(sbCl); } else if (strstr(sbName, XML_TAG_THORCLUSTER) == sbName) buf.append("/ThorCluster"); else if (strstr(sbName, XML_TAG_ROXIECLUSTER) == sbName) buf.append("/RoxieCluster"); else if (buf.str()[buf.length() - 1] != ']') buf.appendf("[@%s='%s']", sbName, pParams->queryProp(sb.replaceString("_name", "_value").str())); } } StringBuffer xpath; xpath.appendf("%s[@name='%s']", pszCompType, pszCompName); IPropertyTree* pComp = pEnvSoftware->queryPropTree(buf.str()); if (!pComp) { xpath.clear().appendf("*[@name='%s']", pszCompName); Owned iter = pEnvSoftware->getElements(xpath); ForEach (*iter) { IPropertyTree* pTmpComp = &iter->query(); const char* pBldSet = pTmpComp->queryProp(XML_ATTR_BUILDSET); if (pBldSet && !strcmp(pBldSet, pszCompType)) { pComp = &iter->query(); break; } } } if (!pComp) throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", pszCompType, pszCompName); else { xpath.clear().appendf("@%s", pszAttrName); pComp->setProp(xpath, pszNewValue); resp.setUpdateValue(pszNewValue); if (pszSubType && !strcmp(pszSubType, XML_TAG_INSTANCE) && !strcmp(pszAttrName, TAG_COMPUTER)) { xpath.clear().appendf("Hardware/Computer[@name='%s']", pszNewValue); IPropertyTree* pEnvComputer = pEnvRoot->queryPropTree(xpath); if (pEnvComputer) { const char* pszNetAddr = pEnvComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pComp->setProp(XML_ATTR_NETADDRESS, pszNetAddr); } } } resp.setIsSaved("true"); } } else if (pHardwareFolder) { Owned iter = pSrcTree->getElements("Setting[@category='Hardware']"); ForEach (*iter) { IPropertyTree* pSetting = &iter->query(); StringBuffer decodedParams( pSetting->queryProp("@params") ); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); const char* pszAttrName = pSetting->queryProp("@attrName"); const char* rowIndex = pSetting->queryProp("@rowIndex"); const char* pszOldValue = pSetting->queryProp("@oldValue"); const char* pszNewValue = pSetting->queryProp("@newValue"); //read anyupdates to rows that have not been updated const char* pszUpdate = NULL; int idx = 1; StringBuffer sbUpdate; while (true) { sbUpdate.clear().appendf("Update%dKey", idx); const char* key = pParams->queryProp(sbUpdate.str()); if (!key) break; else if (!strcmp(key, "name") || !strcmp(key, "Name")) { sbUpdate.clear().appendf("Update%dValue", idx); pszUpdate = pParams->queryProp(sbUpdate.str()); break; } idx++; } StringBuffer xpath; if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0/* && !strcmp(pszSubType, "Instance")*/) { if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']') xpath.appendf("%s%s", pszSubType, pszSubTypeKey); else xpath.clear().appendf("%s[@name='%s']", pszSubType, pszSubTypeKey); } else if (pszSubType && strlen(rowIndex) > 0/* && !strcmp(pszSubType, "Instance")*/) xpath.clear().appendf("%s[%s]", pszSubType, rowIndex); IPropertyTree* pComp = pEnvHardware->queryPropTree(xpath.str()); if (!pComp) { //check for any updates first if (pszUpdate && pszSubType) xpath.clear().appendf("%s[@name='%s']", pszSubType, pszUpdate); pComp = pEnvHardware->queryPropTree(xpath.str()); if (!pComp) { xpath.clear().appendf("*[@name='%s']", pszCompName); Owned iter = pEnvHardware->getElements(xpath); ForEach (*iter) { IPropertyTree* pTmpComp = &iter->query(); const char* pBldSet = pTmpComp->queryProp(XML_ATTR_BUILDSET); if (pBldSet && !strcmp(pBldSet, pszCompType)) { pComp = &iter->query(); break; } } } } if (!pComp) throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", pszCompType, pszCompName); else { if (!strcmp(pszAttrName, "name")) { xpath.clear().appendf("%s["XML_ATTR_NAME"='%s']", pszSubType, pszNewValue); if (pEnvHardware->queryPropTree(xpath.str())) throw MakeStringException(-1, "Another item exists with the same name '%s'! Please specify a unique name.", pszNewValue); } xpath.clear().appendf("@%s", pszAttrName); String strAttrName(pszAttrName); StringBuffer encryptedText; if (strAttrName.toLowerCase()->endsWith("password")) { encrypt(encryptedText, pszNewValue); pszNewValue = encryptedText.str(); } if (m_bCloud && !strcmp(pszAttrName, "netAddress")) { StringBuffer sb, sbMsg; { sb.clear().appendf("", pszNewValue); Owned pComputer = createPTreeFromXMLString(sb.str()); CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", pComputer); bool ret = lockCloud.start(sbMsg.clear()); if (!ret || sbMsg.length()) throw MakeStringException(-1, "Cannot set netAddress as environment lock could not be obtained. Reason(s):\n%s", sbMsg.str()); } if (pszOldValue && *pszOldValue) { sb.clear().appendf("", pszOldValue); Owned pComputer = createPTreeFromXMLString(sb.str()); CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", pComputer); bool ret = unlockCloud.start(sbMsg.clear()); if (!ret || sbMsg.length()) { //Unlock the new node. { sb.clear().appendf("", pszNewValue); Owned pComputer = createPTreeFromXMLString(sb.str()); CCloudActionHandler unlockPrevCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", pComputer); ret = unlockPrevCloud.start(sbMsg.clear()); } throw MakeStringException(-1, "Cannot set netAddress as some targets could not be unlocked. Reason(s):\n%s", sbMsg.str()); } } } pComp->setProp(xpath, pszNewValue); resp.setUpdateValue(pszNewValue); //update references if (!strcmp(pszAttrName, "name")) { if (!strcmp(pszSubType, XML_TAG_COMPUTER)) { UpdateRefAttributes(pEnvRoot, XML_TAG_SOFTWARE"//*", XML_ATTR_COMPUTER, pszOldValue, pszNewValue); UpdateRefAttributes(pEnvRoot, XML_TAG_SOFTWARE"/"XML_TAG_DALISERVERPROCESS, XML_ATTR_BACKUPCOMPUTER, pszOldValue, pszNewValue); } else if (!strcmp(pszSubType, XML_TAG_DOMAIN)) UpdateRefAttributes(pEnvRoot, XML_TAG_HARDWARE"/"XML_TAG_COMPUTER, XML_ATTR_DOMAIN, pszOldValue, pszNewValue); else if (!strcmp(pszSubType, XML_TAG_SWITCH)) UpdateRefAttributes(pEnvRoot, XML_TAG_HARDWARE"/"XML_TAG_COMPUTER, XML_ATTR_SWITCH, pszOldValue, pszNewValue); else if (!strcmp(pszSubType, XML_TAG_COMPUTERTYPE)) UpdateRefAttributes(pEnvRoot, XML_TAG_HARDWARE"/"XML_TAG_COMPUTER, XML_ATTR_COMPUTERTYPE, pszOldValue, pszNewValue); } else if (!strcmp(pszAttrName, "netAddress")) { Owned iter = pEnvRoot->getElements(XML_TAG_SOFTWARE"//*"); for (iter->first(); iter->isValid(); iter->next()) { IPropertyTree& node = iter->query(); const char* szVal = node.queryProp(XML_ATTR_COMPUTER); const char* szComputer = pComp->queryProp(XML_ATTR_NAME); if (szVal && strcmp(szVal, szComputer)==0) { if (node.hasProp(XML_ATTR_NETADDRESS)) node.setProp(XML_ATTR_NETADDRESS, pszNewValue); } } } if (pszSubType && !strcmp(pszSubType, XML_TAG_INSTANCE) && !strcmp(pszAttrName, TAG_COMPUTER)) { xpath.clear().appendf("Hardware/Computer[@name='%s']", pszNewValue); IPropertyTree* pEnvComputer = pEnvRoot->queryPropTree(xpath); if (pEnvComputer) { const char* pszNetAddr = pEnvComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pComp->setProp(XML_ATTR_NETADDRESS, pszNetAddr); } } } resp.setIsSaved("true"); } } else if (pEnvFolder) { Owned iter = pSrcTree->getElements("Setting[@category='Environment']"); ForEach (*iter) { IPropertyTree* pSetting = &iter->query(); StringBuffer decodedParams( pSetting->queryProp("@params") ); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszAttrName = pSetting->queryProp("@attrName"); const char* pszOldValue = pSetting->queryProp("@oldValue"); const char* pszNewValue = pSetting->queryProp("@newValue"); StringBuffer xpath; const char* pszUpdate = NULL; int idx = 1; StringBuffer sbUpdate; while (true) { sbUpdate.clear().appendf("Update%dKey", idx); const char* key = pParams->queryProp(sbUpdate.str()); if (!key) break; else if (!strcmp(key, "name") || !strcmp(key, "Name")) { sbUpdate.clear().appendf("Update%dValue", idx); pszUpdate = pParams->queryProp(sbUpdate.str()); break; } idx++; } const char* pszParams = NULL; idx = 2; StringBuffer sbParams; StringBuffer sb; bool flag = false; const char* isAttr = pParams->queryProp("isAttr"); while (true) { sbParams.clear().appendf("parentParams%d", idx); const char* val = pParams->queryProp(sbParams.str()); if (!val || !*val) { if (!flag) flag = true; else { if (pszUpdate) { sbParams.clear().appendf("parentParams%d", idx-2); const char* val = pParams->queryProp(sbParams.str()); String st(val); if (st.indexOf("pcName=") != -1) sbParams.clear().append("[@name='").append(*st.substring(st.indexOf("pcName=") + 7)).append("']"); String str(xpath.str()); sb.clear().append(*str.substring(0, str.indexOf(sbParams.str()))); sb.appendf("[@name='%s']", pszUpdate); xpath.clear().append(sb.str()); } break; } idx++; continue; } else { flag = false; sb.clear(); StringBuffer params(val); params.replaceString(":", "\n"); Owned pSubParams = createProperties(); pSubParams->loadProps(params.str()); sb.append(pSubParams->queryProp("pcType")); if (sb.length()) xpath.append(xpath.length()?"/":"").append(sb.str()); sb.clear().append(pSubParams->queryProp("pcName")); if (sb.length()) xpath.appendf("[@name='%s']", sb.str()); } idx++; } IPropertyTree* pComp = pEnvRoot->queryPropTree(xpath.str()); if (pComp) { sb.clear(); if (!isAttr) sb.append("@"); sb.append(pszAttrName); pComp->setProp(sb.str(), pszNewValue); resp.setUpdateValue(pszNewValue); } else throw MakeStringException(-1, "Cannot find component/attribute in environment: '%s'.", pszAttrName); } } return true; } bool CWsDeployFileInfo::getNavTreeDefn(IEspContext &context, IEspGetNavTreeDefnRequest &req, IEspGetNavTreeDefnResponse &resp) { synchronized block(m_mutex); const char* xmlArg = req.getXmlArgs(); StringBuffer sbDefn, sb; resp.setReadOnly("false"); bool doreload = true; StringBuffer decodedParams(xmlArg); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* reload = pParams->queryProp("reloadEnv"); StringBuffer sbName, sbUserIp; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()) && reload && !strcmp(reload, "true")) throw MakeStringException(-1, "Another browser window already has write access on machine '%s'. Please use that window.", sbUserIp.str()); if (m_pNavTree.get() == NULL) m_pNavTree.setown(getEnvTree(context, &req.getReqInfo())); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); generateHeadersFromEnv(pEnvRoot, sbDefn); resp.setCompDefn(sbDefn.str()); m_lastSaved.getString(sb.clear()); resp.setLastSaved(sb.str()); m_pService->getLastStarted(sb.clear()); resp.setLastStarted(sb.str()); return true; } bool CWsDeployFileInfo::lockEnvironmentForCloud(IEspContext &context, IEspLockEnvironmentForCloudRequest &req, IEspLockEnvironmentForCloudResponse &resp) { synchronized block(m_mutex); const char* user = req.getUserName(); const char* ip = req.getIp(); if (!user || !*user || !ip || !*ip) { resp.setReturnCode(0); resp.setMsg("User name or ip cannot be empty"); } StringBuffer xml; try { if (m_userWithLock.length() == 0) { StringBuffer sb; StringBuffer sbUserIp; context.getPeer(sbUserIp); m_userWithLock.clear().append(user); m_userIp.clear().append(sbUserIp); Owned pEnvRoot = &m_constEnvRdOnly->getPTree(); unsigned timeout = 60; if (pEnvRoot) timeout = pEnvRoot->getPropInt(XML_TAG_ENVSETTINGS"/brokenconntimeout", 60); if (m_cloudLockerAliveThread && m_cloudLockerAliveThread.get() != NULL) m_cloudLockerAliveThread.clear(); m_cloudLockerAliveThread.setown(new CLockerAliveThread(this, timeout * 60 * 1000, user, sbUserIp.str())); m_cloudLockerAliveThread->init(); resp.setReturnCode(1); resp.setMsg(""); } else { xml.appendf("Write access to the Environment cannot be provided as it is currently being used on machine %s.", m_userIp.str()); resp.setMsg(xml.str()); resp.setReturnCode(0); } } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); char achHost[128] = ""; const char* p = strstr(sErrMsg.str(), "\n\n"); if (p && *(p+=2)) { const char* q = strchr(p, ':'); if (q) { const int len = q-p; strncpy(achHost, p, len); achHost[len] = '\0'; } } unsigned int addr = inet_addr(achHost); struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); if (hp) strcpy(achHost, hp->h_name); StringBuffer sMsg; sMsg.appendf("Error accessing the environment definition"); if (achHost[0]) sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost); else sMsg.append(":\n\n").append(sErrMsg); //throw MakeStringException(0, sMsg); resp.setMsg(sMsg.str()); resp.setReturnCode(0); } return true; } bool CWsDeployFileInfo::unlockEnvironmentForCloud(IEspContext &context, IEspUnlockEnvironmentForCloudRequest &req, IEspUnlockEnvironmentForCloudResponse &resp) { synchronized block(m_mutex); const char* user = req.getUserName(); const char* ip = req.getIp(); const char* newEnv = req.getNewEnvXml(); if (!user || !*user || !ip || !*ip) { resp.setReturnCode(0); resp.setMsg("User name or ip cannot be empty"); } StringBuffer xml, sbMsg; int ret = 0; try { if (!stricmp(m_userWithLock.str(), user) && !stricmp(m_userIp.str(), ip)) { m_Environment.clear(); m_userWithLock.clear(); m_userIp.clear(); if (m_cloudLockerAliveThread) { m_cloudLockerAliveThread->signal(); m_cloudLockerAliveThread.clear(); } Owned pNavTree(getEnvTree(context, &req.getReqInfo())); if (!areMatchingPTrees(pNavTree, m_pNavTree)) { m_pEnvXml.clear(); m_pGraphXml.clear(); m_pNavTree.clear(); m_pNavTree.setown(getEnvTree(context, &req.getReqInfo())); } resp.setReturnCode(1); resp.setMsg(""); } else { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setReturnCode(0); resp.setMsg(xml.str()); } } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); char achHost[128] = ""; const char* p = strstr(sErrMsg.str(), "\n\n"); if (p && *(p+=2)) { const char* q = strchr(p, ':'); if (q) { const int len = q-p; strncpy(achHost, p, len); achHost[len] = '\0'; } } unsigned int addr = inet_addr(achHost); struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); if (hp) strcpy(achHost, hp->h_name); StringBuffer sMsg; sMsg.appendf("The environment definition in dali server " "could not be opened for write access"); if (achHost[0]) sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost); else sMsg.append(":\n\n").append(sErrMsg); resp.setReturnCode(0); resp.setMsg(sMsg.str()); } return true; } bool CWsDeployFileInfo::saveEnvironmentForCloud(IEspContext &context, IEspSaveEnvironmentForCloudRequest &req, IEspSaveEnvironmentForCloudResponse &resp) { synchronized block(m_mutex); const char* user = req.getUserName(); const char* ip = req.getIp(); if (!user || !*user || !ip || !*ip) { resp.setReturnCode(0); resp.setMsg("User name or ip cannot be empty"); } StringBuffer xml; try { if (m_userWithLock.length() == 0) { xml.appendf("Environment cannot be saved as it is not locked."); resp.setMsg(xml.str()); resp.setReturnCode(0); return false; } else if (stricmp(m_userWithLock.str(), user) || stricmp(m_userIp.str(), ip)) { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setReturnCode(0); resp.setMsg(xml.str()); return false; } else { const char* newEnv = req.getNewEnv(); const char* newEnvId = req.getId(); m_cloudEnvId.clear().append(newEnvId); if (!newEnv || !*newEnv) { resp.setReturnCode(0); resp.setMsg("Input xml cannot be empty"); return false; } StringBuffer sbBackup; setEnvironment(context, &req.getReqInfo(), newEnv, "SaveEnvironmentForCloud", sbBackup, false, false); m_cloudEnvBkupFileName.clear().append(sbBackup); resp.setReturnCode(1); resp.setMsg(""); } } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); resp.setMsg(sErrMsg.str()); resp.setReturnCode(0); } return true; } bool CWsDeployFileInfo::rollbackEnvironmentForCloud(IEspContext &context, IEspRollbackEnvironmentForCloudRequest &req, IEspRollbackEnvironmentForCloudResponse &resp) { synchronized block(m_mutex); const char* user = req.getUserName(); const char* ip = req.getIp(); if (!user || !*user || !ip || !*ip) { resp.setReturnCode(0); resp.setMsg("User name or ip cannot be empty"); } StringBuffer xml; try { if (m_userWithLock.length() == 0) { xml.appendf("Cannot rollback environment as it is not locked."); resp.setMsg(xml.str()); resp.setReturnCode(0); return false; } else if (stricmp(m_userWithLock.str(), user) || stricmp(m_userIp.str(), ip)) { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setReturnCode(0); resp.setMsg(xml.str()); return false; } else { const char* newEnvId = req.getId(); if (newEnvId && *newEnvId && !strcmp(newEnvId, m_cloudEnvId.str())) { StringBuffer sbBackup; Owned pFile = createIFile(m_cloudEnvBkupFileName.str()); Owned pFileIO = pFile->open(IFOreadwrite); StringBuffer sbxml; { Owned pTree = createPTree(*pFileIO); toXML(pTree, sbxml); setEnvironment(context, &req.getReqInfo(), sbxml, "RollbackEnvironmentForCloud", sbBackup); } resp.setReturnCode(1); resp.setMsg(""); } else { resp.setReturnCode(0); resp.setMsg("Cannot rollback Environment as rollback id does not match"); return false; } } } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); resp.setMsg(sErrMsg.str()); resp.setReturnCode(0); } return true; } bool CWsDeployFileInfo::notifyInitSystemSaveEnvForCloud(IEspContext &context, IEspNotifyInitSystemSaveEnvForCloudRequest &req, IEspNotifyInitSystemSaveEnvForCloudResponse &resp) { synchronized block(m_mutex); const char* user = req.getUserName(); const char* ip = req.getIp(); if (!user || !*user || !ip || !*ip) { resp.setReturnCode(0); resp.setMsg("User name or ip cannot be empty"); } StringBuffer xml; try { if (m_userWithLock.length() == 0) { xml.appendf("Cannot notify init system as the environment as it is not locked."); resp.setMsg(xml.str()); resp.setReturnCode(0); return false; } else if (stricmp(m_userWithLock.str(), user) || stricmp(m_userIp.str(), ip)) { xml.appendf("The environment has been locked on machine '%s'", m_userIp.str()); resp.setReturnCode(0); resp.setMsg(xml.str()); return false; } else { StringBuffer xpath; xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalConfFile", m_pService->getName()); const char* pConfFile = m_pService->getCfg()->queryProp(xpath.str()); if( pConfFile && *pConfFile) { Owned pParams = createProperties(pConfFile); Owned iter = pParams->getIterator(); StringBuffer prop, out, err; pParams->getProp("initSystemNotifyScript", prop); if(prop.length()) runScript(out, err, prop.str()); resp.setMsg(""); resp.setReturnCode(1); } } } catch(IException* e) { throw e; } return true; } bool CWsDeployFileInfo::getValue(IEspContext &context, IEspGetValueRequest &req, IEspGetValueResponse &resp) { synchronized block(m_mutex); StringBuffer decodedParams(req.getParams()); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCategory = pParams->queryProp("category"); const char* pszBldSet = pParams->queryProp(TAG_BUILDSET); const char* pszCompName = pParams->queryProp("compName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeName = pParams->queryProp("subTypeName"); const char* pszAttrName = pParams->queryProp("attrName"); const char* pszQueryType = pParams->queryProp("queryType"); const char* pszExcludePath = pParams->queryProp("excludePath"); const char* pszExcludeAttr = pParams->queryProp("excludeAttr"); const char* pszXpath = pParams->queryProp("xpath"); const char* pszparams = pParams->queryProp("params"); const char* pszAttrValue = pParams->queryProp("attrValue"); if (!pszCompName) pszCompName = pParams->queryProp("pcName"); if (!pszBldSet) pszBldSet = pParams->queryProp("pcType"); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); StringBuffer xpath; const char* pszValue; StringBuffer sbMultiple; if (pszQueryType && !strcmp(pszQueryType, "multiple")) { StringBuffer excludes; //prepare exclude list if (pszExcludePath && *pszExcludePath && pszExcludeAttr && *pszExcludeAttr) { if (pszCategory) xpath.clear().append(pszCategory).append("/"); xpath.append(pszExcludePath); Owned pExcludes = pEnvRoot->getElements(xpath.str()); ForEach(*pExcludes) { IPropertyTree* pExclude = &pExcludes->query(); excludes.append(":").append(pExclude->queryProp(pszExcludeAttr)).append(":"); } } xpath.clear().append(pszCategory).append("/*"); if (pszBldSet) xpath.appendf("[@buildSet='%s']", pszBldSet); if (pszCompName) xpath.appendf("[@name='%s']", pszCompName); if (pszSubType) xpath.appendf("/%s", pszSubType); Owned pComps = pEnvRoot->getElements(xpath.str()); xpath.clear().appendf("@%s", pszAttrName); ForEach(*pComps) { IPropertyTree* pComp = &pComps->query(); String excl(excludes.str()); StringBuffer sb(":"); sb.append(pComp->queryProp(xpath.str())).append(":"); if (excl.indexOf(sb.str()) == -1) sbMultiple.append(pComp->queryProp(xpath.str())).append(","); } if (sbMultiple.length()) sbMultiple.setLength(sbMultiple.length() - 1); pszValue = sbMultiple.str(); } else if (pszQueryType && !strcmp(pszQueryType, "xpathType") && pszXpath && *pszXpath) { StringBuffer sb; sbMultiple.clear().append(""); xpath.clear().appendf("./Software/%s[@name=\"%s\"]", pszBldSet, pszCompName); IPropertyTree* pNode = pEnvRoot->queryPropTree(xpath.str()); if (!pNode) { xpath.clear().appendf("./Software/*[@buildSet=\"%s\"][@name=\"%s\"]", pszBldSet, pszCompName); pNode = pEnvRoot->queryPropTree(xpath.str()); } if (pNode) { substituteParameters(pEnvRoot, pszXpath, pNode, sb); const char* szPath = sb.str(); const char* buildSet = NULL; if (!strncmp(szPath, "$process", 8)) { if (!pNode) return false; szPath += strlen("$process"); if (*szPath == '\0') { const char* szName = pNode->queryProp("@name"); if (szName && *szName) sbMultiple.append(",").append(szName); pszValue = sbMultiple.str(); return true; } szPath++; //skip over '/' } else { if (pNode && !strcmp(szPath, "Programs/Build")) buildSet = pNode->queryProp("@buildSet"); if (!pNode) pNode = pEnvRoot; } String str(szPath); Owned iter; if (str.startsWith(XML_TAG_SOFTWARE) || str.startsWith(XML_TAG_HARDWARE) || str.startsWith(XML_TAG_PROGRAMS)) iter.setown(pEnvRoot->getElements(szPath)); else iter.setown(pNode->getElements(szPath)); ForEach(*iter) { IPropertyTree* pChildNode = &iter->query(); const char* szName = pChildNode->queryProp(XML_ATTR_NAME); if (szName) { bool bAdd; if (buildSet) { StringBuffer xpath; xpath.appendf("BuildSet[@name='%s']", buildSet); bAdd = pChildNode->queryPropTree(xpath.str()) != NULL; } else bAdd = true; if (bAdd) sbMultiple.append(",").append(szName); } } } pszValue = sbMultiple.str(); } else if(pszQueryType && !strcmp(pszQueryType, "customType")) { sbMultiple.clear(); if(pszparams && *pszparams) { StringArray sArray; DelimToStringArray(pszparams, sArray, ","); for(unsigned i = 0; i < sArray.ordinality() ; i++) { if(!strcmp(sArray.item(i), "checklock")) { StringBuffer sbName, sbUserIp, msg; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if(m_userWithLock.length()) { if (strcmp(sbName.str(), m_userWithLock.str()) || strcmp(sbUserIp.str(), m_userIp.str())) sbMultiple.append(sArray.item(i)).append("=").append("Cannot get access to Wizard mode as Environment is currently being configured in wizard mode on machine ").append(m_userIp.str()); else if(!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(),m_userIp.str())) sbMultiple.append(sArray.item(i)).append("=").append("Another browser window already has write access on machine ").append(m_userIp.str()).append(".Please use that window."); else sbMultiple.append(sArray.item(i)).append("=''"); if(sbMultiple.length()) sbMultiple.append(","); } } else if(!strcmp(sArray.item(i), "lastsaved")) { StringBuffer lastSaved; m_lastSaved.getString(lastSaved); if(lastSaved.length()) sbMultiple.append(sArray.item(i)).append("=").append(lastSaved); else sbMultiple.append(sArray.item(i)).append("=''"); if(sbMultiple.length()) sbMultiple.append(","); } } } pszValue = sbMultiple.str(); } else if(pszQueryType && !strcmp(pszQueryType, "DomainsAndComputerTypes")) { xpath.clear().append(XML_TAG_HARDWARE"/"XML_TAG_DOMAIN); sbMultiple.append(""); bool flag = false; Owned pDomains = pEnvRoot->getElements(xpath.str()); ForEach(*pDomains) { IPropertyTree* pDomain = &pDomains->query(); sbMultiple.append(pDomain->queryProp(XML_ATTR_NAME)).append(","); flag = true; } if (flag) sbMultiple.setLength(sbMultiple.length() - 1); sbMultiple.append(""); flag = false; xpath.clear().append(XML_TAG_HARDWARE"/"XML_TAG_COMPUTERTYPE); sbMultiple.append(""); Owned pCTypes = pEnvRoot->getElements(xpath.str()); ForEach(*pCTypes) { IPropertyTree* pCType = &pCTypes->query(); sbMultiple.append(pCType->queryProp(XML_ATTR_NAME)).append(","); flag = true; } if (flag) sbMultiple.setLength(sbMultiple.length() - 1); sbMultiple.append(""); pszValue = sbMultiple.str(); } else { if (pszCategory) xpath.append(pszCategory); if (pszBldSet) xpath.append("/").append(pszBldSet); if (pszCompName) xpath.appendf("["XML_ATTR_NAME"='%s']", pszCompName); if (pszSubType) xpath.append("/").append(pszSubType); if (pszSubTypeName) xpath.appendf("["XML_ATTR_NAME"='%s']", pszSubTypeName); if (pszAttrName) xpath.appendf("/@%s", pszAttrName); pszValue = pEnvRoot->queryProp(xpath.str()); } resp.setReqValue(pszValue); resp.setStatus("true"); return true; } bool CWsDeployFileInfo::unlockUser(IEspContext &context, IEspUnlockUserRequest &req, IEspUnlockUserResponse &resp) { synchronized block(m_mutex); resp.setStatus("false"); StringBuffer sbName, sbUserIp; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str())) { m_userWithLock.clear(); m_userIp.clear(); resp.setStatus("true"); } else return false; return true; } bool CWsDeployFileInfo::clientAlive(IEspContext &context, IEspClientAliveRequest &req, IEspClientAliveResponse &resp) { StringBuffer sbName, sbUserIp; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); StringBuffer sb(sbName); sb.append(sbUserIp); if (getConfigChanged() == true) { updateConfigFromFile(); setConfigChanged(false); } if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str())) { CClientAliveThread* pClientAliveThread = m_keepAliveHTable.getValue(sb.str()); if (pClientAliveThread) pClientAliveThread->signal(); } m_lastSaved.getString(sb.clear()); resp.setLastSaved(sb.str()); m_pService->getLastStarted(sb.clear()); resp.setLastStarted(sb.str()); return true; } bool CWsDeployFileInfo::getEnvironment(IEspContext &context, IEspGetEnvironmentRequest &req, IEspGetEnvironmentResponse &resp) { synchronized block(m_mutex); StringBuffer sb; if (m_pFileIO.get()) { Owned pTree = createPTree(*m_pFileIO); toXML(pTree, sb); resp.setEnvXml(sb.str()); } return true; } bool CWsDeployFileInfo::setEnvironment(IEspContext &context, IEspSetEnvironmentRequest &req, IEspSetEnvironmentResponse &resp) { synchronized block(m_mutex); const char* pszEnv = req.getEnvXml(); if (!pszEnv || !*pszEnv) { resp.setReturnCode(1); resp.setErrorMsg("Input xml cannot be empty"); return false; } try { StringBuffer sbBackup; setEnvironment(context, NULL, pszEnv, "SetEnvironment", sbBackup); } catch(IException* e) { resp.setReturnCode(2); StringBuffer sb; e->errorMessage(sb); resp.setErrorMsg(sb.str()); throw e; } resp.setReturnCode(0); return true; } void CWsDeployFileInfo::setEnvironment(IEspContext &context, IConstWsDeployReqInfo *reqInfo, const char* pszEnv, const char* fnName, StringBuffer& sbBackupName, bool validate, bool updateDali) { if (!pszEnv) return; try { Owned factory = getEnvironmentFactory(); Owned constEnv = factory->loadLocalEnvironment(pszEnv); Owned pEnvRoot = createPTreeFromXMLString(pszEnv); Owned dalis = pEnvRoot->getElements("Software/DaliServerProcess/Instance"); if (validate) validateEnv(constEnv); if (updateDali && dalis && dalis->first()) updateDaliEnv(pEnvRoot); //save and write to backup StringBuffer sXML; StringBuffer tmp; StringBuffer dtStr; CDateTime dt; try { if (m_pFile.get()) { StringBuffer sb; if (!checkDirExists(m_pService->getBackupDir())) recursiveCreateDirectory(m_pService->getBackupDir()); while(true) { String strEnvFile(m_envFile); int idx = strEnvFile.lastIndexOf('/'); if (idx <= 0) idx = strEnvFile.lastIndexOf('\\'); String* tmpstr = strEnvFile.substring(idx+1); sb.clear().append(m_pService->getBackupDir()).append(PATHSEPCHAR).append(*tmpstr); delete tmpstr; dt.setNow(); tmp.clear(); dtStr.clear(); dt.getDateString(tmp, true); tmp.append("_"); dt.getTimeString(tmp, true); dtStr.append(".").append(tmp); dtStr.replaceString("-","_"); dtStr.replaceString(":","_"); String ext(sb); idx = ext.lastIndexOf(PATHSEPCHAR); if(ext.indexOf('.', idx > 0 ? idx : 0) != -1) sb.insert(ext.lastIndexOf('.'), dtStr.str()); else sb.append(dtStr.str()); if (checkFileExists(sb)) continue; else { Owned pFile(createIFile(sb.str())); copyFile(pFile, m_pFile, 0x100000); sbBackupName.clear().append(sb); break; } } } } catch(IException* e) { //ignore any attempts to create the backup e->Release(); } if (!m_pFile.get()) m_pFile.setown(createIFile(m_envFile)); m_pFileIO.clear(); m_pFileIO.setown(m_pFile->open(IFOcreaterw)); dt.setNow(); dt.getString(tmp.clear()); StringBuffer sbUserWithLock, sbUserIp; if (reqInfo) sbUserWithLock.clear().append(reqInfo->getUserId()); context.getPeer(sbUserIp); sXML.appendf("<"XML_HEADER">\n\n", fnName, sbUserWithLock.str(), sbUserIp.str(), tmp.str()); toXML(pEnvRoot, sXML, 0, XML_SortTags | XML_Format); m_pFileIO->write(0, sXML.length(), sXML.str()); m_lastSaved.clear(); m_lastSaved.setNow(); m_lastSaved.getString(tmp.clear()); initFileInfo(false); m_pNavTree.setown(getEnvTree(context, reqInfo)); //reset the readonly tree m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sXML.str())); } catch(IException* e) { throw e; } } bool CWsDeployFileInfo::displaySettings(IEspContext &context, IEspDisplaySettingsRequest &req, IEspDisplaySettingsResponse &resp) { synchronized block(m_mutex); if (m_pNavTree.get() == NULL) { resp.setComponent("Refresh"); resp.setXmlArgs(""); return false; } const char* cmd = req.getCmd(); const char* xmlArg = req.getXmlArgs(); StringBuffer sbDefn, sbViewChildNodes, sbMultiRowNodes; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); Owned pSettings = createPTree("Settings"); Owned pParamTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); IPropertyTree* pSoftwareFolder = pParamTree->queryPropTree("Component[@parent='Software']"); IPropertyTree* pBuildFolder = pParamTree->queryPropTree("Component[@name='Programs']"); IPropertyTree* pHardwareFolder = pParamTree->queryPropTree("Component[@name='Hardware']"); IPropertyTree* pBuildSet = pParamTree->queryPropTree(XML_TAG_BUILDSET); IPropertyTree* pEnvSettings = pParamTree->queryPropTree("Component[@name='EnvSettings']"); IPropertyTree* pEnvironment = pParamTree->queryPropTree("Component[@name='Environment']"); if (pSoftwareFolder) { IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree(XML_TAG_SOFTWARE); Owned iter = pParamTree->getElements("Component[@parent='Software']", iptiter_sort); ForEach (*iter) { IPropertyTree* pFolder = &iter->query(); const char* pszCompType = pFolder->queryProp("@compType"); const char* pszCompName = pFolder->queryProp(XML_ATTR_NAME); StringBuffer xpath; if (!strcmp(pszCompName, "Directories")) xpath.append(pszCompName); else xpath.appendf("%s[@name='%s']", pszCompType, pszCompName); IPropertyTree* pComp = pEnvSoftware->queryPropTree(xpath.str()); if (!pComp) continue; if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS)) xpath.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pComp->queryProp(XML_ATTR_BUILDSET)); else xpath.clear().appendf("./Programs/Build/BuildSet[@processName=\"%s\"]", pszCompType); Owned buildSetIter = pEnvRoot->getElements(xpath.str()); buildSetIter->first(); IPropertyTree* pBuildSet = NULL; if (buildSetIter->isValid()) pBuildSet = &buildSetIter->query(); else if (!strcmp(pszCompName, "Directories")) { pBuildSet = createPTree(XML_TAG_BUILDSET); pBuildSet->addProp(XML_ATTR_NAME, pszCompName); pBuildSet->addProp(XML_ATTR_SCHEMA, "directories.xsd"); pBuildSet->addProp(XML_ATTR_PROCESS_NAME, "Directories"); } if (!pBuildSet) throw MakeStringException(-1, "Cannot determine buildset for component in environment: '%s' named '%s'.", pszCompType, pszCompName); const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); if ( m_pService->m_configHelper.isInBuildSet(pszCompType,buildSetName) == false ) { throw MakeStringException(-1, "Component '%s' named '%s' not in build set. Component may be incompatible with the current version.", pszCompType, pszCompName); } StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); if (!strcmp(processName, XML_TAG_ESPSERVICE) || !strcmp(processName, XML_TAG_PLUGINPROCESS)) getDefnString(pEnvRoot, pSchema, pComp->queryProp(XML_ATTR_BUILDSET), sbDefn, sbViewChildNodes, sbMultiRowNodes); else if (!strcmp(processName, XML_TAG_TOPOLOGY)) generateHeaderForTopology(pEnvRoot, sbDefn); else getDefnString(pEnvRoot, pSchema, processName, sbDefn, sbViewChildNodes, sbMultiRowNodes); resp.setCompDefn(sbDefn.str()); resp.setViewChildNodes(sbViewChildNodes.str()); resp.setMultiRowNodes(sbMultiRowNodes.str()); StringBuffer xml; toXML(pComp, xml, false); xml.replaceString("\\","\\\\"); //add any missing parameters Owned pSrcTree = createPTreeFromXMLString(xml); Owned pNewCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName(), true, false, 0, true); if (pNewCompTree) { StringBuffer sbxml; toXML(pNewCompTree, sbxml); Owned iAttr = pNewCompTree->getAttributes(); ForEach(*iAttr) { const char* attrName = iAttr->queryName(); if (!pSrcTree->hasProp(attrName)) { pSrcTree->addProp(attrName, iAttr->queryValue()); const char* prop = "@_notInEnv"; StringBuffer sbVal; if (pSrcTree->hasProp(prop)) sbVal.append(pSrcTree->queryProp(prop)); pSrcTree->setProp(prop, sbVal.append(";").append(attrName).append(";").str()); } } //Add subelements that occur only once Owned iterElems = pNewCompTree->getElements("*"); ForEach (*iterElems) { IPropertyTree* pElem = &iterElems->query(); Owned srcElems = pSrcTree->getElements(pElem->queryName()); IPropertyTree* pSrcElem = NULL; ForEach(*srcElems) { pSrcElem = &srcElems->query(); Owned iAttrElem = pElem->getAttributes(); ForEach(*iAttrElem) { const char* attrName = iAttrElem->queryName(); if (!pSrcElem->hasProp(attrName)) { pSrcElem->addProp(attrName, iAttrElem->queryValue()); const char* prop = "@_notInEnv"; StringBuffer sbVal; if (pSrcElem->hasProp(prop)) sbVal.append(pSrcElem->queryProp(prop)); pSrcElem->setProp(prop, sbVal.append(";").append(attrName).append(";").str()); } } Owned iterSubElems = pElem->getElements("*"); ForEach (*iterSubElems) { IPropertyTree* pSubElem = &iterSubElems->query(); Owned srcSubElems = pSrcElem->getElements(pSubElem->queryName()); IPropertyTree* pSrcSubElem = NULL; ForEach(*srcSubElems) { pSrcSubElem = &srcSubElems->query(); Owned iAttrElem = pSubElem->getAttributes(); ForEach(*iAttrElem) { const char* attrName = iAttrElem->queryName(); if (!pSrcSubElem->hasProp(attrName)) pSrcSubElem->addProp(attrName, iAttrElem->queryValue()); } } if (!pSrcSubElem) pSrcSubElem = pSrcElem->addPropTree(pSubElem->queryName(), createPTreeFromIPT(pSubElem)); } } } Owned iterNotes = pSrcTree->getElements("Notes"); ForEach (*iterNotes) { IPropertyTree* pNotes = &iterNotes->query(); Owned iterNote = pNotes->getElements("Note"); ForEach (*iterNote) { IPropertyTree* pNote = &iterNote->query(); StringBuffer sbVal(pNotes->queryProp(pNote->queryName())); sbVal.replaceString("\r\n", " "); pNotes->setProp(pNote->queryName(), sbVal.str()); } } xml.clear(); toXML(pSrcTree, xml, false); } if (!strcmp(pszCompType, "Directories")) { Owned pSrcTree = createPTreeFromXMLString(xml); Owned iterCats = pSrcTree->getElements("Category"); ForEach (*iterCats) { IPropertyTree* pCat = &iterCats->query(); const char* pszName = pCat->queryProp(XML_ATTR_NAME); if (!strcmp(pszName, "lock") || !strcmp(pszName, "run") || !strcmp(pszName, "conf")) { pSrcTree->removeTree(pCat); (*iterCats).first(); } else { IPropertyTree* pOver = pCat->queryPropTree("Override[1]"); if (!pOver) pOver = pCat->addPropTree("Override", createPTree()); if (!pOver->queryProp("@component")) pOver->addProp("@component", ""); if (!pOver->queryProp("@dir")) pOver->addProp("@dir", ""); if (!pOver->queryProp("@instance")) pOver->addProp("@instance", ""); } } xml.clear(); toXML(pSrcTree, xml, false); } else if (!strcmp(pszCompType, XML_TAG_THORCLUSTER)) { Owned pSrcTree = createPTreeFromXMLString(xml); IPropertyTree* pTopoNode = pSrcTree->queryPropTree(XML_TAG_TOPOLOGY); if (!pTopoNode) { pTopoNode = pSrcTree->addPropTree(XML_TAG_TOPOLOGY, createPTree()); IPropertyTree* pMaster = pSrcTree->queryPropTree(XML_TAG_THORMASTERPROCESS); if (pMaster) { IPropertyTree* pMasterNode = createPTree(XML_TAG_NODE); pMasterNode->addProp(XML_ATTR_PROCESS, pMaster->queryProp(XML_ATTR_NAME)); pTopoNode->addPropTree(XML_TAG_NODE, pMasterNode); Owned iterSlaves = pSrcTree->getElements(XML_TAG_THORSLAVEPROCESS); ForEach (*iterSlaves) { IPropertyTree* pSlave = &iterSlaves->query(); IPropertyTree* pNode = createPTree(XML_TAG_NODE); pNode->addProp(XML_ATTR_PROCESS, pSlave->queryProp(XML_ATTR_NAME)); pMasterNode->addPropTree(XML_TAG_NODE, pNode); } } Owned iterSpares = pSrcTree->getElements(XML_TAG_THORSPAREPROCESS); ForEach (*iterSpares) { IPropertyTree* pSpare = &iterSpares->query(); IPropertyTree* pNode = createPTree(XML_TAG_NODE); pNode->addProp(XML_ATTR_PROCESS, pSpare->queryProp(XML_ATTR_NAME)); pTopoNode->addPropTree(XML_TAG_NODE, pNode); } } xpath.clear().append("Topology/Node"); Owned iterMNodes = pSrcTree->getElements(xpath.str()); ForEach (*iterMNodes) { IPropertyTree* pMasterNode = &iterMNodes->query(); const char* pszMName = pMasterNode->queryProp(XML_ATTR_PROCESS); pMasterNode->addProp("@_processId", pszMName); if (pszMName) { xpath.clear().appendf(XML_TAG_THORMASTERPROCESS"/[@name='%s']", pszMName); IPropertyTree* pMasterNodeTree = pComp->queryPropTree(xpath); //if not master, then spare if (!pMasterNodeTree) { xpath.clear().appendf(XML_TAG_THORSPAREPROCESS"/[@name='%s']", pszMName); IPropertyTree* pSpareNodeTree = pComp->queryPropTree(xpath); const char* pszComputer = pSpareNodeTree->queryProp(XML_ATTR_COMPUTER); if (pszComputer) { xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer); IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str()); const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pMasterNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr); pMasterNode->addProp(XML_ATTR_NAME, pszComputer); pMasterNode->addProp(XML_ATTR_PROCESS, "Spare"); } } else { const char* pszComputer = pMasterNodeTree->queryProp(XML_ATTR_COMPUTER); if (pszComputer) { xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer); IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str()); const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pMasterNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr); pMasterNode->addProp(XML_ATTR_NAME, pszComputer); pMasterNode->addProp(XML_ATTR_PROCESS, "Master"); } xpath.clear().appendf("Node"); Owned iterSNodes = pMasterNode->getElements(xpath); ForEach (*iterSNodes) { IPropertyTree* pSlaveNode = &iterSNodes->query(); const char* pszSName = pSlaveNode->queryProp(XML_ATTR_PROCESS); pSlaveNode->addProp("@_processId", pszSName); if (pszMName) { xpath.clear().appendf("ThorSlaveProcess/[@name='%s']", pszSName); IPropertyTree* pSlaveNodeTree = pSrcTree->queryPropTree(xpath); const char* pszComputer = pSlaveNodeTree->queryProp(XML_ATTR_COMPUTER); if (pszComputer) { xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer); IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str()); const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pSlaveNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr); pSlaveNode->addProp(XML_ATTR_NAME, pszComputer); pSlaveNode->addProp(XML_ATTR_PROCESS, "Slave"); } } } } } } xml.clear(); toXML(pSrcTree, xml, false); } else if (!strcmp(pszCompType, "RoxieCluster")) { Owned pSrcTree = createPTreeFromXMLString(xml); pNewCompTree.setown(generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName())); if (!strcmp(pszCompType, "RoxieCluster")) { xpath.clear().append("RoxieFarmProcess/RoxieServerProcess"); Owned iterRoxieServers = pSrcTree->getElements(xpath.str()); ForEach (*iterRoxieServers ) { IPropertyTree* pRoxieServer = &iterRoxieServers->query(); const char* pszComputer = pRoxieServer->queryProp(XML_ATTR_COMPUTER); if (pszComputer) { xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer); IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str()); const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pRoxieServer->addProp(XML_ATTR_NETADDRESS, pszNetAddr); } } xpath.clear().append(XML_TAG_ROXIE_ONLY_SLAVE); Owned iterSlaves = pSrcTree->getElements(xpath.str()); ForEach (*iterSlaves) { IPropertyTree* pRoxieSlave = &iterSlaves->query(); const char* pszComputer = pRoxieSlave->queryProp(XML_ATTR_COMPUTER); if (pszComputer) { xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer); IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str()); const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS); if (pszNetAddr) pRoxieSlave->addProp(XML_ATTR_NETADDRESS, pszNetAddr); } } } if (pSrcTree->hasProp("ACL")) { Owned iterACL = pSrcTree->getElements("ACL"); ForEach (*iterACL) { IPropertyTree* pAcl = &iterACL->query(); if (!pAcl->queryPropTree("Access") && pNewCompTree->queryPropTree("Access")) { IPropertyTree* pAccess = pAcl->addPropTree("Access", createPTreeFromIPT(pNewCompTree->queryPropTree("Access"))); Owned iAttrElem = pNewCompTree->queryPropTree("Access")->getAttributes(); ForEach(*iAttrElem) { const char* attrName = iAttrElem->queryName(); pAccess->setProp(attrName, ""); } } if (!pAcl->queryPropTree("BaseList") && pNewCompTree->queryPropTree("BaseList")) { IPropertyTree* pBaseList = pAcl->addPropTree("BaseList", createPTreeFromIPT(pNewCompTree->queryPropTree("BaseList"))); Owned iAttrElem = pNewCompTree->queryPropTree("BaseList")->getAttributes(); ForEach(*iAttrElem) { const char* attrName = iAttrElem->queryName(); pBaseList->setProp(attrName, ""); } } } } xml.clear(); toXML(pSrcTree, xml, false); xml.replaceString(" pTree = createPTreeFromXMLString(xml); Owned iterBindings = pTree->getElements(XML_TAG_ESPBINDING); ForEach (*iterBindings) { IPropertyTree* pBinding = &iterBindings->query(); bool flag = false; Owned iterUrl = pBinding->getElements("AuthenticateFeature"); ForEach (*iterUrl) { flag = true; break; } if (!flag) { IPropertyTree* pAuthFeature = pBinding->addPropTree( "AuthenticateFeature", createPTree() ); pAuthFeature->addProp("@authenticate", ""); pAuthFeature->addProp("@description", ""); pAuthFeature->addProp("@path", ""); pAuthFeature->addProp("@resource", ""); pAuthFeature->addProp("@service", ""); } flag = false; Owned iterFeature = pBinding->getElements("Authenticate"); ForEach (*iterFeature) { flag = true; break; } if (!flag) { IPropertyTree* pAuth = pBinding->addPropTree( "Authenticate", createPTree() ); pAuth->addProp("@access", ""); pAuth->addProp("@description", ""); pAuth->addProp("@method", ""); pAuth->addProp("@path", ""); pAuth->addProp("@resource", ""); } } Owned iterInst = pTree->getElements(XML_TAG_INSTANCE); ForEach (*iterInst) { IPropertyTree* pInst = &iterInst->query(); Owned iterNode = pInst->getElements("*"); if (iterNode->first() && iterNode->isValid()) { ForEach (*iterNode) { IPropertyTree* pNode = &iterNode->query(); if (!strcmp(pNode->queryName(), "CSR") || !strcmp(pNode->queryName(), "Certificate") || !strcmp(pNode->queryName(), "PrivateKey")) { StringBuffer sbVal(pInst->queryProp(pNode->queryName())); sbVal.replaceString("\r\n", " "); pInst->setProp(pNode->queryName(), sbVal.str()); } } } if (!pInst->hasProp("CSR")) pInst->addPropTree("CSR", createPTree()); if (!pInst->hasProp("Certificate")) pInst->addPropTree("Certificate", createPTree()); if (!pInst->hasProp("PrivateKey")) pInst->addPropTree("PrivateKey", createPTree()); } xml.clear(); toXML(pTree, xml, false); } const char* pszBldSet = pComp->queryProp(XML_ATTR_BUILDSET); if (strcmp(pszCompName, "Directories") && !pszBldSet) throw MakeStringException(-1, "Cannot determine buildset for component in environment: '%s' named '%s'.", pszCompType, pszCompName); if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS)) resp.setComponent(pszBldSet); else resp.setComponent(pszCompType); resp.setXmlArgs( xml.str() ); } } else if (pHardwareFolder) { IPropertyTree* pEnvHardware = pEnvRoot->queryPropTree(XML_TAG_HARDWARE); generateHardwareHeaders(pEnvRoot, sbDefn); resp.setCompDefn(sbDefn.str()); StringBuffer sb; Owned multiRowNodes = createPTree("multiRowNodes"); multiRowNodes->addProp("Node", "ComputerType"); multiRowNodes->addProp("Node", "Domain"); multiRowNodes->addProp("Node", "Computer"); multiRowNodes->addProp("Node", "Switch"); toXML(multiRowNodes, sb); resp.setMultiRowNodes(sb.str()); StringBuffer xml; toXML(pEnvHardware, xml, false); xml.replaceString("switch=","Switch="); //add any missing parameters Owned pSrcTree = createPTreeFromXMLString(xml); StringBuffer sbTemp; Owned pNewCompTree = createPTree(XML_TAG_HARDWARE); generateHardwareHeaders(pEnvRoot, sbTemp, false, pNewCompTree); const char* pElemNames[] = {XML_TAG_COMPUTER}; bool modified = false; for (int i = 0; i < sizeof(pElemNames)/sizeof(char*); i++) { IPropertyTree* pSrcElem = pNewCompTree->queryPropTree(pElemNames[i]); Owned iter = pSrcTree->getElements(pElemNames[i]); ForEach (*iter) { IPropertyTree* pElem = &iter->query(); Owned iAttr = pSrcElem->getAttributes(); ForEach(*iAttr) { const char* attrName = iAttr->queryName(); if (strcmp(attrName, "@state") && strcmp(attrName, "@switch") &&!pElem->hasProp(attrName)) { pElem->addProp(attrName, iAttr->queryValue()); modified = true; } } } } if (modified) { xml.clear(); toXML(pSrcTree, xml, false); } resp.setComponent(XML_TAG_HARDWARE); resp.setXmlArgs( xml.str() ); } else if (pBuildFolder) { IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS); generateBuildHeaders(pEnvRoot, true, sbDefn, false); resp.setCompDefn(sbDefn.str()); StringBuffer xml; toXML(pEnvPrograms, xml, false); xml.replaceString(" url="," path="); resp.setComponent(XML_TAG_PROGRAMS); resp.setXmlArgs( xml.str() ); } else if (pBuildSet) { generateBuildHeaders(pEnvRoot, false, sbDefn, false); resp.setCompDefn(sbDefn.str()); IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS); Owned iter = pParamTree->getElements(XML_TAG_BUILDSET); ForEach (*iter) { IPropertyTree* pFolder = &iter->query(); const char* pszBuild = pFolder->queryProp(XML_ATTR_BUILD); const char* pszBuildPath = pFolder->queryProp("@buildpath"); const char* pszBuildSet = pFolder->queryProp(XML_ATTR_NAME); const char* pszBuildSetPath = pFolder->queryProp("@path"); StringBuffer xpath; xpath.appendf("Build[@name='%s']/BuildSet[@name='%s']", pszBuild, pszBuildSet); IPropertyTree* pComp = pEnvPrograms->queryPropTree(xpath.str()); if (!pComp) throw MakeStringException(-1, "No such build and buildset in environment: '%s' named '%s'.", pszBuild, pszBuildSet); StringBuffer s; s.append("./Programs/Build[@name=\"").append(pszBuild).append("\"]"); IPropertyTree *b = pEnvRoot->queryPropTree(s.str()); IPropertyTree *bs = NULL; IPropertyTree* pParentNode = NULL; IPropertyTree* pFiles = NULL; if (b) { s.clear().append("BuildSet[@name=\"").append(pszBuildSet).append("\"]"); bs = b->queryPropTree(s.str()); StringBuffer fileName; connectBuildSet(b, bs, fileName, m_Environment); fileName.append(bs->queryProp("@installSet")); pParentNode = createPTreeFromXMLFile(fileName.str()); pFiles = pParentNode->queryPropTree("File"); } StringBuffer xml; toXML(pFiles, xml, false); resp.setComponent(XML_TAG_BUILDSET); resp.setXmlArgs( xml.str() ); } } else if (pEnvSettings) { IPropertyTree* pEnvSettings = pEnvRoot->queryPropTree("EnvSettings"); generateHeadersForEnvSettings(pEnvRoot, sbDefn); resp.setCompDefn(sbDefn.str()); StringBuffer xml; toXML(pEnvSettings, xml, false); resp.setComponent("EnvSettings"); resp.setXmlArgs( xml.str() ); } else if (pEnvironment) { generateHeadersForEnvXmlView(pEnvRoot, sbDefn); resp.setCompDefn(sbDefn.str()); StringBuffer xml; toXML(pEnvRoot, xml, false); resp.setComponent("Environment"); resp.setXmlArgs( xml.str() ); } return true; } bool CWsDeployFileInfo::startDeployment(IEspContext &context, IEspStartDeploymentRequest &req, IEspStartDeploymentResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* selComps = req.getSelComps(); CDeployOptions& depOptions = dynamic_cast(req.getOptions()); CDeployInfo depInfo("wsDeploy", "true"); StringBuffer deployResult; CWsDeployEngine depEngine(*m_pService, &context, depInfo, selComps, 2); depEngine.deploy(depOptions); Owned pDeployResult = depEngine.getDeployResult(); if (pDeployResult) { IPropertyTree* pComponents = pDeployResult->queryPropTree("SelectedComponents"); toXML(pComponents, deployResult, false); } IPropertyTree* pOptions = pDeployResult->queryPropTree("Options"); if (pOptions) toXML(pOptions, deployResult, false); resp.setStatus( depEngine.getDeployStatus() ); if (depEngine.GetErrorCount() == 0) resp.setStatus(deployResult.str()); return true; } bool CWsDeployFileInfo::getDeployableComps(IEspContext &context, IEspGetDeployableCompsRequest &req, IEspGetDeployableCompsResponse &resp) { synchronized block(m_mutex); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); Owned iter = pEnvRoot->getElements("Software/*"); Owned pDeploy = createPTree("Deploy"); ForEach(*iter) { IPropertyTree* pComponent = &iter->query(); const char* type = pComponent->queryName(); if (stricmp(type, "Topology")!=0) { const char* name = pComponent->queryProp(XML_ATTR_NAME); const char* build = pComponent->queryProp(XML_ATTR_BUILD); const char* buildSet= pComponent->queryProp(XML_ATTR_BUILDSET); StringBuffer sXPath; sXPath.appendf("Programs/Build[@name='%s']/BuildSet[@name='%s']/@deployable", build, buildSet); const char* szDeployable = pEnvRoot->queryProp(sXPath.str()); bool bDeployable = !szDeployable || (stricmp(szDeployable, "no") != 0 && stricmp(szDeployable, "false") != 0 && strcmp(szDeployable, "0") != 0); if (name && *name && build && *build && bDeployable) { IPropertyTree* pCompNode = pDeploy->addPropTree( XML_TAG_COMPONENT, createPTree() ); pCompNode->addProp(XML_ATTR_NAME, name); pCompNode->addProp(XML_ATTR_BUILD, build); pCompNode->addProp(XML_ATTR_BUILDSET, type); Owned iter = pComponent->getElements("*", iptiter_sort); ForEach(*iter) { IPropertyTree* pNode = &iter->query(); const char* nodeName = pNode->queryName(); const char* computer = pNode->queryProp(XML_ATTR_COMPUTER); const char* instanceName = pNode->queryProp(XML_ATTR_NAME); if (computer && *computer) { const char* instanceNodeNames[] = { XML_TAG_INSTANCE, XML_TAG_ROXIE_SERVER, XML_TAG_ROXIE_SLAVE }; for (UINT i=0; iaddPropTree(XML_TAG_INSTANCES, createPTree()); const char* directory = pNode->queryProp(*nodeName == 'R' ? XML_ATTR_DATADIRECTORY : XML_ATTR_DIRECTORY); if (directory && *directory) pInstanceNode->addProp(XML_ATTR_BUILD, directory); pInstanceNode->addProp("@nodeName", computer); pInstanceNode->addProp(XML_ATTR_BUILDSET, XML_TAG_INSTANCE); pInstanceNode->addProp("@instanceName", instanceName); } } } } } } } StringBuffer xml, outputXml; toXML(pDeploy, xml, false); resp.setComponent( "Deploy" ); resp.setXmlArgs( xml.str() ); return true; } bool CWsDeployFileInfo::getComputersForRoxie(IEspContext &context, IEspGetComputersForRoxieRequest &req, IEspGetComputersForRoxieResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* cmd = req.getCmd(); const char* xmlArg = req.getXmlArgs(); StringBuffer sbC, sbF; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); getComputersListWithUsage(pEnvRoot, sbC, sbF); resp.setComputers(sbC.str()); resp.setFilters( sbF.str() ); return true; } bool CWsDeployFileInfo::handleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* cmd = req.getCmd(); const char* xmlArg = req.getXmlArgs(); StringBuffer sbC, sbF; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); bool retVal = ::handleRoxieOperation(pEnvRoot, cmd, xmlArg); resp.setStatus(retVal? "true" : "false"); return true; } bool CWsDeployFileInfo::getBuildSetInfo(IEspContext &context, IEspGetBuildSetInfoRequest &req, IEspGetBuildSetInfoResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* cmd = req.getCmd(); const char* xmlArg = req.getXmlArgs(); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); Owned pSettings = createPTree("Settings"); Owned pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); IPropertyTree* pBuildSet = pSrcTree->queryPropTree(XML_TAG_BUILDSET); if (pBuildSet) { IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS); Owned iter = pSrcTree->getElements(XML_TAG_BUILDSET); ForEach (*iter) { IPropertyTree* pFolder = &iter->query(); const char* pszBuild = pFolder->queryProp(XML_ATTR_BUILD); const char* pszBuildPath = pFolder->queryProp("@buildpath"); const char* pszBuildSet = pFolder->queryProp(XML_ATTR_NAME); const char* pszBuildSetPath = pFolder->queryProp("@path"); StringBuffer xpath; xpath.appendf("Build[@name='%s']/BuildSet[@name='%s']", pszBuild, pszBuildSet); IPropertyTree* pComp = pEnvPrograms->queryPropTree(xpath.str()); if (!pComp) throw MakeStringException(-1, "No such build and buildset in environment: '%s' named '%s'.", pszBuild, pszBuildSet); StringBuffer s; s.append("./Programs/Build[@name=\"").append(pszBuild).append("\"]"); IPropertyTree *b = pEnvRoot->queryPropTree(s.str()); IPropertyTree *bs = NULL; IPropertyTree* pParentNode = NULL; IPropertyTree* pFiles = NULL; if (b) { s.clear().append("BuildSet[@name=\"").append(pszBuildSet).append("\"]"); bs = b->queryPropTree(s.str()); StringBuffer fileName; connectBuildSet(b, bs, fileName, m_Environment); fileName.append(bs->queryProp("@installSet")); pParentNode = createPTreeFromXMLFile(fileName.str()); pFiles = pParentNode->queryPropTree("File"); } StringBuffer xml; toXML(pParentNode, xml, false); resp.setComponent(XML_TAG_BUILDSET); resp.setXmlArgs( xml.str() ); } } return true; } bool CWsDeployFileInfo::importBuild(IEspContext &context, IEspImportBuildRequest &req, IEspImportBuildResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getBuildSets(); IPropertyTree* buildSets = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); IPropertyTree* buildNode = createPTree(XML_TAG_BUILD); const char* buildName = buildSets->queryProp(XML_ATTR_NAME); const char* buildUrl = buildSets->queryProp("@path"); buildNode->setProp(XML_ATTR_NAME, buildName); buildNode->setProp(XML_ATTR_URL, buildUrl); Owned iBuildSet = buildSets->getElements("*"); ForEach(*iBuildSet) { IPropertyTree* pBuildSet = &iBuildSet->query(); const char* bsName = pBuildSet->queryProp(XML_ATTR_NAME); const char* bsPath = pBuildSet->queryProp("@path"); IPropertyTree* pBuildsetNode = createPTree(); pBuildsetNode->addProp(XML_ATTR_NAME, bsName); pBuildsetNode->addProp(XML_ATTR_PATH, bsPath); pBuildsetNode->addProp(XML_ATTR_INSTALLSET, "deploy_map.xml"); try { Owned installSet = loadInstallSet(buildNode, pBuildsetNode, m_Environment); if (strcmp(installSet->queryName(), XML_TAG_INSTALLSET) == 0) { pBuildsetNode->setProp(XML_ATTR_PROCESS_NAME, installSet->queryProp(XML_ATTR_PROCESS_NAME)); pBuildsetNode->setProp(XML_ATTR_SCHEMA, installSet->queryProp(XML_ATTR_SCHEMA)); if (installSet->hasProp(XML_ATTR_NAME)) pBuildsetNode->setProp(XML_ATTR_NAME, installSet->queryProp(XML_ATTR_NAME)); const char* szDeployable = installSet->queryProp("@deployable"); if (szDeployable) pBuildsetNode->setProp("@deployable", szDeployable); IPropertyTree* pProperties = installSet->getPropTree("Properties"); if (pProperties) pBuildsetNode->addPropTree("Properties", pProperties); buildNode->addPropTree(XML_TAG_BUILDSET, pBuildsetNode); } } catch(...) { } } Owned pEnvRoot = &m_Environment->getPTree(); IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS); if (!pEnvPrograms) pEnvPrograms = pEnvRoot->addPropTree(XML_TAG_PROGRAMS, createPTree() ); pEnvPrograms->addPropTree(XML_TAG_BUILD, buildNode); resp.setStatus("true"); return true; } bool CWsDeployFileInfo::getBuildServerDirs(IEspContext &context, IEspGetBuildServerDirsRequest &req, IEspGetBuildServerDirsResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* cmd = req.getCmd(); const char* xmlArg = req.getXmlArgs(); StringBuffer sourceDir; if (xmlArg && *xmlArg) { if (xmlArg[0] != '\\' && xmlArg[1] != '\\') sourceDir.append("\\\\127.0.0.1\\"); sourceDir.append(xmlArg); } if (!strcmp(cmd, "SubDirs")) { Owned inFiles = NULL; IPropertyTree* pParentNode = createPTree("BuildServerDirs"); try { inFiles.setown(createIFile(sourceDir)); if(!inFiles->exists()) { resp.setXmlArgs("Input directory %s does not exist"); return false; } } catch(IException* e) { StringBuffer errmsg; e->errorMessage(errmsg); e->Release(); resp.setXmlArgs("Error when trying to access source directory."); return false; } Owned di = inFiles->directoryFiles(NULL, 0, true); CIArrayOf sortedfiles; StringArray dispfiles; bool bDirChosen = false; sortDirectory(sortedfiles, *di, SD_bydate, true, true); StringBuffer lastDirName; int index = 0; ForEachItemIn(idx, sortedfiles) { CDirectoryEntry *de = &sortedfiles.item(idx); if (de->isdir) { StringBuffer sb; de->modifiedTime.getString(sb); IPropertyTree* pCompNode = pParentNode->addPropTree( "Directory", createPTree() ); pCompNode->addProp(XML_ATTR_NAME, de->name.get()); pCompNode->addProp("@modified", sb.str()); } } StringBuffer xml; toXML(pParentNode, xml, false); resp.setComponent("BuildServerDirs"); resp.setXmlArgs( xml.str() ); } else { Owned inFiles = NULL; IPropertyTree* pParentNode = createPTree("BuildServerComps"); if (!strcmp(cmd, "Release")) sourceDir.append(PATHSEPCHAR).append("release"); else if (!strcmp(cmd, "Debug")) sourceDir.append(PATHSEPCHAR).append("debug"); try { inFiles.setown(createIFile(sourceDir)); if(!inFiles->exists()) { resp.setXmlArgs("Input directory %s does not exist"); return false; } } catch(IException* e) { StringBuffer errmsg; e->errorMessage(errmsg); e->Release(); resp.setXmlArgs("Error when trying to access source directory."); return false; } if(inFiles.get() != NULL && inFiles->isDirectory()) { Owned di = inFiles->directoryFiles(NULL, 0, true); bool bCompFound = false; StringBuffer dirName, compName, fileName; if(di.get()) { ForEach(*di) { IFile &file = di->query(); if (!file.isFile()) { dirName.clear(); di->getName(dirName); compName.clear().append(dirName); Owned dirFiles = NULL; StringBuffer sbPath(cmd); sbPath.toLowerCase(); dirName.clear().append(sourceDir); if(dirName.charAt(dirName.length() - 1) != PATHSEPCHAR) dirName.append(PATHSEPCHAR); dirName.append(compName); sbPath.append(PATHSEPCHAR).append(compName); fileName.clear().append(dirName).append(PATHSEPCHAR).append("deploy_map.xml"); Owned depfile(createIFile(fileName)); if(depfile->exists()) { IPropertyTree* pCompNode = pParentNode->addPropTree("Comp", createPTree() ); pCompNode->addProp(XML_ATTR_NAME, compName.str()); pCompNode->addProp("@path", sbPath.str()); } } } } StringBuffer xml; toXML(pParentNode, xml, false); resp.setComponent("BuildServerComps"); resp.setXmlArgs( xml.str() ); } } return true; } bool CWsDeployFileInfo::handleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned pComponents = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* operation = req.getOperation(); StringBuffer sbNewName; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); if (!strcmp(operation, "Add")) { Owned iterComp = pComponents->getElements("*"); ForEach(*iterComp) { IPropertyTree& pComp = iterComp->query(); const char* buildSet = pComp.queryProp(XML_ATTR_BUILDSET); StringBuffer xpath; xpath.appendf("./Programs/Build/BuildSet[@name=\"%s\"]", buildSet); Owned buildSetIter = pEnvRoot->getElements(xpath.str()); buildSetIter->first(); IPropertyTree* pBuildSet = &buildSetIter->query(); const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); xpath.clear().appendf("./Software/%s[@name='%s']", processName, buildSetName); IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName(), false); IPropertyTree* pInstTree = pCompTree->queryPropTree(XML_TAG_INSTANCE); if (pInstTree) pCompTree->removeTree(pInstTree); addComponentToEnv(pEnvRoot, buildSet, sbNewName, pCompTree); } resp.setCompName(sbNewName.str()); resp.setStatus("true"); } else if (!strcmp(operation, "Delete")) { Owned iterComp = pComponents->getElements("*"); ForEach(*iterComp) { IPropertyTree& pComp = iterComp->query(); const char* compName = pComp.queryProp(XML_ATTR_NAME); const char* compType = pComp.queryProp("@compType"); StringBuffer xpath; xpath.clear().appendf("./Software/%s[@name=\"%s\"]", compType, compName); IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str()); StringBuffer sbMsg; if(pCompTree) { bool ret = checkComponentReferences(pEnvRoot, pCompTree, compName, sbMsg); if (ret) { pEnvRoot->queryPropTree("./Software")->removeTree(pCompTree); resp.setStatus("true"); resp.setCompName(XML_TAG_SOFTWARE); } else { resp.setStatus(sbMsg.str()); resp.setCompName(compName); } } } } return true; } bool CWsDeployFileInfo::handleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* operation = req.getOperation(); const char* xmlArg = req.getXmlArgs(); Owned instances = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* buildSet = instances->queryProp(XML_ATTR_BUILDSET); const char* compName = instances->queryProp("@compName"); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); StringBuffer xpath; xpath.appendf("./Programs/Build/BuildSet[@name=\"%s\"]", buildSet); Owned buildSetIter = pEnvRoot->getElements(xpath.str()); buildSetIter->first(); IPropertyTree* pBuildSet = &buildSetIter->query(); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); StringBuffer dups, reqdComps, reqdCompNames; if (!strcmp(operation, "Add")) { StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); xpath.clear().appendf("./Software/%s[@name=\"%s\"]", processName, compName); IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str()); Owned iterInst = instances->getElements("*"); bool bAdded = false; ForEach(*iterInst) { IPropertyTree& pComputer = iterInst->query(); xpath.clear().appendf("./Hardware/Computer[@name=\"%s\"]", pComputer.queryProp(XML_ATTR_NAME)); IPropertyTree* pComputerNode = pEnvRoot->queryPropTree(xpath.str()); xpath.clear().appendf("Instance[@netAddress=\"%s\"]", pComputerNode->queryProp(XML_ATTR_NETADDRESS)); if (pCompTree->queryPropTree(xpath.str())) { dups.appendf("\n%s", pComputerNode->queryProp(XML_ATTR_NETADDRESS)); continue; } IPropertyTree* pNode = pCompTree->addPropTree(XML_TAG_INSTANCE, createPTree()); if (pSchema) { Owned iter = pSchema->getElements("xs:element/xs:complexType/xs:sequence/xs:element[@name=\"Instance\"]/xs:complexType/xs:attribute"); ForEach(*iter) { IPropertyTree &attr = iter->query(); StringBuffer attrName("@"); attrName.append(attr.queryProp(XML_ATTR_NAME)); // we try to pull @computer and @netAddress from computerNode. Others come from default values in schema (if supplied) const char *szAttrib; StringBuffer sb; if (!strcmp(attrName.str(), XML_ATTR_COMPUTER)) { szAttrib = pComputerNode->queryProp(XML_ATTR_NAME); if (!bAdded) { bAdded = true; resp.setNewName(szAttrib); } } else if (!strcmp(attrName.str(), XML_ATTR_NETADDRESS)) szAttrib = pComputerNode->queryProp(XML_ATTR_NETADDRESS); else if (!strcmp(attrName.str(), XML_ATTR_DIRECTORY)) { StringBuffer rundir; if (!getConfigurationDirectory(pEnvRoot->queryPropTree("Software/Directories"),"run",buildSet,compName,rundir)) sb.clear().appendf(RUNTIME_DIR"/%s", compName); else sb.clear().append(rundir); szAttrib = sb.str(); } else szAttrib = attr.queryProp("@default"); pNode->addProp(attrName.str(), szAttrib); } Owned pNewCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSet, m_pService->getCfg(), m_pService->getName(), true); if (pNewCompTree) { StringBuffer sbxml; toXML(pNewCompTree, sbxml); Owned iterElems = pNewCompTree->getElements("Instance/*"); ForEach (*iterElems) { IPropertyTree* pElem = &iterElems->query(); if (!pNode->queryProp(pElem->queryName())) pNode->addPropTree(pElem->queryName(), createPTreeFromIPT(pElem)); } } } if (!checkForRequiredComponents(pEnvRoot, pComputerNode->queryProp(XML_ATTR_NETADDRESS), reqdCompNames)) reqdComps.appendf("\n%s", pComputerNode->queryProp(XML_ATTR_NETADDRESS)); } resp.setReqdCompNames(reqdCompNames.str()); resp.setAddReqdComps(reqdComps.str()); resp.setDuplicates(dups.str()); } else if (!strcmp(operation, "Delete")) { Owned iterInst = instances->getElements("*"); ForEach(*iterInst) { IPropertyTree& pInst = iterInst->query(); StringBuffer decodedParams( pInst.queryProp("@params") ); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); xpath.clear().appendf("./Software/%s[@name=\"%s\"]", pszCompType, pszCompName); IPropertyTree* pInstParent = pEnvRoot->queryPropTree(xpath.str()); if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']') xpath.clear().appendf("%s%s", pszSubType, pszSubTypeKey); else xpath.clear().appendf("%s[@name=\"%s\"]", pszSubType, pszSubTypeKey); IPropertyTree* pInstTree = pInstParent->queryPropTree(xpath.str()); if (pInstParent && pInstTree) pInstParent->removeTree(pInstTree); } } //rename instance names int nCount = 1; xpath.clear().appendf("./Software/%s[@name=\"%s\"]/Instance", processName, compName); Owned iter = pEnvRoot->getElements(xpath.str()); StringBuffer sName; ForEach(*iter) { sName.clear().append("s").append(nCount); iter->query().setProp(XML_ATTR_NAME, sName.str()); nCount++; } resp.setStatus("true"); return true; } bool CWsDeployFileInfo::addReqdComps(IEspContext &context, IEspAddReqdCompsRequest &req, IEspAddReqdCompsResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned instances = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); Owned iterComp = instances->getElements("*"); bool bAdded = false; StringBuffer reqCompNames, failed; ForEach(*iterComp) { IPropertyTree& pComputer = iterComp->query(); if (!checkForRequiredComponents(pEnvRoot, pComputer.queryProp(XML_ATTR_NETADDRESS), reqCompNames, true)) failed.appendf("\n%s", pComputer.queryProp(XML_ATTR_NETADDRESS)); } resp.setFailures(failed.str()); resp.setStatus("true"); return true; } bool CWsDeployFileInfo::handleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned pBindings = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* type = pBindings->queryProp(XML_ATTR_TYPE); const char* espName = pBindings->queryProp("@compName"); const char* operation = req.getOperation(); StringBuffer sbNewName; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); StringBuffer xpath; if (!strcmp(operation, "Add")) { xpath.append("./Programs/Build/BuildSet[@processName=\"EspProcess\"]"); Owned buildSetIter = pEnvRoot->getElements(xpath.str()); buildSetIter->first(); IPropertyTree* pBuildSet = &buildSetIter->query(); const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); xpath.clear().appendf("./Software/%s[@name='%s']", processName, espName); Owned iterItems = pBindings->getElements("Item"); bool flag = false; ForEach (*iterItems) { flag = true; IPropertyTree* pItem = &iterItems->query(); const char* bindingName = pItem->queryProp(XML_ATTR_NAME); const char* params = pItem->queryProp("@params"); StringBuffer decodedParams(params); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); if (strcmp(type, XML_TAG_ESPBINDING) && bindingName) xpath.appendf("/EspBinding[@name='%s']", bindingName); else if (pszSubType && *pszSubType) { String subType(pszSubType); int idx = subType.lastIndexOf('/'); if (idx > 0) { String* tmpstr = subType.substring(0, idx); xpath.append("/").append(*tmpstr); delete tmpstr; } } IPropertyTree* pEspService = pEnvRoot->queryPropTree(xpath.str()); IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()); StringBuffer sb(type); if (!strncmp(sb.str(), "_", 1)) sb.remove(0, 1); if (!strcmp(type, XML_TAG_ESPBINDING)) { StringBuffer sbNewName(XML_TAG_ESPBINDING); xpath.clear().appendf("%s[@name='%s']/EspBinding", processName, espName); getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE); xpath.clear().append(sb.str()).append("/").append(XML_ATTR_NAME); pCompTree->setProp(xpath.str(), sbNewName); resp.setNewName(sbNewName); } if (pEspService && pCompTree) pEspService->addPropTree(sb.str(), pCompTree->queryPropTree(sb.str())); //If we are adding, just consider the first selection. break; } if (!flag) { IPropertyTree* pEspService = pEnvRoot->queryPropTree(xpath.str()); IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()); StringBuffer sbNewName(XML_TAG_ESPBINDING); xpath.clear().appendf("%s[@name='%s']/EspBinding", processName, espName); getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE); xpath.clear().append(XML_TAG_ESPBINDING).append("/").append(XML_ATTR_NAME); pCompTree->setProp(xpath.str(), sbNewName); resp.setNewName(sbNewName); if (pEspService && pCompTree) pEspService->addPropTree(XML_TAG_ESPBINDING, pCompTree->queryPropTree(XML_TAG_ESPBINDING)); } resp.setStatus("true"); } else if (!strcmp(operation, "Delete")) { Owned iterItems = pBindings->getElements("Item"); bool deleteAll = true; IPropertyTreePtrArray bindings; ForEach (*iterItems) { IPropertyTree* pItem = &iterItems->query(); const char* bindingName = pItem->queryProp(XML_ATTR_NAME); const char* params = pItem->queryProp("@params"); StringBuffer decodedParams(params); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); xpath.clear().appendf("./Software/%s[@name='%s']", XML_TAG_ESPPROCESS, espName); if (!strcmp(type, XML_TAG_ESPBINDING)) { if (bindingName) xpath.appendf("/EspBinding[@name='%s']", bindingName); IPropertyTree* pEspBinding = pEnvRoot->queryPropTree(xpath.str()); StringBuffer sbMsg; StringBuffer sbFullName(espName); sbFullName.append("/").append(bindingName); bool ret = checkComponentReferences(pEnvRoot, pEspBinding, sbFullName.str(), sbMsg); if (ret) bindings.push_back(pEspBinding); else { deleteAll = false; resp.setStatus(sbMsg.str()); break; } } else { if (pszSubType && *pszSubType) xpath.append("/").append(pszSubType); const char* resource = pItem->queryProp("@resource"); if (resource) xpath.appendf("[@resource='%s']", resource); IPropertyTree* pSubType = pEnvRoot->queryPropTree(xpath.str()); String subType(xpath.str()); int idx = subType.lastIndexOf('/'); if (idx > 0) { String* tmpstr = subType.substring(0, idx); xpath.clear().append(*tmpstr); delete tmpstr; } if (pSubType) pEnvRoot->queryPropTree(xpath.str())->removeTree(pSubType); } } if (deleteAll) { xpath.clear().appendf("./Software/%s[@name='%s']", XML_TAG_ESPPROCESS, espName); IPropertyTree* pEspService = pEnvRoot->queryPropTree(xpath.str()); int nBindings = bindings.size(); for (int i=0; i < nBindings; i++) { IPropertyTree* pBinding = bindings[i]; pEspService->removeTree(pBinding); } resp.setStatus("true"); } } return true; } bool CWsDeployFileInfo::handleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned pParams = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* type = pParams->queryProp(XML_ATTR_TYPE); const char* operation = req.getOperation(); StringBuffer sbNewName; StringBuffer xpath; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); if (!strcmp(operation, "New")) { StringBuffer sbTemp; IPropertyTree* pCompTree = createPTree(XML_TAG_HARDWARE); generateHardwareHeaders(pEnvRoot, sbTemp, false, pCompTree); StringBuffer sbNewName(type); xpath.clear().appendf("%s", type); getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_HARDWARE); xpath.clear().append(type).append("/").append(XML_ATTR_NAME); pCompTree->setProp(xpath.str(), sbNewName); pEnvRoot->queryPropTree(XML_TAG_HARDWARE)->addPropTree(type, pCompTree->queryPropTree(type)); resp.setCompName(sbNewName.str()); resp.setStatus("true"); } else if (!strcmp(operation, "NewRange")) { const char* prefix = pParams->queryProp("@prefix"); const char* domain = pParams->queryProp(XML_ATTR_DOMAIN); const char* cType = pParams->queryProp(XML_ATTR_COMPUTERTYPE); const char* startIP = pParams->queryProp("@startIP"); const char* endIP = pParams->queryProp("@endIP"); IPropertyTree* pComps = getNewRange(pEnvRoot, prefix, domain, cType, startIP, endIP); if (m_bCloud) { StringBuffer sbMsg; CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_UNLOCK_ENV, m_userWithLock.str(), "8015", pComps); bool ret = lockCloud.start(sbMsg); if (!ret || sbMsg.length()) { resp.setStatus("false"); throw MakeStringException(-1, "Cannot add new range of computers as environment lock could not be obtained. Reason(s):\n%s", sbMsg.str()); } } if (pComps) { mergePTree(pEnvRoot->queryPropTree(XML_TAG_HARDWARE), pComps); resp.setCompName(pComps->queryPropTree("Computer[1]")->queryProp(XML_ATTR_NAME)); } resp.setStatus("true"); } else if (!strcmp(operation, "Delete")) { StringBuffer refs; StringBuffer refName; Owned iterComputers = pParams->getElements("Item"); ForEach (*iterComputers) { IPropertyTree* pComp = &iterComputers->query(); const char* name = pComp->queryProp(XML_ATTR_NAME); if (!strcmp(type, XML_TAG_COMPUTER)) xpath.clear().appendf(XML_TAG_SOFTWARE"//["XML_ATTR_COMPUTER"=\"%s\"]", name); else if (!strcmp(type, XML_TAG_COMPUTERTYPE)) xpath.clear().appendf(XML_TAG_HARDWARE"//["XML_ATTR_COMPUTERTYPE"=\"%s\"]", name); else if (!strcmp(type, XML_TAG_DOMAIN)) xpath.clear().appendf(XML_TAG_HARDWARE"//["XML_ATTR_DOMAIN"=\"%s\"]", name); else if (!strcmp(type, XML_TAG_SWITCH)) xpath.clear().appendf(XML_TAG_HARDWARE"//["XML_ATTR_SWITCH"=\"%s\"]", name); Owned iter = pEnvRoot->getElements(xpath.str()); ForEach(*iter) { IPropertyTree& pComp = iter->query(); const char* compName = pComp.queryProp(XML_ATTR_NAME); const char* parentName = pComp.queryName(); refs.append("\n").append(parentName).append(" name=").append(compName); } if (refs.length()) { refName.clear().append(name); break; } } if (refs.length()) throw MakeStringException(-1, "Cannot delete %s with name %s as it is being referenced by components: %s.", type, refName.str(), refs.str()); else { if (m_bCloud && !strcmp(type, XML_TAG_COMPUTER)) { StringBuffer sb, sbMsg; sb.append(""); ForEach (*iterComputers) { IPropertyTree* pComp = &iterComputers->query(); xpath.clear().appendf(XML_TAG_HARDWARE"/%s["XML_ATTR_NAME"=\"%s\"]", type, pComp->queryProp(XML_ATTR_NAME)); IPropertyTree* pTree = pEnvRoot->queryPropTree(xpath.str()); sb.appendf("", pTree->queryProp(XML_ATTR_NETADDRESS)); } sb.append(""); Owned pComputers = createPTreeFromXMLString(sb.str()); CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_LOCK_ENV, m_userWithLock.str(), "8015", pComputers); bool ret = unlockCloud.start(sbMsg); if (!ret || sbMsg.length()) throw MakeStringException(-1, "Cannot delete computers as they cannot be unlocked. Reason(s):\n%s", sbMsg.str()); } ForEach (*iterComputers) { IPropertyTree* pComp = &iterComputers->query(); xpath.clear().appendf(XML_TAG_HARDWARE"/%s["XML_ATTR_NAME"=\"%s\"]", type, pComp->queryProp(XML_ATTR_NAME)); IPropertyTree* pTree = pEnvRoot->queryPropTree(xpath.str()); pEnvRoot->queryPropTree(XML_TAG_HARDWARE)->removeTree(pTree); } resp.setStatus("true"); } } return true; } bool CWsDeployFileInfo::handleTopology(IEspContext &context, IEspHandleTopologyRequest &req, IEspHandleTopologyResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned pParams = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* compType = pParams->queryProp("@compType"); const char* name = pParams->queryProp(XML_ATTR_NAME); const char* newType = pParams->queryProp("@newType"); const char* operation = req.getOperation(); StringBuffer decodedParams( pParams->queryProp("@params") ); decodedParams.replaceString("::", "\n"); Owned pTopParams = createProperties(); pTopParams->loadProps(decodedParams.str()); StringBuffer buf("Software/Topology"); for (int i = 3; i >= 0; i--) { StringBuffer sb; sb.appendf("inner%d_name", i); const char* sbName = pTopParams->queryProp(sb.str()); if (sbName) { if (strstr(sbName, "EclCCServerProcess") == sbName || strstr(sbName, "EclServerProcess") == sbName || strstr(sbName, "EclAgentProcess") == sbName || strstr(sbName, "EclSchedulerProcess") == sbName) { StringBuffer sbEcl(sbName); if (strstr(sbName, " - ")) sbEcl.replaceString(" - ", "[@process='").append("']"); else if (strstr(sbName, " -")) sbEcl.replaceString(" -", "[@process='").append("']"); buf.append("/").append(sbEcl); } else if (strstr(sbName, "Cluster") == sbName) { StringBuffer sbCl(sbName); if (strstr(sbName, " - ")) sbCl.replaceString(" - ", "[@name='").append("']"); else if (strstr(sbName, " -")) sbCl.replaceString(" -", "[@name='").append("']"); buf.append("/").append(sbCl); } else if (strstr(sbName, XML_TAG_THORCLUSTER) == sbName) buf.append("/ThorCluster"); else if (strstr(sbName, XML_TAG_ROXIECLUSTER) == sbName) buf.append("/RoxieCluster"); else if (buf.str()[buf.length() - 1] != ']') buf.appendf("[@%s='%s']", sbName, pTopParams->queryProp(sb.replaceString("_name", "_value").str())); } } Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); if (!strcmp(operation, "Add")) { StringBuffer sbNewType(newType); if (!strcmp(newType, "EclCCServer")) sbNewType.clear().append(XML_TAG_ECLCCSERVERPROCESS); else if (!strcmp(newType, "EclServer")) sbNewType.clear().append(XML_TAG_ECLSERVERPROCESS); else if (!strcmp(newType, "EclAgent")) sbNewType.clear().append(XML_TAG_ECLAGENTPROCESS); else if (!strcmp(newType, "EclScheduler")) sbNewType.clear().append(XML_TAG_ECLSCHEDULERPROCESS); else if (!strcmp(newType, "Thor")) sbNewType.clear().append(XML_TAG_THORCLUSTER); else if (!strcmp(newType, "Roxie")) sbNewType.clear().append(XML_TAG_ROXIECLUSTER); IPropertyTree* pNode = createPTree(sbNewType.str()); if (!strcmp(sbNewType.str(), XML_TAG_ECLCCSERVERPROCESS) || !strcmp(sbNewType.str(), XML_TAG_ECLSERVERPROCESS) || !strcmp(sbNewType.str(), XML_TAG_ECLAGENTPROCESS) || !strcmp(sbNewType.str(), XML_TAG_ECLSCHEDULERPROCESS) || !strcmp(sbNewType.str(), XML_TAG_THORCLUSTER) || !strcmp(sbNewType.str(), XML_TAG_ROXIECLUSTER)) pNode->addProp(XML_ATTR_PROCESS, ""); else if (!strcmp(sbNewType.str(), XML_TAG_CLUSTER)) { pNode->addProp(XML_ATTR_NAME, ""); pNode->addProp(XML_ATTR_PREFIX, ""); } IPropertyTree* pTopology = pEnvRoot->queryPropTree(buf.str()); if (pTopology) pTopology->addPropTree(sbNewType.str(), pNode); resp.setStatus("true"); } else if (!strcmp(operation, "Delete")) { String sParent(buf.str()); StringBuffer sbParent(XML_TAG_SOFTWARE"/"XML_TAG_TOPOLOGY); int idx = sParent.lastIndexOf('/'); if (idx > 0) { String* tmpstr = sParent.substring(0, idx); sbParent.clear().append(*tmpstr); delete tmpstr; } IPropertyTree* pTopology = pEnvRoot->queryPropTree(sbParent); IPropertyTree* pDel = pEnvRoot->queryPropTree(buf.str()); if (pTopology && pDel) pTopology->removeTree(pDel); resp.setStatus("true"); } return true; } bool CWsDeployFileInfo::handleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); const char* operation = req.getOperation(); StringBuffer xpath; StringBuffer sMsg; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); bool retVal = handleThorTopologyOp(pEnvRoot, operation, xmlArg, sMsg); resp.setStatus(retVal? "true" : sMsg.str()); return true; } bool CWsDeployFileInfo::handleRows(IEspContext &context, IEspHandleRowsRequest &req, IEspHandleRowsResponse &resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); const char* xmlArg = req.getXmlArgs(); Owned pParams = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : ""); const char* buildSet = pParams->queryProp(XML_ATTR_BUILDSET); const char* name = pParams->queryProp("@compName"); const char* rowType = pParams->queryProp("@rowType"); const char* operation = req.getOperation(); StringBuffer sbNewName; StringBuffer xpath; Owned buildSetIter; IPropertyTree* pBuildSet = NULL; const char* buildSetName = NULL; const char* processName = NULL; Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); if (strcmp(name, "Directories")) { xpath.appendf("./Programs/Build/BuildSet[@name=\"%s\"]", buildSet); buildSetIter.setown(pEnvRoot->getElements(xpath.str())); buildSetIter->first(); pBuildSet = &buildSetIter->query(); buildSetName = pBuildSet->queryProp(XML_ATTR_NAME); processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); } StringBuffer buildSetPath; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()); if (!strcmp(operation, "Add")) { if (!strcmp(name, "Directories")) { xpath.clear().appendf("Software/Directories/Category[@name='%s']", rowType); IPropertyTree* pCat = pEnvRoot->queryPropTree(xpath.str()); if (pCat) { IPropertyTree* pOver = pCat->queryPropTree("Override[@component=''][@dir=''][@instance='']"); if (!pOver) { pOver = pCat->addPropTree("Override", createPTree()); pOver->addProp("@component", ""); pOver->addProp("@dir", ""); pOver->addProp("@instance", ""); } } } else { xpath.clear().appendf("./Software/%s[@name='%s']", processName, name); Owned rows = pParams->getElements("Row"); bool flag = false; ForEach (*rows) { flag = true; IPropertyTree* pRow = &rows->query(); const char* params = pRow->queryProp("@params"); StringBuffer decodedParams(params); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); StringBuffer sbParent; if (pszSubType && *pszSubType) { String subType(pszSubType); int idx = subType.lastIndexOf('/'); if (idx > 0) { String* tmpstr = subType.substring(0, idx); xpath.append("/").append(*tmpstr); sbParent.append(*tmpstr); delete tmpstr; } else { xpath.append("/").append(pszSubType); sbParent.append(pszSubType); if (pszSubTypeKey && *pszSubTypeKey) xpath.append(pszSubTypeKey); } } IPropertyTree* pComponent = pEnvRoot->queryPropTree(xpath.str()); IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()); StringBuffer sb(rowType); if (!strncmp(sb.str(), "_", 1)) sb.remove(0, 1); StringBuffer s; s.appendf("xs:element//*[@name=\"%s\"]//*[@name=\"%s\"]//xs:attribute[@name='name']", sbParent.str(), rowType); IPropertyTree* pt = pSchema->queryPropTree(s.str()); if (pt && pt->hasProp("@type")) { const char* px = pt->queryProp("@type"); if (!strcmp(px, "xs:string")) { StringBuffer sbNewName(rowType); xpath.clear().appendf("%s[@name='%s']/%s", processName, name, sbParent.str()); getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE); pCompTree->setProp(sb.str(), sbNewName); resp.setCompName(sbNewName); } } if (pComponent && pCompTree) pComponent->addPropTree(rowType, pCompTree->queryPropTree(rowType)); //If we are adding, just consider the first selection. break; } if (!flag) { if (pCompTree->queryPropTree(rowType)) { if (strcmp(rowType, "Notes")) { StringBuffer sbNewName(rowType); xpath.clear().appendf("%s[@name]", rowType); if (pCompTree->hasProp(xpath.str())) { xpath.clear().appendf("%s[@name='%s']/%s", processName, name, rowType); getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE); pCompTree->queryPropTree(rowType)->setProp(XML_ATTR_NAME, sbNewName); resp.setCompName(sbNewName.str()); } } else { IPropertyTree* pNotes = pCompTree->queryPropTree(rowType); if (pNotes->hasProp("@computer")) pNotes->setProp("@computer", m_userIp.str()); if (pNotes->hasProp("@user")) pNotes->setProp("@user", ""); if (pNotes->hasProp("@date")) { CDateTime dt; StringBuffer tmp; dt.setNow(); tmp.clear(); unsigned mo, da, yr; dt.getDate(yr, mo, da, true); tmp.appendf("%d/%d/%d ", mo, da, yr); dt.getTimeString(tmp, true); pNotes->setProp("@date", tmp.str()); resp.setCompName(tmp.str()); } } xpath.clear().appendf("./Software/%s[@name='%s']", processName, name); IPropertyTree* pComponent = pEnvRoot->queryPropTree(xpath.str()); if (pComponent) pComponent->addPropTree(rowType, pCompTree->queryPropTree(rowType)); } } } resp.setStatus("true"); } else if (!strcmp(operation, "Delete")) { if (!strcmp(name, "Directories")) xpath.clear().appendf("./Software/Directories/Category[@name='%s']", rowType); else xpath.clear().appendf("./Software/%s[@name='%s']", processName, name); IPropertyTree* pComponent = pEnvRoot->queryPropTree(xpath.str()); Owned iterRows = pParams->getElements("Row"); ForEach (*iterRows) { IPropertyTree* pRow = &iterRows->query(); const char* rowName = pRow->queryProp("@rowName"); if (!strcmp(name, "Directories")) { const char* compType = pRow->queryProp("@compType"); xpath.clear().appendf("Override[@component='%s'][@instance='%s']", compType, rowName); } else { if (!strcmp(rowType, "Notes")) { const char* rowDate = pRow->queryProp("@rowDate"); if (!rowDate || !*rowDate) continue; xpath.clear().appendf("%s[@date='%s']", rowType, rowDate); } else if (rowName && *rowName) xpath.clear().appendf("%s[@name='%s']", rowType, rowName); else { const char* params = pRow->queryProp("@params"); StringBuffer decodedParams(params); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszCompType = pParams->queryProp("pcType"); const char* pszCompName = pParams->queryProp("pcName"); const char* pszSubType = pParams->queryProp("subType"); const char* pszSubTypeKey = pParams->queryProp("subTypeKey"); StringBuffer sbParent; if (pszSubType && *pszSubType) { String subType(pszSubType); xpath.clear().append(pszSubType); if (pszSubTypeKey && *pszSubTypeKey) xpath.append(pszSubTypeKey); } } } if (pComponent) pComponent->removeTree(pComponent->queryPropTree(xpath.str())); } resp.setCompName(""); resp.setStatus("true"); } return true; } IPropertyTree* CWsDeployFileInfo::findComponentForFolder(IPropertyTree* pFolder, IPropertyTree* pEnvSoftware) { //Folder's @params has string of the form: //"comp=EspProcess&name=esp&inst=s1&computer=2wd20" // StringBuffer decodedParams( pFolder->queryProp("@params") ); decodedParams.replace('&', '\n'); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* comp = pParams->queryProp("comp"); const char* name = pParams->queryProp("name"); if (!(comp && *comp && name && *name)) throw MakeStringException(-1, "Invalid parameters"); StringBuffer xpath; xpath.appendf("%s[@name='%s']", comp, name); IPropertyTree* pComp = pEnvSoftware->queryPropTree(xpath.str()); if (!pComp) throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", comp, name); return pComp; } void CWsDeployFileInfo::addDeployableComponentAndInstances(IPropertyTree* pEnvRoot, IPropertyTree* pComp, IPropertyTree* pDst, IPropertyTree* pFolder, const char* displayType) { const char* comp = pComp->queryName(); const char* name = pComp->queryProp(XML_ATTR_NAME); if (!name || !*name) throw MakeStringException(-1, "The environment has an incomplete definition for a '%s'!", comp); const char* build= pComp->queryProp(XML_ATTR_BUILD); const char* buildSet= pComp->queryProp(XML_ATTR_BUILDSET); if (!build || !*build) throw MakeStringException(-1, "%s '%s' does not have any build defined!", comp, name); if (!buildSet || !*buildSet) throw MakeStringException(-1, "%s '%s' does not have any build set defined!", comp, name); StringBuffer xpath; xpath.appendf("Programs/Build[@name='%s']/BuildSet[@name='%s']", build, buildSet); IPropertyTree* pBuildSetNode = pEnvRoot->queryPropTree(xpath.str()); if (!pBuildSetNode) throw MakeStringException(-1, "Build %s or build set %s is not defined!", build, buildSet); const char* deployable = pBuildSetNode->queryProp("@deployable"); if (!deployable || (0!=strcmp(deployable, "no") && 0!=strcmp(deployable, "false"))) { char achDisplayType[132];//long enough to hold any expanded type whatsoever if (!displayType) { GetDisplayProcessName(pComp->queryName(), achDisplayType); displayType = achDisplayType; } const bool bDeployAllInstances = !pFolder || pFolder->getPropBool("@selected", false); if (bDeployAllInstances) { //add its instances Owned iInst = pComp->getElements("*"); ForEach(*iInst) { IPropertyTree* pInstance = &iInst->query(); const char* instType = pInstance->queryName(); if (instType && (!strcmp(instType, XML_TAG_INSTANCE) || !strcmp(instType, XML_TAG_ROXIE_SERVER))) { const char* instName = pInstance->queryProp(XML_ATTR_NAME); const char* computer = pInstance->queryProp(XML_ATTR_COMPUTER); if (instName && *instName && computer && *computer) addInstance(pDst, comp, displayType, name, build, instType, instName, computer); } }//ForEach(*iInst) } else { //pFolder exists and is not selected so deploy selected instances Owned iLink = pFolder->getElements("*[@selected='true']"); ForEach(*iLink) { IPropertyTree* pLink = &iLink->query(); const char* params = pLink->queryProp("@params"); if (params) { // pFolder's @params has string of the form: "comp=EspProcess&name=esp&instType=Instance&inst=s1&computer=2wd20" // StringBuffer decodedParams( params ); decodedParams.replace('&', '\n'); Owned pParams = createProperties(); pParams->loadProps( decodedParams.str() ); const char* instType = pParams->queryProp("instType"); const char* instName = pParams->queryProp("inst"); const char* computer = pParams->queryProp(TAG_COMPUTER); if (instType && *instType && instName && *instName && computer && *computer) { StringBuffer xpath; xpath.appendf("%s[@name='%s']", instType, instName); IPropertyTree* pInstNode = pComp->queryPropTree(xpath.str()); if (!pInstNode) throw MakeStringException(-1, "%s '%s' does not have any '%s' named %s!", displayType, comp, instType, instName); addInstance(pDst, comp, displayType, name, build, instType, instName, computer); } } } } } } void CWsDeployFileInfo::addInstance(IPropertyTree* pDst, const char* comp, const char* displayType, const char* compName, const char* build, const char* instType, const char* instName, const char* computer) { IPropertyTree* pCompNode = pDst->addPropTree( XML_TAG_COMPONENT, createPTree() ); pCompNode->addProp("Type", comp); pCompNode->addProp("DisplayType", displayType); pCompNode->addProp("Name", compName); pCompNode->addProp("Build", build); pCompNode->addProp("InstanceType", instType); pCompNode->addProp("Instance", instName); pCompNode->addProp("Computer", computer); } //--------------------------------------------------------------------------- // GetDisplayProcessName //--------------------------------------------------------------------------- const char* CWsDeployFileInfo::GetDisplayProcessName(const char* processName, char* buf) const { //produces "LDAPServerProcess" as "LDAP Server" and "EspService" as "Esp Service", etc. if (!strcmp(processName, XML_TAG_ESPPROCESS)) return strcpy(buf, "ESP Server"); else { const char* begin = buf; const char* end = strstr(processName, "Process"); if (!end) end = processName + strlen(processName); *buf++ = *processName++; bool bLower = false; while (processName < end) { char ch = *processName; if (isupper(ch)) { if (bLower || //last char was uppercase or the following character is lowercase? ((processName+1 < end) && islower(*(processName+1)))) { *buf++ = ' '; } bLower = false; } else bLower = true; *buf++ = *processName++; } *buf = '\0'; return begin; } } void CWsDeployFileInfo::updateConfigFromFile() { StringBuffer sbxml; if (m_pFileIO.get() != NULL) { m_pFileIO.clear(); } if (m_lastSaved.isNull()) { m_lastSaved.setNow(); } m_pFileIO.setown(m_pFile->open(IFOread)); Owned pTree = createPTree(*m_pFileIO); toXML(pTree, sbxml.clear()); Owned factory = getEnvironmentFactory(); m_constEnvRdOnly.clear(); m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sbxml.str())); m_lastSaved.clear(); m_lastSaved.setNow(); } bool CWsDeployFileInfo::deploy(IEspContext &context, IEspDeployRequest& req, IEspDeployResponse& resp) { synchronized block(m_mutex); checkForRefresh(context, &req.getReqInfo(), true); resp.setComponent("WsDeploy"); resp.setCommand("Deploy"); StringBuffer deployResult; IConstDeployInfo& depInfo = req.getDeploy(); IArrayOf& components = depInfo.getComponents(); unsigned int nComps = components.ordinality(); if (nComps == 0) { resp.setStatus( "Please select at least one component to deploy!" ); CDeployOptions& depOptions = dynamic_cast( depInfo.getOptions() ); depOptions.serialize(&context,deployResult, "Options"); } else { CWsDeployEngine depEngine(*m_pService, req.getDeploy(),&context); depEngine.deploy(); Owned pDeployResult = depEngine.getDeployResult(); IPropertyTree* pComponents = pDeployResult->queryPropTree("Components"); toXML(pComponents, deployResult, false); IPropertyTree* pOptions = pDeployResult->queryPropTree("Options"); toXML(pOptions, deployResult, false); resp.setStatus( depEngine.getDeployStatus() ); } resp.setDeploy( deployResult.str() ); return true; } bool CWsDeployExCE::onInit(IEspContext &context, IEspEmptyRequest& req, IEspInitResponse& resp) { resp.setComponent("WsDeploy"); resp.setCommand("Init"); return true; } //the following method must be called with ownership of m_mutex // void CWsDeployFileInfo::generateGraph(IEspContext &context, IConstWsDeployReqInfo *reqInfo) { { synchronized block(m_mutex); checkForRefresh(context, reqInfo, true); } if (!m_pEnvXml) { Owned pEnvTree = getEnvTree(context, reqInfo); m_pEnvXml.set(new SCMStringBuffer()); toXML(pEnvTree, m_pEnvXml->s, false); } m_pGraphXml.set(new SCMStringBuffer()); xsltTransform(m_pEnvXml->str(), StringBuffer(getCFD()).append("xslt/graph_env.xslt").str(), NULL, m_pGraphXml->s); } //--------------------------------------------------------------------------- // onGraph //--------------------------------------------------------------------------- bool CWsDeployFileInfo::graph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp) { synchronized block(m_mutex); if (!m_pGraphXml) generateGraph(context, NULL); resp.setGraphContainer(m_pGraphXml->str()); return true; } void CWsDeployFileInfo::getNavigationData(IEspContext &context, IPropertyTree* pData) { try { synchronized block(m_mutex); if (m_envFile.length()) { if (!m_userWithLock.length()) { context.getUserID(m_userWithLock); context.getPeer(m_userIp); } else { StringBuffer sbName, sbUserIp; context.getUserID(sbName); context.getPeer(sbUserIp); if (strcmp(sbName.str(), m_userWithLock.str()) || strcmp(sbUserIp.str(), m_userIp.str())) throw MakeStringException(-1, "A user on machine %s is accessing the file. Please try again later.", m_userIp.str()); } initFileInfo(false); } if (!m_pNavTree) { if (!m_pEnvXml) { Owned pEnvTree = getEnvTree(context, NULL); m_pEnvXml.set(new SCMStringBuffer()); toXML(pEnvTree, m_pEnvXml->s, false); } m_pNavTree.setown(getEnvTree(context, NULL)); } pData->setProp("@viewType", "tree"); mergePTree(pData, m_pNavTree); } catch(IException*e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); } catch(...) { } } void CWsDeployFileInfo::saveEnvironment(IEspContext* pContext, IConstWsDeployReqInfo *reqInfo, StringBuffer& errMsg, bool saveAs) { if (m_envFile.length()) { Owned pEnvRoot; StringBuffer valerrs; try { if (!saveAs || (saveAs && m_Environment)) { pEnvRoot.setown(&m_Environment->getPTree()); validateEnv((IConstEnvironment*)m_Environment, false); } else if (saveAs) { pEnvRoot.setown(&m_constEnvRdOnly->getPTree()); validateEnv(m_constEnvRdOnly, false); } } catch(IException* e) { e->errorMessage(valerrs); e->Release(); } //save and write to backup StringBuffer sXML; StringBuffer tmp; StringBuffer dtStr; CDateTime dt; dt.setNow(); dt.getString(tmp.clear()); sXML.appendf("<"XML_HEADER">\n\n", m_userIp.str(), tmp.str()); toXML(pEnvRoot, sXML, 0, XML_SortTags | XML_Format); if (m_bCloud && pContext) { StringBuffer sbName, sbUserIp, sbMsg; if (reqInfo) sbName.clear().append(reqInfo->getUserId()); pContext->getPeer(sbUserIp); CCloudActionHandler saveCloud(this, CLOUD_SAVE_ENV, CLOUD_ROLLBACK_ENV, sbName.str(), "8015", NULL); StringBuffer tick; tick.appendf("%d", msTick()); saveCloud.setSaveActionParams(sXML.str(), tick.str()); bool ret = saveCloud.start(sbMsg); if (!ret || sbMsg.length()) throw MakeStringException(0, "Environment could not be successfully saved. Reason(s):\n%s", sbMsg.str()); } try { if (m_pFile.get()) { StringBuffer sb; if (!checkDirExists(m_pService->getBackupDir())) recursiveCreateDirectory(m_pService->getBackupDir()); while(true) { String strEnvFile(m_envFile); int idx = strEnvFile.lastIndexOf('/'); if (idx <= 0) idx = strEnvFile.lastIndexOf('\\'); String* tmpstr = strEnvFile.substring(idx+1); sb.clear().append(m_pService->getBackupDir()).append(PATHSEPCHAR).append(*tmpstr); delete tmpstr; dt.setNow(); tmp.clear(); dtStr.clear(); dt.getDateString(tmp, true); tmp.append("_"); dt.getTimeString(tmp, true); dtStr.append(".").append(tmp); dtStr.replaceString("-","_"); dtStr.replaceString(":","_"); String ext(sb); idx = ext.lastIndexOf(PATHSEPCHAR); if(ext.indexOf('.', idx > 0 ? idx : 0) != -1) sb.insert(ext.lastIndexOf('.'), dtStr.str()); else sb.append(dtStr.str()); if (checkFileExists(sb)) continue; else { Owned pFile(createIFile(sb.str())); m_configFileMonitorThread.clear(); copyFile(pFile, m_pFile, 0x100000); break; } } } } catch(IException* e) { //ignore any attempts to create the backup e->Release(); } if (!m_pFile.get()) m_pFile.setown(createIFile(m_envFile)); m_pFileIO.clear(); m_pFileIO.setown(m_pFile->open(IFOcreaterw)); m_pFileIO->write(0, sXML.length(), sXML.str()); m_lastSaved.clear(); m_lastSaved.setNow(); //reset the readonly tree Owned factory = getEnvironmentFactory(); m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sXML.str())); if (valerrs.length()) errMsg.appendf("CWsDeployFileInfo::saveEnvironment:Save operation was successful. However the following exceptions were raised.\n%s", valerrs.str()); } else { // JAKESMITH->SMEDA - apparently this code is legacy and can be deleted, please do + clearup related code if any try { m_Environment->commit(); StringBuffer response; initClusterGroups(false, response, NULL); if (response.length()) PROGLOG("CWsDeployFileInfo::saveEnvironment: %s", response.str()); } catch (IException* e) { StringBuffer sErrMsg; e->errorMessage(sErrMsg); e->Release(); /*typical error message when lock fails is as follows: SDS: Lock timeout SDS Reply Error : SDS: Lock timeout Failed to establish lock to NewEnvironment/ Existing lock status: Locks on path: /NewEnvironment/ Endpoint |SessionId |ConnectionId |mode 172.16.48.175:7254 |c00000038 |c0000003b |653 */ //if we can extract IP address of computer holding the lock then //show a customized message. // //Retrieve IP address of computer holding the lock... char achHost[128] = ""; const char* p = strstr(sErrMsg.str(), "\n\n"); if (p && *(p+=2)) { const char* q = strchr(p, ':'); if (q) { const int len = q-p; strncpy(achHost, p, len); achHost[len] = '\0'; } } //resolve hostname for this IP address unsigned int addr = inet_addr(achHost); struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); if (hp) strcpy(achHost, hp->h_name); StringBuffer sMsg; sMsg.appendf("The environment definition in dali server " "could not be opened for write access"); if (achHost[0]) sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost); else sMsg.append(":\n\n").append(sErrMsg); throw MakeStringException(0, "%s", sMsg.str()); } } if (m_configFileMonitorThread.get() == NULL) { m_configFileMonitorThread.setown(new CWsDeployFileInfo::CConfigFileMonitorThread(this, CONFIG_MONITOR_CHECK_INTERVAL, CONFIG_MONITOR_TIMEOUT_PERIOD)); m_configFileMonitorThread->init(); } } void CWsDeployFileInfo::unlockEnvironment(IEspContext* context, IConstWsDeployReqInfo *reqInfo, const char* xmlArg, StringBuffer& sbErrMsg, bool saveEnv) { if (m_bCloud) { StringBuffer sbMsg; Owned pComputers = createPTreeFromXMLString(xmlArg); Owned unlockComputers = createPTree("ComputerList"); Owned lockComputers = createPTree("ComputerList"); Owned iter; StringBuffer xpath; if (pComputers && pComputers->numChildren() && m_lockedNodesBeforeEnv.get() != NULL) { expandRange(pComputers); iter.setown(pComputers->getElements("Computer")); ForEach (*iter) { IPropertyTree* pComputer = &iter->query(); xpath.clear().appendf(XML_TAG_COMPUTER"["XML_ATTR_NETADDRESS"='%s']", pComputer->queryProp(XML_ATTR_NETADDRESS)); if (!m_lockedNodesBeforeEnv->queryPropTree(xpath.str())) lockComputers->addPropTree(XML_TAG_COMPUTER, createPTreeFromIPT(pComputer)); } } if (!pComputers && m_lockedNodesBeforeEnv.get() != NULL) unlockComputers.set(m_lockedNodesBeforeEnv); else if (m_lockedNodesBeforeEnv.get() != NULL) { iter.setown(m_lockedNodesBeforeEnv->getElements("Computer")); ForEach (*iter) { IPropertyTree* pComputer = &iter->query(); xpath.clear().appendf(XML_TAG_COMPUTER"["XML_ATTR_NETADDRESS"='%s']", pComputer->queryProp(XML_ATTR_NETADDRESS)); if (!pComputers->queryPropTree(xpath.str())) unlockComputers->addPropTree(XML_TAG_COMPUTER, createPTreeFromIPT(pComputer)); } } CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", unlockComputers->numChildren() ? unlockComputers : NULL); bool ret = unlockCloud.start(sbMsg); if (!ret || sbMsg.length()) { if (saveEnv) sbErrMsg.append("Save operation is successful. However, "); sbErrMsg.appendf("Write access to the Environment cannot be revoked. Reason(s):\n%s", sbMsg.str()); return; } else { Owned iter = unlockComputers->getElements("Computer"); StringBuffer xpath; ForEach (*iter) { IPropertyTree* pComputer = &iter->query(); xpath.clear().appendf(XML_TAG_COMPUTER"["XML_ATTR_NETADDRESS"='%s']", pComputer->queryProp(XML_ATTR_NETADDRESS)); IPropertyTree* pDelComputer = m_lockedNodesBeforeEnv->queryPropTree(xpath.str()); m_lockedNodesBeforeEnv->removeTree(pDelComputer); } } if (lockComputers->numChildren()) { CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", lockComputers); ret = lockCloud.start(sbMsg.clear()); if (!ret || sbMsg.length()) { if (saveEnv) sbErrMsg.append("Save operation is successful. However, "); sbErrMsg.appendf("Write access to the Environment could not be obtained. Reason(s):\n%s", sbMsg.str()); return; } } } m_Environment.clear(); StringBuffer sb(m_userWithLock); sb.append(m_userIp); CClientAliveThread* th = m_keepAliveHTable.getValue(sb.str()); if (th) { th->Release(); m_keepAliveHTable.remove(sb.str()); } if (m_envFile.length() == 0) { Owned serverGroup = createIGroup(m_daliServer.str(), m_daliServerPort); if (!serverGroup) throw MakeStringException(0, "Could not instantiate IGroup"); if (!initClientProcess(serverGroup, DCR_Config, 0, NULL, NULL, 10000)) throw MakeStringException(0, "Could not initialize the client process"); m_pSubscription.clear(); m_pSubscription.setown( new CSdsSubscription(this) ); Owned factory = getEnvironmentFactory(); m_constEnvRdOnly.setown(factory->openEnvironment()); } m_constEnvRdOnly->clearCache(); m_userWithLock.clear(); m_userIp.clear(); Owned pNavTree(getEnvTree(*context, reqInfo)); if (!areMatchingPTrees(pNavTree, m_pNavTree)) { m_pEnvXml.clear(); m_pGraphXml.clear(); m_pNavTree.clear(); m_pNavTree.setown(getEnvTree(*context, reqInfo)); } } void CWsDeployFileInfo::checkForRefresh(IEspContext &context, IConstWsDeployReqInfo *reqInfo, bool checkWriteAccess) { StringBuffer sbUser, sbIp; if (reqInfo) sbUser.clear().append(reqInfo->getUserId()); context.getPeer(sbIp); if (checkWriteAccess) { if (!m_Environment || m_userWithLock.length() == 0 || m_userIp.length() == 0) throw MakeStringException(-1, "Cannot modify environment as it is currently in readonly mode"); else if (m_userWithLock.length() != 0 && m_userIp.length() != 0 && (strcmp(m_userWithLock.str(), sbUser.str()) || strcmp(m_userIp.str(), sbIp.str()))) throw MakeStringException(-1, "Cannot modify setting as environment is currently in use on machine '%s'", m_userIp.str()); } } IPropertyTree* CWsDeployFileInfo::queryComputersForCloud() { Owned pEnvTree = m_Environment?&m_Environment->getPTree():&m_constEnvRdOnly->getPTree(); return pEnvTree->queryPropTree(XML_TAG_HARDWARE); } void CCloudTaskThread::main() { static Mutex m; m.lock(); try { m_pTask->makeSoapCall(); } catch(IException* e) { e->Release(); } m.unlock(); } CCloudTask* createCloudTask(CCloudActionHandler* pHandler, EnvAction eA, const char* ip) { return new CCloudTask(pHandler, eA, ip); } bool CWsDeployFileInfo::updateEnvironment(const char* xml) { if (!xml || !*xml) return false; Owned factory = getEnvironmentFactory(); m_constEnvRdOnly.setown(factory->loadLocalEnvironment(xml)); return true; } bool CWsDeployFileInfo::isLocked(StringBuffer& sbUser, StringBuffer& sbIp) { if (m_userIp.length() != 0 && m_userWithLock.length() != 0) { sbUser.clear().append(m_userWithLock); sbIp.clear().append(m_userIp); return true; } return false; } bool CWsDeployFileInfo::buildEnvironment(IEspContext &context, IEspBuildEnvironmentRequest &req, IEspBuildEnvironmentResponse &resp) { synchronized block(m_mutex); resp.setStatus("false"); const char* xml = req.getXmlArgs(); StringBuffer sbName, sbUserIp, msg, envXml; sbName.clear().append(req.getReqInfo().getUserId()); context.getPeer(sbUserIp); if(m_userWithLock.length() > 0) { if(!strcmp(sbName.str(), m_userWithLock.str()) || !strcmp(sbUserIp.str(), m_userIp.str())) { buildEnvFromWizard(xml, m_pService->getName(), m_pService->getCfg(), envXml); if(envXml.length()) { resp.setStatus("true"); if(m_Environment != NULL) { m_Environment.clear(); } Owned factory = getEnvironmentFactory(); m_Environment.setown(factory->loadLocalEnvironment(envXml.str())); } else resp.setMessage("Failed to generated the environment xml for unknown reason"); } else{ sbName.append("Cannot generate environment, As environment is locked by ").append(m_userWithLock); resp.setMessage(sbName.str()); } } else resp.setMessage("Environment has not been locked."); return true; } bool CWsDeployFileInfo::getSubnetIPAddr(IEspContext &context, IEspGetSubnetIPAddrRequest &req, IEspGetSubnetIPAddrResponse &resp) { synchronized block(m_mutex); resp.setIPList(""); resp.setMessage(""); StringBuffer ipList, msg, script; StringBuffer xpath ; xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalConfFile",m_pService->getName()); const char* pConfFile = m_pService->getCfg()->queryProp(xpath.str()); if( pConfFile && *pConfFile) { Owned pParams = createProperties(pConfFile); Owned iter = pParams->getIterator(); pParams->getProp("autodetectipscript", script); if( script.length()) { runScript(ipList, msg, script.str()); if( ipList.length()) { try { ipList.replace('\n', ';'); validateIPS(ipList.str()); resp.setIPList(ipList); } catch(IException* e) { StringBuffer sb; e->errorMessage(sb); e->Release(); resp.setMessage(sb.str()); } } else if( msg.length()) { resp.setMessage(msg); } } else resp.setMessage("Could not find the autodetectipscript entry in configmgr.conf"); } else resp.setMessage("Unknown Exception. Could not get the List of IPAddresses"); return true; } void CWsDeployFileInfo::CLockerAliveThread::main() { while (!m_quitThread) { try { StringBuffer sbMsg; CCloudActionHandler checkLocker(this->m_pFileInfo, CLOUD_CHECK_LOCKER, CLOUD_NONE, m_user.str(), "8015", m_pComputers); bool ret = checkLocker.start(sbMsg); String str(sbMsg.str()); if (str.startsWith("SOAP Connection error")) { m_pFileInfo->activeUserNotResponding(); m_quitThread = true; break; } m_sem.wait(m_brokenConnTimeout); } catch(IException* e) { if (m_pFileInfo && m_quitThread != true) m_pFileInfo->activeUserNotResponding(); m_quitThread = true; e->Release(); } } } const char* getFnString(EnvAction ea) { const char* ret = NULL; switch(ea) { case CLOUD_LOCK_ENV: ret = "LockEnvironmentForCloud"; break; case CLOUD_UNLOCK_ENV: ret = "UnlockEnvironmentForCloud"; break; case CLOUD_SAVE_ENV: ret = "SaveEnvironmentForCloud"; break; case CLOUD_ROLLBACK_ENV: ret = "RollbackEnvironmentForCloud"; break; case CLOUD_NOTIFY_INITSYSTEM: ret = "NotifyInitSystemSaveEnvForCloud"; break; case CLOUD_CHECK_LOCKER: ret = "GetValue"; break; } return ret; } bool CWsDeployFileInfo::getSummary(IEspContext &context, IEspGetSummaryRequest &req, IEspGetSummaryResponse &resp) { synchronized block(m_mutex); StringBuffer respXmlStr; resp.setStatus("false"); bool link = req.getPrepareLinkFlag(); Owned pEnvRoot = getEnvTree(context, &req.getReqInfo()); ::getSummary(pEnvRoot, respXmlStr, link); if(respXmlStr.length()) { resp.setStatus("true"); resp.setXmlStr(respXmlStr.str()); } return true; } void CWsDeployFileInfo::initFileInfo(bool createOrOverwrite) { StringBuffer xpath; m_skipEnvUpdateFromNotification = false; m_activeUserNotResp = false; bool fileExists = true; StringBuffer sbxml; if (!checkFileExists(m_envFile) || createOrOverwrite) { fileExists = false; StringBuffer s(""); Owned pNewTree = createPTreeFromXMLString(s); if ( strlen(m_pService->m_configHelper.getBuildSetFilePath()) > 0 ) { try { Owned pDefBldSet = createPTreeFromXMLFile( m_pService->m_configHelper.getBuildSetFilePath() ); pNewTree->addPropTree(XML_TAG_PROGRAMS, createPTreeFromIPT(pDefBldSet->queryPropTree("./Programs"))); pNewTree->addPropTree(XML_TAG_SOFTWARE, createPTreeFromIPT(pDefBldSet->queryPropTree("./Software"))); } catch(IException* e) { e->Release(); } } if(!pNewTree->queryPropTree(XML_TAG_SOFTWARE)) { pNewTree->addPropTree(XML_TAG_SOFTWARE, createPTree()); pNewTree->addPropTree("./Software/Directories", createPTreeFromXMLString(DEFAULT_DIRECTORIES)); } pNewTree->addPropTree(XML_TAG_HARDWARE, createPTree()); if (!pNewTree->queryPropTree(XML_TAG_PROGRAMS)) pNewTree->addPropTree(XML_TAG_PROGRAMS, createPTree()); toXML(pNewTree, s.clear()); sbxml.clear().append(s); if (createOrOverwrite) { if (m_pFileIO.get() != NULL) m_pFileIO.clear(); if (m_pFile.get() != NULL) { m_pFile->remove(); m_pFile.clear(); } if (m_lastSaved.isNull()) m_lastSaved.setNow(); recursiveCreateDirectoryForFile(m_envFile); Owned f = createIFile(m_envFile); Owned fio = f->open(IFOcreaterw); fio->write(0,s.length(),s.str()); fileExists = true; } } if (fileExists) { if (m_pFile.get() != NULL) m_pFile.clear(); if (m_pFileIO.get() != NULL) m_pFileIO.clear(); if (m_lastSaved.isNull()) m_lastSaved.setNow(); m_pFile.setown(createIFile(m_envFile)); m_pFileIO.setown(m_pFile->open(IFOread)); { Owned pTree = createPTree(*m_pFileIO); toXML(pTree, sbxml.clear()); } } Owned factory = getEnvironmentFactory(); m_Environment.setown(factory->loadLocalEnvironment(sbxml.str())); //add env bool modified = false; Owned pEnvRoot = &m_Environment->getPTree(); IPropertyTree* pSettings = pEnvRoot->queryPropTree(XML_TAG_ENVSETTINGS); if (!pSettings) { pSettings = pEnvRoot->addPropTree(XML_TAG_ENVSETTINGS, createPTree()); modified = true; } xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvConfFile", m_pService->getName()); const char* tmp = m_pService->getCfg()->queryProp(xpath.str()); if (tmp && *tmp) { Owned pParams = createProperties(tmp); Owned iter = pParams->getIterator(); ForEach(*iter) { StringBuffer prop; pParams->getProp(iter->getPropKey(), prop); const char* val = pSettings->queryProp(iter->getPropKey()); if (!val || strcmp(val, prop.str())) { pSettings->setProp(iter->getPropKey(), prop.length() ? prop.str():""); modified = true; } } if (updateDirsWithConfSettings(pEnvRoot, pParams)) modified = true; } try { StringBuffer err; if (modified && fileExists) saveEnvironment(NULL, NULL, err); } catch (IErrnoException* e) { //Don't ignore file access exceptions throw e; } catch(IException* e) { //ignore any exceptions at this point like validation errors e.t.c e->Release(); } if (!fileExists) toXML(pEnvRoot, sbxml.clear()); m_Environment.clear(); if (m_constEnvRdOnly.get() == NULL) { if (fileExists) { sbxml.clear(); Owned pTree = createPTree(*m_pFileIO); toXML(pTree, sbxml); } m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sbxml.str())); } } void CWsDeployFileInfo::CSdsSubscription::notify(SubscriptionId id, const char *xpath, SDSNotifyFlags flags, unsigned valueLen, const void *valueData) { DBGLOG("Environment was updated by another client of Dali server. Invalidating cache.\n"); //if (id != sub_id) m_pFileInfo->environmentUpdated(); } void CWsDeployExCE::getLastStarted(StringBuffer& sb) { synchronized block(m_mutexSrv); m_lastStarted.getString(sb); } CWsDeployFileInfo::~CWsDeployFileInfo() { if (m_bCloud && m_userWithLock.length() && m_userIp.length()) { StringBuffer sbMsg; CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", m_lockedNodesBeforeEnv.get()? m_lockedNodesBeforeEnv.get(): NULL); unlockCloud.start(sbMsg); } m_pNavTree.clear(); m_pGraphXml.clear(); m_Environment.clear(); m_constEnvRdOnly.clear(); m_pSubscription.clear(); m_pEnvXml.clear(); m_pFile.clear(); m_pFileIO.clear(); m_lockedNodesBeforeEnv.clear(); m_pGenJSFactoryThread.clear(); m_keepAliveHTable.kill(); } bool CWsDeployEx::onNavMenuEvent(IEspContext &context, IEspNavMenuEventRequest &req, IEspNavMenuEventResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); const char* cmd = req.getCmd(); if (!strcmp(cmd, "ValidateEnvironment") || !strcmp(cmd, "SaveEnvironment") || !strcmp(cmd, "SaveEnvironmentAs")) { synchronized block(m_mutexSrv); return fi->navMenuEvent(context, req, resp); } else return fi->navMenuEvent(context, req, resp); } bool CWsDeployEx::onSaveSetting(IEspContext &context, IEspSaveSettingRequest &req, IEspSaveSettingResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); return fi->saveSetting(context, req, resp); } bool CWsDeployEx::onGetNavTreeDefn(IEspContext &context, IEspGetNavTreeDefnRequest &req, IEspGetNavTreeDefnResponse &resp) { const char* xmlArg = req.getXmlArgs(); StringBuffer decodedParams(xmlArg); decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* create = pParams->queryProp("createFile"); CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true, create && *create ? true : false); return fi->getNavTreeDefn(context, req, resp); } bool CWsDeployEx::onLockEnvironmentForCloud(IEspContext &context, IEspLockEnvironmentForCloudRequest &req, IEspLockEnvironmentForCloudResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->lockEnvironmentForCloud(context, req, resp); } bool CWsDeployEx::onUnlockEnvironmentForCloud(IEspContext &context, IEspUnlockEnvironmentForCloudRequest &req, IEspUnlockEnvironmentForCloudResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->unlockEnvironmentForCloud(context, req, resp); } bool CWsDeployEx::onSaveEnvironmentForCloud(IEspContext &context, IEspSaveEnvironmentForCloudRequest &req, IEspSaveEnvironmentForCloudResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->saveEnvironmentForCloud(context, req, resp); } bool CWsDeployEx::onRollbackEnvironmentForCloud(IEspContext &context, IEspRollbackEnvironmentForCloudRequest &req, IEspRollbackEnvironmentForCloudResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->rollbackEnvironmentForCloud(context, req, resp); } bool CWsDeployEx::onNotifyInitSystemSaveEnvForCloud(IEspContext &context, IEspNotifyInitSystemSaveEnvForCloudRequest &req, IEspNotifyInitSystemSaveEnvForCloudResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->notifyInitSystemSaveEnvForCloud(context, req, resp); } bool CWsDeployExCE::onGetValue(IEspContext &context, IEspGetValueRequest &req, IEspGetValueResponse &resp) { //Check for common properties here StringBuffer decodedParams(req.getParams()); if (decodedParams.length() == 0) { resp.setReqValue(""); resp.setStatus("true"); return true; } decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszQueryType = pParams->queryProp("queryType"); const char* pszparams = pParams->queryProp("params"); const char* pszAttrValue = pParams->queryProp("attrValue"); StringBuffer xpath; const char* pszValue = NULL; StringBuffer sbMultiple; bool allHandled = true; if (pszQueryType && !strcmp(pszQueryType, "customType")) { sbMultiple.clear(); if(pszparams && *pszparams) { StringArray sArray; DelimToStringArray(pszparams, sArray, ","); for(unsigned i = 0; i < sArray.ordinality() ; i++) { if(!strcmp(sArray.item(i), "environment")) { xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvFile", getName()); const char* pEnvFile = getCfg()->queryProp(xpath.str()); if (pEnvFile && *pEnvFile) { if (checkFileExists(pEnvFile)) sbMultiple.append(sArray.item(i)).append("=true"); else sbMultiple.append(sArray.item(i)).append("=false"); if(sbMultiple.length()) sbMultiple.append(","); } } else if(!strcmp(sArray.item(i), "username")) { StringBuffer sbName; sbName.clear().append(msTick()); sbMultiple.append(sArray.item(i)).append("=").append(sbName); if(sbMultiple.length()) sbMultiple.append(","); } else if(!strcmp(sArray.item(i), "defenvfile")) { if (strstr(m_envFile.str(), m_sourceDir.str())) { StringBuffer sb(m_envFile.str() + m_sourceDir.length() + 1); sbMultiple.append(sArray.item(i)).append("=").append(sb.str()); if(sbMultiple.length()) sbMultiple.append(","); } } else if(!strcmp(sArray.item(i), "checklock")) { //StringBuffer sb(m_sourceDir); //if (sb.charAt[sb.length() - 1] != PATHSEPCHAR) // sb.append(PATHSEPCHAR); //sb.append(req.getFileName()); //if (checkFileExists(sb.str())) allHandled = false; } else if(!strcmp(sArray.item(i), "encryptpassword")) { if(pszAttrValue && *pszAttrValue) { StringArray sArray; DelimToStringArray(pszAttrValue, sArray, ","); ForEachItemIn(x, sArray) { StringBuffer encryptedPasswd ; encrypt(encryptedPasswd , sArray.item(x)); sbMultiple.append(encryptedPasswd.str()); if(sbMultiple.length()) sbMultiple.append(","); } } } else if(!strcmp(sArray.item(i), "lastsaved")) { allHandled = false; } else if(!strcmp(sArray.item(i), "laststarted")) { StringBuffer lastStarted; getLastStarted(lastStarted); if(lastStarted.length()) sbMultiple.append(sArray.item(i)).append("=").append(lastStarted); else sbMultiple.append(sArray.item(i)).append("=''"); if(sbMultiple.length()) sbMultiple.append(","); } else if(!strcmp(sArray.item(i), "wizops")) { StringBuffer sbOps; this->getWizOptions(sbOps); sbMultiple.append(sArray.item(i)).append("=").append(sbOps); if(sbMultiple.length()) sbMultiple.append(","); } } } pszValue = sbMultiple.str(); } else if (pszQueryType && !strcmp(pszQueryType, "sourceEnvironments")) { sbMultiple.clear(); Owned pDir = createIFile(getSourceDir()); if (pDir->exists()) { if (pDir->isDirectory()) { Owned it = pDir->directoryFiles(NULL, false, true); ForEach(*it) { StringBuffer name; it->getName(name); String str(name.toLowerCase()); if (str.endsWith(".xml")) { StringBuffer sb(getSourceDir()); sb.append(PATHSEPCHAR).append(it->getName(name.clear())); try { Owned pTree = createPTreeFromXMLFile(sb.str()); if (pTree && pTree->queryName() && !strcmp(XML_TAG_ENVIRONMENT, pTree->queryName())) sbMultiple.append(it->getName(name.clear())).append(";"); } catch(IException* e) { e->Release(); //add any files already in use CWsDeployFileInfo* fi = m_fileInfos.getValue(name.str()); if (fi) sbMultiple.append(name).append(";"); } } } } } pszValue = sbMultiple.str(); } else if (pszQueryType && *pszQueryType) allHandled = false; if (allHandled) { resp.setReqValue(pszValue); resp.setStatus("true"); return true; } else { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); bool ret = fi->getValue(context, req, resp); if (ret) { const char* val = resp.getReqValue(); StringBuffer sb; if (pszValue) sb.append(pszValue); sb.append(val); resp.setReqValue(sb.str()); resp.setStatus("true"); } return ret; } } bool CWsDeployExCE::onUnlockUser(IEspContext &context, IEspUnlockUserRequest &req, IEspUnlockUserResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->unlockUser(context, req, resp); } bool CWsDeployExCE::onClientAlive(IEspContext &context, IEspClientAliveRequest &req, IEspClientAliveResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); return fi->clientAlive(context, req, resp); } bool CWsDeployExCE::onGetEnvironment(IEspContext &context, IEspGetEnvironmentRequest &req, IEspGetEnvironmentResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(m_envFile.str()); return fi->getEnvironment(context, req, resp); } bool CWsDeployExCE::onSetEnvironment(IEspContext &context, IEspSetEnvironmentRequest &req, IEspSetEnvironmentResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(m_envFile.str()); return fi->setEnvironment(context, req, resp); } bool CWsDeployEx::onDisplaySettings(IEspContext &context, IEspDisplaySettingsRequest &req, IEspDisplaySettingsResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->displaySettings(context, req, resp); } bool CWsDeployEx::onStartDeployment(IEspContext &context, IEspStartDeploymentRequest &req, IEspStartDeploymentResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->startDeployment(context, req, resp); } bool CWsDeployEx::onGetDeployableComps(IEspContext &context, IEspGetDeployableCompsRequest &req, IEspGetDeployableCompsResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->getDeployableComps(context, req, resp); } bool CWsDeployEx::onGetComputersForRoxie(IEspContext &context, IEspGetComputersForRoxieRequest &req, IEspGetComputersForRoxieResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->getComputersForRoxie(context, req, resp); } bool CWsDeployEx::onHandleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleRoxieOperation(context, req, resp); } bool CWsDeployEx::onGetBuildSetInfo(IEspContext &context, IEspGetBuildSetInfoRequest &req, IEspGetBuildSetInfoResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->getBuildSetInfo(context, req, resp); } bool CWsDeployEx::onImportBuild(IEspContext &context, IEspImportBuildRequest &req, IEspImportBuildResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->importBuild(context, req, resp); } bool CWsDeployEx::onGetBuildServerDirs(IEspContext &context, IEspGetBuildServerDirsRequest &req, IEspGetBuildServerDirsResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->getBuildServerDirs(context, req, resp); } bool CWsDeployEx::onHandleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleComponent(context, req, resp); } bool CWsDeployEx::onHandleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleInstance(context, req, resp); } bool CWsDeployEx::onHandleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleEspServiceBindings(context, req, resp); } bool CWsDeployEx::onHandleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleComputer(context, req, resp); } bool CWsDeployEx::onHandleTopology(IEspContext &context, IEspHandleTopologyRequest &req, IEspHandleTopologyResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleTopology(context, req, resp); } bool CWsDeployEx::onHandleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleThorTopology(context, req, resp); } bool CWsDeployEx::onHandleRows(IEspContext &context, IEspHandleRowsRequest &req, IEspHandleRowsResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->handleRows(context, req, resp); } bool CWsDeployEx::onGraph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp) { CWsDeployFileInfo* fi = getFileInfo(m_envFile.str()); return fi->graph(context, req, resp); } void CWsDeployExCE::getNavigationData(IEspContext &context, IPropertyTree* pData) { CWsDeployFileInfo* fi = getFileInfo(m_envFile.str()); return fi->getNavigationData(context, pData); } bool CWsDeployExCE::onBuildEnvironment(IEspContext &context, IEspBuildEnvironmentRequest &req, IEspBuildEnvironmentResponse &resp) { String sb(req.getReqInfo().getFileName()); StringBuffer sbnew(req.getReqInfo().getFileName()); String* tmp = sb.toLowerCase(); if (!tmp->endsWith(".xml")) sbnew.appendf(".xml"); delete tmp; CWsDeployFileInfo* fi = getFileInfo(sbnew.str()); return fi->buildEnvironment(context, req, resp); } bool CWsDeployExCE::onGetSubnetIPAddr(IEspContext &context, IEspGetSubnetIPAddrRequest &req, IEspGetSubnetIPAddrResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->getSubnetIPAddr(context, req, resp); } bool CWsDeployExCE::onGetSummary(IEspContext &context, IEspGetSummaryRequest &req, IEspGetSummaryResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); return fi->getSummary(context, req, resp); } bool CWsDeployExCE::onAddReqdComps(IEspContext &context, IEspAddReqdCompsRequest &req, IEspAddReqdCompsResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); return fi->addReqdComps(context, req, resp); } bool CWsDeployEx::onDeploy(IEspContext &context, IEspDeployRequest& req, IEspDeployResponse& resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName()); return fi->deploy(context, req, resp); } CWsDeployFileInfo* CWsDeployExCE::getFileInfo(const char* fileName, bool addIfNotFound, bool createFile) { synchronized block(m_mutexSrv); if (!fileName || !*fileName) throw MakeStringException(-1, "File name required for operation"); CWsDeployFileInfo* fi = m_fileInfos.getValue(fileName); if (!fi) { if (addIfNotFound) { StringBuffer filePath(m_sourceDir); if (filePath.charAt(filePath.length() - 1) != PATHSEPCHAR) filePath.append(PATHSEPCHAR); filePath.append(fileName); fi = new CWsDeployFileInfo(this, filePath, m_bCloud); const char* psz = strrchr(fileName, PATHSEPCHAR); if (!psz) psz = strrchr(fileName, PATHSEPCHAR == '\\' ? '/' : '\\'); StringBuffer sb; if (!psz) sb.append(fileName); else sb.append(psz + 1); if (!sb.length()) sb.append(fileName); try { fi->initFileInfo(createFile); fi->m_configFileMonitorThread.clear(); fi->m_configFileMonitorThread.setown(new CWsDeployFileInfo::CConfigFileMonitorThread(fi, CONFIG_MONITOR_CHECK_INTERVAL, CONFIG_MONITOR_TIMEOUT_PERIOD)); fi->m_configFileMonitorThread->init(); } catch (IException* e) { delete fi; throw e; } m_fileInfos.setValue(sb.str(), fi); } else throw MakeStringException(-1, "File information not found for %s", fileName); } else if (createFile) { StringBuffer sbuser, sbip; if (fi->getUserWithLock(sbuser, sbip)) throw MakeStringException(-1, "Cannot overwrite file '%s' as it is currently locked by user '%s' on machine '%s'", fileName, sbuser.str(), sbip.str()); else { try { fi->initFileInfo(createFile); } catch (IException* e) { m_fileInfos.remove(fileName); delete fi; throw e; } } } return fi; } bool CWsDeployFileInfo::getUserWithLock(StringBuffer& sbUser, StringBuffer& sbIp) { if (m_userWithLock.length() && m_userIp.length()) { sbUser.clear().append(m_userWithLock); sbIp.clear().append(m_userIp); return true; } return false; } bool CWsDeployExCE::onNavMenuEvent(IEspContext &context, IEspNavMenuEventRequest &req, IEspNavMenuEventResponse &resp) { CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true); const char* cmd = req.getCmd(); if (!strcmp(cmd, "LockEnvironment") || !strcmp(cmd, "UnlockEnvironment")) return fi->navMenuEvent(context, req, resp); else return supportedInEEOnly(); } bool CWsDeployExCE::onSaveSetting(IEspContext &context, IEspSaveSettingRequest &req, IEspSaveSettingResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onGetNavTreeDefn(IEspContext &context, IEspGetNavTreeDefnRequest &req, IEspGetNavTreeDefnResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onLockEnvironmentForCloud(IEspContext &context, IEspLockEnvironmentForCloudRequest &req, IEspLockEnvironmentForCloudResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onUnlockEnvironmentForCloud(IEspContext &context, IEspUnlockEnvironmentForCloudRequest &req, IEspUnlockEnvironmentForCloudResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onSaveEnvironmentForCloud(IEspContext &context, IEspSaveEnvironmentForCloudRequest &req, IEspSaveEnvironmentForCloudResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onRollbackEnvironmentForCloud(IEspContext &context, IEspRollbackEnvironmentForCloudRequest &req, IEspRollbackEnvironmentForCloudResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onNotifyInitSystemSaveEnvForCloud(IEspContext &context, IEspNotifyInitSystemSaveEnvForCloudRequest &req, IEspNotifyInitSystemSaveEnvForCloudResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onDisplaySettings(IEspContext &context, IEspDisplaySettingsRequest &req, IEspDisplaySettingsResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onStartDeployment(IEspContext &context, IEspStartDeploymentRequest &req, IEspStartDeploymentResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onGetDeployableComps(IEspContext &context, IEspGetDeployableCompsRequest &req, IEspGetDeployableCompsResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onGetBuildServerDirs(IEspContext &context, IEspGetBuildServerDirsRequest &req, IEspGetBuildServerDirsResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onImportBuild(IEspContext &context, IEspImportBuildRequest &req, IEspImportBuildResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onGetComputersForRoxie(IEspContext &context, IEspGetComputersForRoxieRequest &req, IEspGetComputersForRoxieResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleTopology(IEspContext &context, IEspHandleTopologyRequest &req, IEspHandleTopologyResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onHandleRows(IEspContext &context, IEspHandleRowsRequest &req, IEspHandleRowsResponse &resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onGraph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onDeploy(IEspContext &context, IEspDeployRequest& req, IEspDeployResponse& resp) { return supportedInEEOnly(); } bool CWsDeployExCE::onGetBuildSetInfo(IEspContext &context, IEspGetBuildSetInfoRequest &req, IEspGetBuildSetInfoResponse &resp) { return supportedInEEOnly(); } bool CWsDeployEx::onGetValue(IEspContext &context, IEspGetValueRequest &req, IEspGetValueResponse &resp) { //Check for common properties here StringBuffer decodedParams(req.getParams()); if (decodedParams.length() == 0) { resp.setReqValue(""); resp.setStatus("true"); return true; } decodedParams.replaceString("::", "\n"); Owned pParams = createProperties(); pParams->loadProps(decodedParams.str()); const char* pszQueryType = pParams->queryProp("queryType"); const char* pszparams = pParams->queryProp("params"); const char* pszAttrValue = pParams->queryProp("attrValue"); StringBuffer xpath; const char* pszValue = NULL; StringBuffer sbMultiple; bool allHandled = true; if (pszQueryType && !strcmp(pszQueryType, "customType")) { sbMultiple.clear(); if(pszparams && *pszparams) { StringArray sArray; DelimToStringArray(pszparams, sArray, ","); for(unsigned i = 0; i < sArray.ordinality() ; i++) { if(!strcmp(sArray.item(i), "wizops")) { StringBuffer sbOps; this->getWizOptions(sbOps); sbMultiple.append(sArray.item(i)).append("=").append(sbOps); if(sbMultiple.length()) sbMultiple.append(","); } else allHandled = false; } } pszValue = sbMultiple.str(); } else if (pszQueryType && *pszQueryType) allHandled = false; if (allHandled) { resp.setReqValue(pszValue); resp.setStatus("true"); return true; } else { bool ret = CWsDeployExCE::onGetValue(context, req, resp); if (ret) { const char* val = resp.getReqValue(); StringBuffer sb; if (pszValue) sb.append(pszValue); sb.append(val); resp.setReqValue(sb.str()); resp.setStatus("true"); } return ret; } } void CWsDeployExCE::getWizOptions(StringBuffer& sb) { sb.clear().append("1"); } void CWsDeployEx::getWizOptions(StringBuffer& sb) { sb.clear().append("3"); } CWsDeployExCE* createWsDeployEE(IPropertyTree *cfg, const char* name) { return new CWsDeployEx; } CWsDeployExCE* createWsDeployCE(IPropertyTree *cfg, const char* name) { StringBuffer sb; sb.append(XML_TAG_SOFTWARE"/"XML_TAG_ESPPROCESS"/"XML_TAG_ESPBINDING"/"); sb.appendf("["XML_ATTR_SERVICE"='%s']", name); IPropertyTree* pTree = cfg->queryPropTree(sb.str()); const char* ver = "CE"; if (pTree) ver = pTree->queryProp(XML_ATTR_VERSION); if (ver && *ver && !strcmp(ver, "EE")) return new CWsDeployEx; return new CWsDeployExCE; } bool CWsDeployFileInfo::checkForRequiredComponents(IPropertyTree* pEnvRoot, const char* ip, StringBuffer& reqdCompNames, bool autoadd/*=false*/) { StringBuffer prop, xpath, genEnvConf; Owned algProps; StringArray compOnAllNodes; bool retVal = true; xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalConfFile", m_pService->getName()); const char* pConfFile = m_pService->getCfg()->queryProp(xpath.str()); xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvConfFile", m_pService->getName()); const char* pEnvConfFile = m_pService->getCfg()->queryProp(xpath.str()); if (pConfFile && *pConfFile && pEnvConfFile && *pEnvConfFile) { Owned pParams = createProperties(pConfFile); Owned pEnvParams = createProperties(pEnvConfFile); const char* genenv = pParams->queryProp("wizardalgorithm"); if (genenv && *genenv) { const char* cfgpath = pEnvParams->queryProp("configs"); if (!cfgpath || !*cfgpath) cfgpath = CONFIG_DIR; genEnvConf.clear().append(cfgpath); if (genEnvConf.charAt(genEnvConf.length() - 1) != PATHSEPCHAR) genEnvConf.append(PATHSEPCHAR); genEnvConf.append(genenv); if(checkFileExists(genEnvConf.str())) algProps.setown(createProperties(genEnvConf.str())); else throw MakeStringException( -1 , "The algorithm file %s does not exists", genEnvConf.str()); algProps->getProp("comps_on_all_nodes", prop); DelimToStringArray(prop.str(), compOnAllNodes, ","); const char* flag = pParams->queryProp("autoaddallnodescomp"); if (!autoadd) autoadd = (flag && *flag == '1') ? true : false; } } for(unsigned i = 0; i < compOnAllNodes.ordinality(); i++) { xpath.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", compOnAllNodes.item(i)); Owned buildSetIter = pEnvRoot->getElements(xpath.str()); buildSetIter->first(); IPropertyTree* pBuildSet; if (buildSetIter->isValid()) pBuildSet = &buildSetIter->query(); else continue; const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME); xpath.clear().appendf("./Software/%s[1]", processName); IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str()); if (!pCompTree) { if (autoadd) { StringBuffer buildSetPath, sbNewName; Owned pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment); xpath.clear().appendf("./Software/%s[@name='%s']", processName, compOnAllNodes.item(i)); pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, pBuildSet->queryProp(XML_ATTR_NAME), m_pService->getCfg(), m_pService->getName(), false); IPropertyTree* pInstTree = pCompTree->queryPropTree(XML_TAG_INSTANCE); if (pInstTree) pCompTree->removeTree(pInstTree); addComponentToEnv(pEnvRoot, compOnAllNodes.item(i), sbNewName, pCompTree); } else { reqdCompNames.appendf("%s\n", compOnAllNodes.item(i)); retVal = false; continue; } } xpath.clear().appendf(XML_TAG_INSTANCE"["XML_ATTR_NETADDRESS"='%s']", ip); IPropertyTree* pInst = pCompTree->queryPropTree(xpath.str()); if (!pInst) { if (autoadd) { StringBuffer sb, sbl, compName, nodeName; xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_HARDWARE, XML_TAG_COMPUTER, XML_ATTR_NETADDRESS, ip); IPropertyTree* computer = pEnvRoot->queryPropTree(xpath.str()); if(computer) { nodeName.clear().append(computer->queryProp(XML_ATTR_NAME)); xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, processName, XML_ATTR_BUILDSET, compOnAllNodes.item(i)); sb.clear().appendf("", compOnAllNodes.item(i), pCompTree->queryProp(XML_ATTR_NAME), nodeName.str()); Owned pInstance = createPTreeFromXMLString(sb.str()); addInstanceToCompTree(pEnvRoot, pInstance, sbl.clear(), sb.clear(), NULL); } } else { reqdCompNames.appendf("%s\n", compOnAllNodes.item(i)); retVal = false; continue; } } } return retVal; }