ConfigEnv.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "EnvHelper.hpp"
  14. #include "ConfigEnv.hpp"
  15. #include "environment.hpp"
  16. #include "deployutils.hpp"
  17. #include "build-config.h"
  18. namespace ech
  19. {
  20. ConfigEnv::ConfigEnv(IPropertyTree *config)
  21. {
  22. m_envHelper = new EnvHelper(config);
  23. }
  24. ConfigEnv::~ConfigEnv()
  25. {
  26. if (m_envHelper)
  27. delete m_envHelper;
  28. }
  29. unsigned ConfigEnv::add(IPropertyTree *params)
  30. {
  31. const char * action = params->queryProp("@operation");
  32. if (stricmp(action, "add"))
  33. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Invoke add with a wrong operation %s ", action);
  34. const char* category = params->queryProp("@category");
  35. return m_envHelper->getEnvComp(category)->add(params);
  36. }
  37. void ConfigEnv::modify(IPropertyTree *params)
  38. {
  39. const char * action = params->queryProp("@operation");
  40. if (stricmp(action, "modify"))
  41. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Invoke modify with a wrong operation %s ", action);
  42. const char* category = params->queryProp("@category");
  43. m_envHelper->getEnvComp(category)->modify(params);
  44. }
  45. void ConfigEnv::create(IPropertyTree *params)
  46. {
  47. StringBuffer xpath, sbTemp;
  48. //fprintf(stdout, "create environment.xml ...\n");
  49. //Process ips
  50. m_envHelper->processNodeAddress(params);
  51. if (USE_WIZARD)
  52. {
  53. StringBuffer optionsXml, envXml;
  54. const char* pServiceName = "WsDeploy_wsdeploy_esp";
  55. int roxieNodes=1, thorNodes=1, slavesPerNode=1, supportNodes=1,
  56. espNodes=1, thorChannelsPerSlave=1, roxieChannelsPerSlave=1;
  57. bool roxieOnDemand = true;
  58. MapStringTo<StringAttr, const char *> dirMap;
  59. Owned<IPropertyTree> pCfg = createPTreeFromXMLFile(ESP_CONFIG_PATH);
  60. StringArray arrAssignIPRanges;
  61. StringArray arrBuildSetWithAssignedIPs;
  62. if (params->hasProp("@roxie-nodes"))
  63. roxieNodes = params->getPropInt("@roxie-nodes", 1);
  64. if (params->hasProp("@thor-nodes"))
  65. thorNodes = params->getPropInt("@thor-nodes", 1);
  66. if (params->hasProp("@slaves-per-node"))
  67. slavesPerNode = params->getPropInt("@slaves-per-node", 1);
  68. if (params->hasProp("@support-nodes"))
  69. supportNodes = params->getPropInt("@support-nodes", 1);
  70. if (params->hasProp("@esp-nodes"))
  71. espNodes = params->getPropInt("@esp-nodes", 1);
  72. if (params->hasProp("@roxie-on-demand"))
  73. roxieOnDemand = params->getPropBool("@roxie-on-demand", true);
  74. if (params->hasProp("@thor-channels-per-slave"))
  75. thorChannelsPerSlave = params->getPropInt("@thor-channels-per-slave", 1);
  76. if (params->hasProp("@roxie-channels-per-slave"))
  77. roxieChannelsPerSlave = params->getPropInt("@roxie-channels-per-slave", 1);
  78. StringBuffer ipAddr;
  79. const StringArray& ipList = m_envHelper->getNodeList();
  80. ipAddr.clear();
  81. ForEachItemIn(i, ipList)
  82. {
  83. if (ipAddr.length() > 0)
  84. ipAddr.append(";");
  85. ipAddr.append(ipList.item(i));
  86. }
  87. /*
  88. if (ipAddr.length() <= 0)
  89. {
  90. throw MakeStringException(return CfgEnvErrorCode::NoIPAddress,
  91. "Must provide either ip or ipfile. To do JIRA HPCC-15636");
  92. }
  93. */
  94. optionsXml.appendf("<XmlArgs supportNodes=\"%d\" roxieNodes=\"%d\" thorNodes=\"%d\" espNodes=\"%d\" slavesPerNode=\"%d\" roxieOnDemand=\"%s\" thorChannelsPerSlave=\"%d\" roxieChannelsPerSlave=\"%d\" ",
  95. supportNodes, roxieNodes, thorNodes, espNodes, slavesPerNode, roxieOnDemand?"true":"false", thorChannelsPerSlave, roxieChannelsPerSlave);
  96. if (ipAddr.length() > 0)
  97. optionsXml.appendf("ipList=\"%s\"/>", ipAddr.str());
  98. else
  99. optionsXml.appendf("/>");
  100. buildEnvFromWizard(optionsXml, pServiceName, pCfg, envXml, arrBuildSetWithAssignedIPs, arrAssignIPRanges, &dirMap);
  101. m_envHelper->setEnvTree(envXml);
  102. }
  103. else
  104. {
  105. //Hardware
  106. m_envHelper->getEnvComp("Hardware")->create(params);
  107. //Programs
  108. m_envHelper->getEnvComp("Programs")->create(params);
  109. //EnvSettings
  110. m_envHelper->getEnvComp("EnvSettings")->create(params);
  111. //Software
  112. m_envHelper->getEnvComp("Software")->create(params);
  113. }
  114. runUpdateTasks(params);
  115. /*
  116. const IPropertyTree * envTree = m_envHelper->getEnvTree();
  117. //output
  118. StringBuffer env, envXml;
  119. toXML(envTree, envXml, 0, XML_SortTags | XML_Format);
  120. env.clear().appendf("<" XML_HEADER ">\n");
  121. env.append(envXml);
  122. Owned<IFile> pFile;
  123. const char* envFile = params->queryProp("@env-out");
  124. //printf("output envxml to file %s\n", envFile);
  125. pFile.setown(createIFile(envFile));
  126. Owned<IFileIO> pFileIO;
  127. pFileIO.setown(pFile->open(IFOcreaterw));
  128. pFileIO->write(0, env.length(), env.str());
  129. */
  130. }
  131. void ConfigEnv::runUpdateTasks(IPropertyTree *params)
  132. {
  133. Owned<IPropertyTreeIterator> iter = params->getElements("Task");
  134. if (!iter) return;
  135. ForEach(*iter)
  136. {
  137. IPropertyTree* updateTree = &iter->query();
  138. const char * action = updateTree->queryProp("@operation");
  139. const char * category = updateTree->queryProp("@category");
  140. IConfigComp *categoryObj = m_envHelper->getEnvComp(category);
  141. assert(categoryObj);
  142. if (!stricmp(action, "add"))
  143. {
  144. categoryObj->add(updateTree);
  145. }
  146. else if (!stricmp(action, "modify"))
  147. categoryObj->modify(updateTree);
  148. else if (!stricmp(action, "remove"))
  149. categoryObj->remove(updateTree);
  150. else
  151. throw MakeStringException(CfgEnvErrorCode::UnknownTask, "Unknown operation %s on compoent %s", action, category);
  152. }
  153. }
  154. void ConfigEnv::remove(IPropertyTree *params)
  155. {
  156. const char * action = params->queryProp("@operation");
  157. if (stricmp(action, "remove"))
  158. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Invoke remove with a wrong operation %s ", action);
  159. const char* category = params->queryProp("@category");
  160. return m_envHelper->getEnvComp(category)->remove(params);
  161. }
  162. const char * ConfigEnv::queryAttribute(const char *xpath)
  163. {
  164. IPropertyTree * envTree = m_envHelper->getEnvTree();
  165. assert(envTree);
  166. return envTree->queryProp(xpath);
  167. }
  168. void ConfigEnv::setAttribute(const char *xpath , const char* attrName, const char* attrValue)
  169. {
  170. IPropertyTree * envTree = m_envHelper->getEnvTree();
  171. IPropertyTree * pAttrTree = envTree->queryPropTree(xpath);
  172. if (!pAttrTree)
  173. {
  174. pAttrTree = createPTree();
  175. pAttrTree->appendProp(attrName, attrValue);
  176. envTree->setPropTree(xpath, pAttrTree);
  177. }
  178. else
  179. pAttrTree->setProp(attrName, attrValue);
  180. }
  181. bool ConfigEnv::isEnvironmentValid(StringBuffer& env)
  182. {
  183. Owned<IEnvironmentFactory> factory = getEnvironmentFactory(false);
  184. Owned<IConstEnvironment> constEnv = factory->loadLocalEnvironment(env);
  185. return validateEnv(constEnv);
  186. }
  187. IPropertyTree * ConfigEnv::getNode(const char *xpath)
  188. {
  189. IPropertyTree * envTree = m_envHelper->getEnvTree();
  190. assert(envTree);
  191. return envTree->queryPropTree(xpath);
  192. }
  193. IPropertyTree * ConfigEnv::getNode(unsigned id)
  194. {
  195. return NULL;
  196. }
  197. unsigned ConfigEnv::getNodeId(char const *xpath)
  198. {
  199. return 0;
  200. }
  201. void ConfigEnv::getContent(const char* xpath, StringBuffer& out, int format)
  202. {
  203. IPropertyTree * envTree = m_envHelper->getEnvTree();
  204. assert(envTree);
  205. IPropertyTree *outPTree;
  206. if (!xpath || strcmp(xpath, "/"))
  207. outPTree = envTree;
  208. else
  209. {
  210. outPTree = envTree->queryPropTree(xpath);
  211. if (!outPTree)
  212. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Cannot find xpath %s to output", xpath);
  213. }
  214. StringBuffer envXml;
  215. toXML(envTree, envXml, 0, format);
  216. out.clear().appendf("<" XML_HEADER ">\n");
  217. out.append(envXml);
  218. }
  219. void ConfigEnv::addContent(const char* xpath, StringBuffer& in, int type)
  220. {
  221. if (!xpath)
  222. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Cannot insert content to NULL xpath");
  223. IPropertyTree * envTree = m_envHelper->getEnvTree();
  224. IPropertyTree *parent = envTree->queryPropTree(xpath);
  225. if (!parent)
  226. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Cannot find PTree with xpath %s to insert content.", xpath);
  227. IPropertyTree *child;
  228. switch (type)
  229. {
  230. case XML_Format:
  231. child = createPTreeFromXMLString(in.str());
  232. break;
  233. case JSON_Format:
  234. child = createPTreeFromJSONString(in.str());
  235. break;
  236. default:
  237. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Unsupported content type %d", type);
  238. }
  239. if (!child)
  240. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Fail to create PTree with input content.");
  241. const char *name = child->queryName();
  242. if (!name)
  243. throw MakeStringException(CfgEnvErrorCode::InvalidParams, "Cannot get tag name from newly created PTree from input content.");
  244. parent->addPropTree(name, child);
  245. // validate PTree
  246. }
  247. bool ConfigEnv::isAttributeValid(const char* xpath, const char* schema, const char* key, const char* value, bool src)
  248. {
  249. return true;
  250. }
  251. }