ws_packageprocessService.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 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. #pragma warning (disable : 4786)
  14. #include "ws_packageprocessService.hpp"
  15. #include "daclient.hpp"
  16. #include "dalienv.hpp"
  17. #include "dadfs.hpp"
  18. #include "dfuutil.hpp"
  19. #include "ws_fs.hpp"
  20. #include "ws_workunits.hpp"
  21. #include "packageprocess_errors.h"
  22. #include "referencedfilelist.hpp"
  23. #include "package.h"
  24. #define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
  25. void CWsPackageProcessEx::init(IPropertyTree *cfg, const char *process, const char *service)
  26. {
  27. }
  28. bool CWsPackageProcessEx::onEcho(IEspContext &context, IEspEchoRequest &req, IEspEchoResponse &resp)
  29. {
  30. StringBuffer respMsg;
  31. ISecUser* user = context.queryUser();
  32. if(user != NULL)
  33. {
  34. const char* name = user->getName();
  35. if (name && *name)
  36. respMsg.appendf("%s: ", name);
  37. }
  38. const char* reqMsg = req.getRequest();
  39. if (reqMsg && *reqMsg)
  40. respMsg.append(reqMsg);
  41. else
  42. respMsg.append("??");
  43. resp.setResponse(respMsg.str());
  44. return true;
  45. }
  46. IPropertyTree *getPkgSetRegistry(const char *id, const char *process, bool readonly)
  47. {
  48. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageSets/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  49. //Only lock the branch for the target we're interested in.
  50. StringBuffer xpath;
  51. xpath.append("/PackageSets/PackageSet[@id=\"").append(id).append("\"]");
  52. Owned<IRemoteConnection> conn = querySDS().connect(xpath.str(), myProcessSession(), readonly ? RTM_LOCK_READ : RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  53. if (!conn)
  54. {
  55. if (readonly)
  56. return NULL;
  57. Owned<IPropertyTree> querySet = createPTree();
  58. querySet->setProp("@id", id);
  59. if (!process || !*process)
  60. querySet->setProp("@process", "*");
  61. else
  62. querySet->setProp("@process", process);
  63. globalLock->queryRoot()->addPropTree("PackageSet", querySet.getClear());
  64. globalLock->commit();
  65. conn.setown(querySDS().connect(xpath.str(), myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT));
  66. if (!conn)
  67. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali %s", xpath.str());
  68. }
  69. return conn->getRoot();
  70. }
  71. ////////////////////////////////////////////////////////////////////////////////////////
  72. const unsigned roxieQueryRoxieTimeOut = 60000;
  73. #define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
  74. bool isRoxieProcess(const char *process)
  75. {
  76. if (!process)
  77. return false;
  78. Owned<IRemoteConnection> conn = querySDS().connect("Environment", myProcessSession(), RTM_LOCK_READ, SDS_LOCK_TIMEOUT);
  79. if (!conn)
  80. return false;
  81. VStringBuffer xpath("Software/RoxieCluster[@name=\"%s\"]", process);
  82. return conn->queryRoot()->hasProp(xpath.str());
  83. }
  84. bool isFileKnownOnCluster(const char *logicalname, const char *lookupDaliIp, IConstWUClusterInfo *clusterInfo, IUserDescriptor* userdesc)
  85. {
  86. Owned<IDistributedFile> dst = queryDistributedFileDirectory().lookup(logicalname, userdesc, true);
  87. if (dst)
  88. {
  89. SCMStringBuffer processName;
  90. clusterInfo->getRoxieProcess(processName);
  91. if (dst->findCluster(processName.str()) != NotFound)
  92. return true; // file already known for this cluster
  93. }
  94. return false;
  95. }
  96. bool isFileKnownOnCluster(const char *logicalname, const char *lookupDaliIp, const char *target, IUserDescriptor* userdesc)
  97. {
  98. Owned<IConstWUClusterInfo> clusterInfo = getTargetClusterInfo(target);
  99. if (!clusterInfo)
  100. throw MakeStringException(PKG_TARGET_NOT_DEFINED, "Could not find information about target cluster %s ", target);
  101. return isFileKnownOnCluster(logicalname, lookupDaliIp, clusterInfo, userdesc);
  102. }
  103. bool cloneFileInfoToDali(StringArray &fileNames, const char *lookupDaliIp, IConstWUClusterInfo *clusterInfo, bool overWrite, IUserDescriptor* userdesc)
  104. {
  105. bool retval = true;
  106. try
  107. {
  108. StringBuffer user;
  109. StringBuffer password;
  110. if (userdesc)
  111. {
  112. userdesc->getUserName(user);
  113. userdesc->getPassword(password);
  114. }
  115. Owned<IReferencedFileList> wufiles = createReferencedFileList(user, password);
  116. wufiles->addFiles(fileNames);
  117. SCMStringBuffer processName;
  118. clusterInfo->getRoxieProcess(processName);
  119. wufiles->resolveFiles(processName.str(), lookupDaliIp, !overWrite, false);
  120. wufiles->cloneAllInfo(overWrite, true);
  121. }
  122. catch(IException *e)
  123. {
  124. StringBuffer msg;
  125. e->errorMessage(msg);
  126. DBGLOG("ERROR = %s", msg.str());
  127. e->Release(); // report the error later if needed
  128. retval = false;
  129. }
  130. catch(...)
  131. {
  132. retval = false;
  133. }
  134. return retval;
  135. }
  136. bool cloneFileInfoToDali(StringArray &fileNames, const char *lookupDaliIp, const char *target, bool overWrite, IUserDescriptor* userdesc)
  137. {
  138. Owned<IConstWUClusterInfo> clusterInfo = getTargetClusterInfo(target);
  139. if (!clusterInfo)
  140. throw MakeStringException(PKG_TARGET_NOT_DEFINED, "Could not find information about target cluster %s ", target);
  141. return cloneFileInfoToDali(fileNames, lookupDaliIp, clusterInfo, overWrite, userdesc);
  142. }
  143. void makePackageActive(IPropertyTree *pkgSetRegistry, IPropertyTree *pkgSetTree, const char *setName)
  144. {
  145. VStringBuffer xpath("PackageMap[@querySet='%s'][@active='1']", setName);
  146. Owned<IPropertyTreeIterator> iter = pkgSetRegistry->getElements(xpath.str());
  147. ForEach(*iter)
  148. {
  149. iter->query().setPropBool("@active", false);
  150. }
  151. pkgSetTree->setPropBool("@active", true);
  152. }
  153. const char *buildPkgSetId(StringBuffer &pkgSetId, const char *processName)
  154. {
  155. pkgSetId.appendf("default_%s", processName);
  156. pkgSetId.replace('*', '#');
  157. pkgSetId.replace('?', '~');
  158. return pkgSetId.str();
  159. }
  160. //////////////////////////////////////////////////////////
  161. void addPackageMapInfo(IPropertyTree *pkgSetRegistry, const char *target, const char *packageMapName, const char *packageSetName, const char *lookupDaliIp, IPropertyTree *packageInfo, bool active, bool overWrite, IUserDescriptor* userdesc)
  162. {
  163. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  164. StringBuffer lcName(packageMapName);
  165. lcName.toLowerCase();
  166. StringBuffer xpath;
  167. xpath.append("PackageMap[@id='").append(lcName).append("']");
  168. IPropertyTree *pkgRegTree = pkgSetRegistry->queryPropTree(xpath.str());
  169. IPropertyTree *root = globalLock->queryRoot();
  170. IPropertyTree *mapTree = root->queryPropTree(xpath);
  171. if (!overWrite && (pkgRegTree || mapTree))
  172. throw MakeStringException(PKG_NAME_EXISTS, "Package name %s already exists, either delete it or specify overwrite", lcName.str());
  173. if (mapTree)
  174. root->removeTree(mapTree);
  175. if (pkgRegTree)
  176. pkgSetRegistry->removeTree(pkgRegTree);
  177. mapTree = root->addPropTree("PackageMap", createPTree());
  178. mapTree->addProp("@id", packageMapName);
  179. StringArray fileNames;
  180. Owned<IConstWUClusterInfo> clusterInfo = getTargetClusterInfo(target);
  181. if (!clusterInfo)
  182. throw MakeStringException(PKG_TARGET_NOT_DEFINED, "Could not find information about target cluster %s ", target);
  183. IPropertyTree *baseInfo = createPTree();
  184. Owned<IPropertyTreeIterator> iter = packageInfo->getElements("Package");
  185. ForEach(*iter)
  186. {
  187. IPropertyTree &item = iter->query();
  188. Owned<IPropertyTreeIterator> super_iter = item.getElements("SuperFile");
  189. if (super_iter->first())
  190. {
  191. ForEach(*super_iter)
  192. {
  193. IPropertyTree &supertree = super_iter->query();
  194. StringBuffer lc(supertree.queryProp("@id"));
  195. const char *id = lc.toLowerCase().str();
  196. if (*id == '~')
  197. id++;
  198. supertree.setProp("@id", id);
  199. Owned<IPropertyTreeIterator> sub_iter = supertree.getElements("SubFile");
  200. ForEach(*sub_iter)
  201. {
  202. IPropertyTree &subtree = sub_iter->query();
  203. StringAttr subid = subtree.queryProp("@value");
  204. if (subid.length())
  205. {
  206. if (subid[0] == '~')
  207. subtree.setProp("@value", subid+1);
  208. if (!isFileKnownOnCluster(subid, lookupDaliIp, clusterInfo, userdesc))
  209. fileNames.append(subid);
  210. }
  211. }
  212. mapTree->addPropTree("Package", LINK(&item));
  213. }
  214. }
  215. else
  216. {
  217. baseInfo->addPropTree("Package", LINK(&item));
  218. }
  219. }
  220. mergePTree(mapTree, baseInfo);
  221. cloneFileInfoToDali(fileNames, lookupDaliIp, clusterInfo, overWrite, userdesc);
  222. globalLock->commit();
  223. IPropertyTree *pkgSetTree = pkgSetRegistry->addPropTree("PackageMap", createPTree("PackageMap"));
  224. pkgSetTree->setProp("@id", lcName);
  225. pkgSetTree->setProp("@querySet", target);
  226. if (active)
  227. makePackageActive(pkgSetRegistry, pkgSetTree, target);
  228. else
  229. pkgSetTree->setPropBool("@active", false);
  230. }
  231. void getPackageListInfo(IPropertyTree *mapTree, IEspPackageListMapData *pkgList)
  232. {
  233. pkgList->setId(mapTree->queryProp("@id"));
  234. pkgList->setTarget(mapTree->queryProp("@querySet"));
  235. Owned<IPropertyTreeIterator> iter = mapTree->getElements("Package");
  236. IArrayOf<IConstPackageListData> results;
  237. ForEach(*iter)
  238. {
  239. IPropertyTree &item = iter->query();
  240. Owned<IEspPackageListData> res = createPackageListData("", "");
  241. res->setId(item.queryProp("@id"));
  242. if (item.hasProp("@queries"))
  243. res->setQueries(item.queryProp("@queries"));
  244. results.append(*res.getClear());
  245. }
  246. pkgList->setPkgListData(results);
  247. }
  248. void getAllPackageListInfo(IPropertyTree *mapTree, StringBuffer &info)
  249. {
  250. info.append("<PackageMap id='").append(mapTree->queryProp("@id")).append("'");
  251. Owned<IPropertyTreeIterator> iter = mapTree->getElements("Package");
  252. ForEach(*iter)
  253. {
  254. IPropertyTree &item = iter->query();
  255. info.append("<Package id='").append(item.queryProp("@id")).append("'");
  256. if (item.hasProp("@queries"))
  257. info.append(" queries='").append(item.queryProp("@queries")).append("'");
  258. info.append("></Package>");
  259. }
  260. info.append("</PackageMap>");
  261. }
  262. void listPkgInfo(const char *target, const char *process, IArrayOf<IConstPackageListMapData>* results)
  263. {
  264. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  265. if (!globalLock)
  266. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali /PackageMaps");
  267. IPropertyTree *root = globalLock->queryRoot();
  268. Owned<IPropertyTree> pkgSetRegistry = getPkgSetRegistry((process && *process) ? process : "*", NULL, true);
  269. if (!pkgSetRegistry)
  270. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali for process %s", (process && *process) ? process : "*");
  271. StringBuffer xpath("PackageMap");
  272. if (target && *target)
  273. xpath.appendf("[@querySet='%s']", target);
  274. Owned<IPropertyTreeIterator> iter = pkgSetRegistry->getElements(xpath.str());
  275. ForEach(*iter)
  276. {
  277. IPropertyTree &item = iter->query();
  278. const char *id = item.queryProp("@id");
  279. if (id)
  280. {
  281. StringBuffer xpath;
  282. xpath.append("PackageMap[@id='").append(id).append("']");
  283. IPropertyTree *mapTree = root->queryPropTree(xpath);
  284. Owned<IEspPackageListMapData> res = createPackageListMapData("", "");
  285. res->setActive(item.getPropBool("@active"));
  286. getPackageListInfo(mapTree, res);
  287. results->append(*res.getClear());
  288. }
  289. }
  290. }
  291. void getPkgInfo(const char *target, const char *process, StringBuffer &info)
  292. {
  293. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  294. if (!globalLock)
  295. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali /PackageMaps");
  296. IPropertyTree *root = globalLock->queryRoot();
  297. Owned<IPropertyTree> tree = createPTree("PackageMaps");
  298. Owned<IPropertyTree> pkgSetRegistry = getPkgSetRegistry((process && *process) ? process : "*", NULL, true);
  299. StringBuffer xpath("PackageMap[@active='1']");
  300. if (target && *target)
  301. xpath.appendf("[@querySet='%s']", target);
  302. Owned<IPropertyTreeIterator> iter = pkgSetRegistry->getElements(xpath.str());
  303. ForEach(*iter)
  304. {
  305. IPropertyTree &item = iter->query();
  306. const char *id = item.queryProp("@id");
  307. if (id)
  308. {
  309. StringBuffer xpath;
  310. xpath.append("PackageMap[@id='").append(id).append("']");
  311. IPropertyTree *mapTree = root->queryPropTree(xpath);
  312. if (mapTree)
  313. mergePTree(tree, mapTree);
  314. }
  315. }
  316. toXML(tree, info);
  317. }
  318. bool deletePkgInfo(const char *packageMap, const char *target, const char *process)
  319. {
  320. Owned<IRemoteConnection> pkgSet = querySDS().connect("/PackageSets/", myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  321. if (!pkgSet)
  322. throw MakeStringException(PKG_NONE_DEFINED, "No package sets defined");
  323. IPropertyTree* packageSets = pkgSet->queryRoot();
  324. StringBuffer pkgSetId;
  325. buildPkgSetId(pkgSetId, process);
  326. VStringBuffer pkgSet_xpath("PackageSet[@id='%s']", pkgSetId.str());
  327. IPropertyTree *pkgSetRegistry = packageSets->queryPropTree(pkgSet_xpath.str());
  328. if (!pkgSetRegistry)
  329. throw MakeStringException(PKG_TARGET_NOT_DEFINED, "No package sets defined for %s", process);
  330. StringBuffer lcName(packageMap);
  331. lcName.toLowerCase();
  332. VStringBuffer xpath("PackageMap[@id='%s'][@querySet='%s']", lcName.str(), target);
  333. IPropertyTree *pm = pkgSetRegistry->getPropTree(xpath.str());
  334. if (pm)
  335. pkgSetRegistry->removeTree(pm);
  336. else
  337. throw MakeStringException(PKG_DELETE_NOT_FOUND, "Unable to delete %s - information not found", lcName.str());
  338. VStringBuffer ps_xpath("PackageSet/PackageMap[@id='%s']", lcName.str());
  339. if (!packageSets->hasProp(ps_xpath))
  340. {
  341. Owned<IRemoteConnection> pkgMap = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  342. if (pkgMap)
  343. {
  344. VStringBuffer map_xpath("PackageMap[@id='%s']", lcName.str());
  345. IPropertyTree *pkgMaproot = pkgMap->queryRoot();
  346. IPropertyTree *pm = pkgMaproot->getPropTree(map_xpath.str());
  347. if (pm)
  348. pkgMaproot->removeTree(pm);
  349. }
  350. }
  351. return true;
  352. }
  353. void activatePackageMapInfo(const char *target, const char *packageMap, const char *process, bool activate)
  354. {
  355. if (!target || !*target)
  356. throw MakeStringException(PKG_TARGET_NOT_DEFINED, "No target defined");
  357. Owned<IRemoteConnection> globalLock = querySDS().connect("PackageSets", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  358. if (!globalLock)
  359. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve PackageSets information from dali /PackageSets");
  360. StringBuffer lcName(target);
  361. lcName.toLowerCase();
  362. IPropertyTree *root = globalLock->queryRoot();
  363. if (!root)
  364. throw MakeStringException(PKG_ACTIVATE_NOT_FOUND, "Unable to retrieve PackageSet information");
  365. StringBuffer pkgSetId;
  366. buildPkgSetId(pkgSetId, process);
  367. VStringBuffer pkgSet_xpath("PackageSet[@id='%s']", pkgSetId.str());
  368. IPropertyTree *pkgSetTree = root->queryPropTree(pkgSet_xpath.str());
  369. if (pkgSetTree)
  370. {
  371. if (packageMap && *packageMap)
  372. {
  373. StringBuffer lcMapName(packageMap);
  374. lcMapName.toLowerCase();
  375. VStringBuffer xpath_map("PackageMap[@id=\"%s\"]", lcMapName.str());
  376. IPropertyTree *mapTree = pkgSetTree->queryPropTree(xpath_map);
  377. if (activate)
  378. makePackageActive(pkgSetTree, mapTree, lcName.str());
  379. else
  380. mapTree->setPropBool("@active", false);
  381. }
  382. }
  383. }
  384. bool CWsPackageProcessEx::onAddPackage(IEspContext &context, IEspAddPackageRequest &req, IEspAddPackageResponse &resp)
  385. {
  386. resp.updateStatus().setCode(0);
  387. StringBuffer info(req.getInfo());
  388. bool activate = req.getActivate();
  389. bool overWrite = req.getOverWrite();
  390. StringAttr target(req.getTarget());
  391. StringAttr pkgMapName(req.getPackageMap());
  392. StringAttr processName(req.getProcess());
  393. Owned<IUserDescriptor> userdesc;
  394. const char *user = context.queryUserId();
  395. const char *password = context.queryPassword();
  396. if (user && *user && *password && *password)
  397. {
  398. userdesc.setown(createUserDescriptor());
  399. userdesc->set(user, password);
  400. }
  401. StringBuffer pkgSetId;
  402. buildPkgSetId(pkgSetId, processName.get());
  403. Owned<IPropertyTree> packageTree = createPTreeFromXMLString(info.str());
  404. Owned<IPropertyTree> pkgSetRegistry = getPkgSetRegistry(pkgSetId.str(), processName.get(), false);
  405. addPackageMapInfo(pkgSetRegistry, target.get(), pkgMapName.get(), pkgSetId.str(), req.getDaliIp(), LINK(packageTree), activate, overWrite, userdesc);
  406. StringBuffer msg;
  407. msg.append("Successfully loaded ").append(pkgMapName.get());
  408. resp.updateStatus().setDescription(msg.str());
  409. return true;
  410. }
  411. bool CWsPackageProcessEx::onDeletePackage(IEspContext &context, IEspDeletePackageRequest &req, IEspDeletePackageResponse &resp)
  412. {
  413. resp.updateStatus().setCode(0);
  414. StringAttr pkgMap(req.getPackageMap());
  415. StringAttr processName(req.getProcess());
  416. if (processName.length()==0)
  417. processName.set("*");
  418. bool ret = deletePkgInfo(pkgMap.get(), req.getTarget(), processName.get());
  419. StringBuffer msg;
  420. (ret) ? msg.append("Successfully ") : msg.append("Unsuccessfully ");
  421. msg.append("deleted ").append(pkgMap.get()).append(" from ").append(req.getTarget());
  422. resp.updateStatus().setDescription(msg.str());
  423. return true;
  424. }
  425. bool CWsPackageProcessEx::onActivatePackage(IEspContext &context, IEspActivatePackageRequest &req, IEspActivatePackageResponse &resp)
  426. {
  427. resp.updateStatus().setCode(0);
  428. activatePackageMapInfo(req.getTarget(), req.getPackageMap(), req.getProcess(), true);
  429. return true;
  430. }
  431. bool CWsPackageProcessEx::onDeActivatePackage(IEspContext &context, IEspDeActivatePackageRequest &req, IEspDeActivatePackageResponse &resp)
  432. {
  433. resp.updateStatus().setCode(0);
  434. activatePackageMapInfo(req.getTarget(), req.getPackageMap(), req.getProcess(), false);
  435. return true;
  436. }
  437. bool CWsPackageProcessEx::onListPackage(IEspContext &context, IEspListPackageRequest &req, IEspListPackageResponse &resp)
  438. {
  439. resp.updateStatus().setCode(0);
  440. IArrayOf<IConstPackageListMapData> results;
  441. StringAttr process(req.getProcess());
  442. listPkgInfo(req.getTarget(), process.length() ? process.get() : "*", &results);
  443. resp.setPkgListMapData(results);
  444. return true;
  445. }
  446. bool CWsPackageProcessEx::onGetPackage(IEspContext &context, IEspGetPackageRequest &req, IEspGetPackageResponse &resp)
  447. {
  448. resp.updateStatus().setCode(0);
  449. StringAttr process(req.getProcess());
  450. StringBuffer info;
  451. getPkgInfo(req.getTarget(), process.length() ? process.get() : "*", info);
  452. resp.setInfo(info);
  453. return true;
  454. }
  455. bool CWsPackageProcessEx::onValidatePackage(IEspContext &context, IEspValidatePackageRequest &req, IEspValidatePackageResponse &resp)
  456. {
  457. StringArray warnings;
  458. StringArray errors;
  459. StringArray unmatchedQueries;
  460. StringArray unusedPackages;
  461. Owned<IHpccPackageMap> map = createPackageMapFromXml(req.getInfo(), req.getTarget(), NULL);
  462. map->validate(warnings, errors, unmatchedQueries, unusedPackages);
  463. resp.setWarnings(warnings);
  464. resp.setErrors(errors);
  465. resp.updateQueries().setUnmatched(unmatchedQueries);
  466. resp.updatePackages().setUnmatched(unusedPackages);
  467. return true;
  468. }