/*##############################################################################
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;
}