ws_packageprocessService.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #pragma warning (disable : 4786)
  15. #include "ws_packageprocessService.hpp"
  16. #include "daclient.hpp"
  17. #include "dalienv.hpp"
  18. #include "dadfs.hpp"
  19. #include "dfuutil.hpp"
  20. #include "ws_fs.hpp"
  21. #include "ws_workunits.hpp"
  22. #include "packageprocess_errors.h"
  23. #define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
  24. void CWsPackageProcessEx::init(IPropertyTree *cfg, const char *process, const char *service)
  25. {
  26. }
  27. bool CWsPackageProcessEx::onEcho(IEspContext &context, IEspEchoRequest &req, IEspEchoResponse &resp)
  28. {
  29. StringBuffer respMsg;
  30. ISecUser* user = context.queryUser();
  31. if(user != NULL)
  32. {
  33. const char* name = user->getName();
  34. if (name && *name)
  35. respMsg.appendf("%s: ", name);
  36. }
  37. const char* reqMsg = req.getRequest();
  38. if (reqMsg && *reqMsg)
  39. respMsg.append(reqMsg);
  40. else
  41. respMsg.append("??");
  42. resp.setResponse(respMsg.str());
  43. return true;
  44. }
  45. IPropertyTree *getPkgSetRegistry(const char *setName, bool readonly)
  46. {
  47. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageSets/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  48. //Only lock the branch for the target we're interested in.
  49. StringBuffer xpath;
  50. xpath.append("/PackageSets/PackageSet[@id=\"").append(setName).append("\"]");
  51. Owned<IRemoteConnection> conn = querySDS().connect(xpath.str(), myProcessSession(), readonly ? RTM_LOCK_READ : RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  52. if (!conn)
  53. {
  54. if (readonly)
  55. return NULL;
  56. Owned<IPropertyTree> querySet = createPTree();
  57. querySet->setProp("@id", setName);
  58. globalLock->queryRoot()->addPropTree("PackageSet", querySet.getClear());
  59. globalLock->commit();
  60. conn.setown(querySDS().connect(xpath.str(), myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT));
  61. if (!conn)
  62. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali %s", xpath.str());
  63. }
  64. return conn->getRoot();
  65. }
  66. ////////////////////////////////////////////////////////////////////////////////////////
  67. const unsigned roxieQueryRoxieTimeOut = 60000;
  68. #define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
  69. bool isRoxieProcess(const char *process)
  70. {
  71. if (!process)
  72. return false;
  73. Owned<IRemoteConnection> conn = querySDS().connect("Environment", myProcessSession(), RTM_LOCK_READ, SDS_LOCK_TIMEOUT);
  74. if (!conn)
  75. return false;
  76. VStringBuffer xpath("Software/RoxieCluster[@name=\"%s\"]", process);
  77. return conn->queryRoot()->hasProp(xpath.str());
  78. }
  79. bool isFileKnownOnCluster(const char *logicalname, const char *lookupDaliIp, const char *process, IUserDescriptor* userdesc)
  80. {
  81. Owned<IDistributedFile> dst = queryDistributedFileDirectory().lookup(logicalname, userdesc, true);
  82. if (dst)
  83. {
  84. if (dst->findCluster(process) != NotFound)
  85. return true; // file already known for this cluster
  86. }
  87. return false;
  88. }
  89. bool addFileInfoToDali(const char *logicalname, const char *lookupDaliIp, const char *process, bool overwrite, IUserDescriptor* userdesc, StringBuffer &host, short port, StringBuffer &msg)
  90. {
  91. bool retval = true;
  92. try
  93. {
  94. if (!overwrite)
  95. {
  96. if (isFileKnownOnCluster(logicalname, lookupDaliIp, process, userdesc))
  97. return true;
  98. }
  99. StringBuffer user;
  100. StringBuffer password;
  101. if (userdesc)
  102. {
  103. userdesc->getUserName(user);
  104. userdesc->getPassword(password);
  105. }
  106. Owned<IClientFileSpray> fs;
  107. fs.setown(createFileSprayClient());
  108. fs->setUsernameToken(user.str(), password.str(), NULL);
  109. VStringBuffer url("http://%s:%d/FileSpray", host.str(), port);
  110. fs->addServiceUrl(url.str());
  111. bool isRoxie = isRoxieProcess(process);
  112. Owned<IClientCopy> req = fs->createCopyRequest();
  113. req->setSourceLogicalName(logicalname);
  114. req->setDestLogicalName(logicalname);
  115. req->setDestGroup(process);
  116. req->setSuperCopy(false);
  117. if (isRoxie)
  118. req->setDestGroupRoxie("Yes");
  119. req->setSourceDali(lookupDaliIp);
  120. req->setSrcusername(user);
  121. req->setSrcpassword(password);
  122. req->setOverwrite(overwrite);
  123. Owned<IClientCopyResponse> resp = fs->Copy(req);
  124. }
  125. catch(IException *e)
  126. {
  127. e->errorMessage(msg);
  128. DBGLOG("ERROR = %s", msg.str());
  129. e->Release(); // report the error later if needed
  130. retval = false;
  131. }
  132. catch(...)
  133. {
  134. retval = false;
  135. }
  136. return retval;
  137. }
  138. //////////////////////////////////////////////////////////
  139. void addPackageMapInfo(IPropertyTree *pkgSetRegistry, const char *setName, const char *packageSetName, IPropertyTree *packageInfo, bool active, bool overWrite)
  140. {
  141. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  142. StringBuffer lcName(packageSetName);
  143. lcName.toLowerCase();
  144. StringBuffer xpath;
  145. xpath.append("PackageMap[@id='").append(lcName).append("']");
  146. IPropertyTree *pkgRegTree = pkgSetRegistry->queryPropTree(xpath.str());
  147. IPropertyTree *root = globalLock->queryRoot();
  148. IPropertyTree *mapTree = root->queryPropTree(xpath);
  149. if (!overWrite && (pkgRegTree || mapTree))
  150. throw MakeStringException(PKG_NAME_EXISTS, "Package name %s already exists, either delete it or specify overwrite", lcName.str());
  151. if (mapTree)
  152. root->removeTree(mapTree);
  153. if (pkgRegTree)
  154. pkgSetRegistry->removeTree(pkgRegTree);
  155. mapTree = root->addPropTree("PackageMap", createPTree());
  156. mapTree->addProp("@id", packageSetName);
  157. IPropertyTree *baseInfo = createPTree();
  158. Owned<IPropertyTreeIterator> iter = packageInfo->getElements("Package");
  159. ForEach(*iter)
  160. {
  161. IPropertyTree &item = iter->query();
  162. Owned<IPropertyTreeIterator> super_iter = item.getElements("SuperFile");
  163. if (super_iter->first())
  164. {
  165. ForEach(*super_iter)
  166. {
  167. IPropertyTree &supertree = super_iter->query();
  168. StringAttr id(supertree.queryProp("@id"));
  169. if (id.length() && id[0] == '~')
  170. supertree.setProp("@id", id+1);
  171. Owned<IPropertyTreeIterator> sub_iter = supertree.getElements("SubFile");
  172. ForEach(*sub_iter)
  173. {
  174. IPropertyTree &subtree = sub_iter->query();
  175. StringAttr subid = subtree.queryProp("@value");
  176. if (subid.length())
  177. {
  178. if (subid[0] == '~')
  179. subtree.setProp("@value", subid+1);
  180. }
  181. }
  182. mapTree->addPropTree("Package", LINK(&item));
  183. }
  184. }
  185. else
  186. {
  187. baseInfo->addPropTree("Package", LINK(&item));
  188. }
  189. }
  190. mergePTree(mapTree, baseInfo);
  191. globalLock->commit();
  192. IPropertyTree *pkgSetTree = pkgSetRegistry->addPropTree("PackageMap", createPTree("PackageMap"));
  193. pkgSetTree->setProp("@id", lcName);
  194. pkgSetTree->setProp("@querySet", setName);
  195. pkgSetTree->setPropBool("@active", active);
  196. }
  197. void copyPackageSubFiles(IPropertyTree *packageInfo, const char *process, const char *defaultLookupDaliIp, bool overwrite, IUserDescriptor* userdesc, StringBuffer &host, short port)
  198. {
  199. Owned<IPropertyTreeIterator> iter = packageInfo->getElements("Package");
  200. ForEach(*iter)
  201. {
  202. IPropertyTree &item = iter->query();
  203. StringBuffer lookupDaliIp;
  204. lookupDaliIp.append(item.queryProp("@daliip"));
  205. if (lookupDaliIp.length() == 0)
  206. lookupDaliIp.append(defaultLookupDaliIp);
  207. if (lookupDaliIp.length() == 0)
  208. {
  209. StringAttr superfile(item.queryProp("@id"));
  210. throw MakeStringException(PKG_MISSING_DALI_LOOKUP_IP, "Could not lookup SubFiles in package %s because no remote dali ip was specified", superfile.get());
  211. }
  212. Owned<IPropertyTreeIterator> super_iter = item.getElements("SuperFile");
  213. ForEach(*super_iter)
  214. {
  215. IPropertyTree &supertree = super_iter->query();
  216. Owned<IPropertyTreeIterator> sub_iter = supertree.getElements("SubFile");
  217. ForEach(*sub_iter)
  218. {
  219. IPropertyTree &subtree = sub_iter->query();
  220. StringAttr subid = subtree.queryProp("@value");
  221. if (subid.length())
  222. {
  223. StringBuffer msg;
  224. addFileInfoToDali(subid.get(), lookupDaliIp, process, overwrite, userdesc, host, port, msg);
  225. }
  226. }
  227. }
  228. }
  229. }
  230. void getPackageListInfo(IPropertyTree *mapTree, IEspPackageListMapData *pkgList)
  231. {
  232. pkgList->setId(mapTree->queryProp("@id"));
  233. Owned<IPropertyTreeIterator> iter = mapTree->getElements("Package");
  234. IArrayOf<IConstPackageListData> results;
  235. ForEach(*iter)
  236. {
  237. IPropertyTree &item = iter->query();
  238. Owned<IEspPackageListData> res = createPackageListData("", "");
  239. res->setId(item.queryProp("@id"));
  240. if (item.hasProp("@queries"))
  241. res->setQueries(item.queryProp("@queries"));
  242. results.append(*res.getClear());
  243. }
  244. pkgList->setPkgListData(results);
  245. }
  246. void getAllPackageListInfo(IPropertyTree *mapTree, StringBuffer &info)
  247. {
  248. info.append("<PackageMap id='").append(mapTree->queryProp("@id")).append("'");
  249. Owned<IPropertyTreeIterator> iter = mapTree->getElements("Package");
  250. ForEach(*iter)
  251. {
  252. IPropertyTree &item = iter->query();
  253. info.append("<Package id='").append(item.queryProp("@id")).append("'");
  254. if (item.hasProp("@queries"))
  255. info.append(" queries='").append(item.queryProp("@queries")).append("'");
  256. info.append("></Package>");
  257. }
  258. info.append("</PackageMap>");
  259. }
  260. void listPkgInfo(const char *cluster, IArrayOf<IConstPackageListMapData>* results)
  261. {
  262. StringBuffer info;
  263. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  264. if (!globalLock)
  265. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali /PackageMaps");
  266. IPropertyTree *root = globalLock->queryRoot();
  267. if (!cluster || !*cluster)
  268. {
  269. info.append("<PackageMaps>");
  270. Owned<IPropertyTreeIterator> iter = root->getElements("PackageMap");
  271. ForEach(*iter)
  272. {
  273. Owned<IEspPackageListMapData> res = createPackageListMapData("", "");
  274. IPropertyTree &item = iter->query();
  275. getPackageListInfo(&item, res);
  276. results->append(*res.getClear());
  277. }
  278. info.append("</PackageMaps>");
  279. }
  280. else
  281. {
  282. Owned<IPropertyTree> pkgSetRegistry = getPkgSetRegistry(cluster, true);
  283. if (!pkgSetRegistry)
  284. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali for cluster %s", cluster);
  285. Owned<IPropertyTreeIterator> iter = pkgSetRegistry->getElements("PackageMap");
  286. info.append("<PackageMaps>");
  287. ForEach(*iter)
  288. {
  289. IPropertyTree &item = iter->query();
  290. const char *id = item.queryProp("@id");
  291. if (id)
  292. {
  293. StringBuffer xpath;
  294. xpath.append("PackageMap[@id='").append(id).append("']");
  295. IPropertyTree *mapTree = root->queryPropTree(xpath);
  296. Owned<IEspPackageListMapData> res = createPackageListMapData("", "");
  297. getPackageListInfo(mapTree, res);
  298. results->append(*res.getClear());
  299. }
  300. }
  301. info.append("</PackageMaps>");
  302. }
  303. }
  304. void getPkgInfo(const char *cluster, const char *package, StringBuffer &info)
  305. {
  306. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  307. if (!globalLock)
  308. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve package information from dali /PackageMaps");
  309. IPropertyTree *root = globalLock->queryRoot();
  310. Owned<IPropertyTree> tree = createPTree("PackageMaps");
  311. if (cluster)
  312. {
  313. Owned<IPropertyTree> pkgSetRegistry = getPkgSetRegistry(cluster, true);
  314. Owned<IPropertyTreeIterator> iter = pkgSetRegistry->getElements("PackageMap[@active='1']");
  315. ForEach(*iter)
  316. {
  317. IPropertyTree &item = iter->query();
  318. const char *id = item.queryProp("@id");
  319. if (id)
  320. {
  321. StringBuffer xpath;
  322. xpath.append("PackageMap[@id='").append(id).append("']");
  323. IPropertyTree *mapTree = root->queryPropTree(xpath);
  324. if (mapTree)
  325. mergePTree(tree, mapTree);
  326. }
  327. }
  328. }
  329. else
  330. {
  331. StringBuffer xpath;
  332. xpath.append("PackageMap[@id='").append(package).append("']");
  333. Owned<IPropertyTreeIterator> iter = root->getElements(xpath.str());
  334. ForEach(*iter)
  335. {
  336. IPropertyTree &item = iter->query();
  337. mergePTree(tree, &item);
  338. }
  339. }
  340. toXML(tree, info);
  341. }
  342. bool deletePkgInfo(const char *packageSetName, const char *queryset)
  343. {
  344. Owned<IRemoteConnection> pkgSet = querySDS().connect("/PackageSets/", myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  345. if (!pkgSet)
  346. throw MakeStringException(PKG_SET_NOT_DEFINED, "No package sets defined");
  347. IPropertyTree* packageSets = pkgSet->queryRoot();
  348. VStringBuffer pkgSet_xpath("PackageSet[@id='%s']", queryset);
  349. IPropertyTree *pkgSetRegistry = packageSets->queryPropTree(pkgSet_xpath.str());
  350. if (!pkgSetRegistry)
  351. throw MakeStringException(PKG_SET_NOT_DEFINED, "No package sets defined for %s", queryset);
  352. StringBuffer lcName(packageSetName);
  353. lcName.toLowerCase();
  354. VStringBuffer xpath("PackageMap[@id='%s'][@querySet='%s']", lcName.str(), queryset);
  355. IPropertyTree *pm = pkgSetRegistry->getPropTree(xpath.str());
  356. if (pm)
  357. pkgSetRegistry->removeTree(pm);
  358. else
  359. throw MakeStringException(PKG_DELETE_NOT_FOUND, "Unable to delete %s - information not found", lcName.str());
  360. VStringBuffer ps_xpath("PackageSet/PackageMap[@id='%s']", lcName.str());
  361. if (!packageSets->hasProp(ps_xpath))
  362. {
  363. Owned<IRemoteConnection> pkgMap = querySDS().connect("/PackageMaps/", myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  364. if (pkgMap)
  365. {
  366. VStringBuffer map_xpath("PackageMap[@id='%s']", lcName.str());
  367. IPropertyTree *pkgMaproot = pkgMap->queryRoot();
  368. IPropertyTree *pm = pkgMaproot->getPropTree(map_xpath.str());
  369. if (pm)
  370. pkgMaproot->removeTree(pm);
  371. }
  372. }
  373. return true;
  374. }
  375. void activatePackageMapInfo(const char *packageSetName, const char *packageMap, bool activate)
  376. {
  377. if (!packageSetName || !*packageSetName)
  378. throw MakeStringException(PKG_SET_NOT_DEFINED, "No package sets defined");
  379. Owned<IRemoteConnection> globalLock = querySDS().connect("PackageSets", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  380. if (!globalLock)
  381. throw MakeStringException(PKG_DALI_LOOKUP_ERROR, "Unable to retrieve PackageSets information from dali /PackageSets");
  382. StringBuffer lcName(packageSetName);
  383. lcName.toLowerCase();
  384. VStringBuffer xpath("PackageSet[@id=\"%s\"]", lcName.str());
  385. IPropertyTree *root = globalLock->queryRoot();
  386. if (!root)
  387. throw MakeStringException(PKG_ACTIVATE_NOT_FOUND, "Unable to retrieve PackageSet information for %s", lcName.str());
  388. IPropertyTree *pkgSetTree = root->queryPropTree(xpath);
  389. if (pkgSetTree)
  390. {
  391. if (packageMap && *packageMap)
  392. {
  393. StringBuffer lcMapName(packageMap);
  394. lcMapName.toLowerCase();
  395. VStringBuffer xpath_map("PackageMap[@id=\"%s\"]", lcMapName.str());
  396. IPropertyTree *mapTree = pkgSetTree->queryPropTree(xpath_map);
  397. mapTree->setPropBool("@active", activate);
  398. }
  399. else
  400. {
  401. Owned<IPropertyTreeIterator> iter = pkgSetTree->getElements("PackageMap");
  402. ForEach(*iter)
  403. {
  404. IPropertyTree &item = iter->query();
  405. item.setPropBool("@active", activate);
  406. }
  407. }
  408. }
  409. }
  410. bool CWsPackageProcessEx::onAddPackage(IEspContext &context, IEspAddPackageRequest &req, IEspAddPackageResponse &resp)
  411. {
  412. resp.updateStatus().setCode(0);
  413. StringBuffer info(req.getInfo());
  414. bool activate = req.getActivate();
  415. bool overWrite = req.getOverWrite();
  416. StringAttr querySet(req.getQuerySet());
  417. StringAttr pkgName(req.getPackageName());
  418. Owned<IPropertyTree> packageTree = createPTreeFromXMLString(info.str());
  419. Owned<IPropertyTree> pkgSetRegistry = getPkgSetRegistry(querySet.get(), false);
  420. addPackageMapInfo(pkgSetRegistry, querySet.get(), pkgName.get(), LINK(packageTree), activate, overWrite);
  421. StringBuffer msg;
  422. msg.append("Successfully loaded ").append(pkgName.get());
  423. resp.updateStatus().setDescription(msg.str());
  424. return true;
  425. }
  426. bool CWsPackageProcessEx::onDeletePackage(IEspContext &context, IEspDeletePackageRequest &req, IEspDeletePackageResponse &resp)
  427. {
  428. resp.updateStatus().setCode(0);
  429. StringAttr pkgName(req.getPackageName());
  430. bool ret = deletePkgInfo(pkgName.get(), req.getQuerySet());
  431. StringBuffer msg;
  432. (ret) ? msg.append("Successfully ") : msg.append("Unsuccessfully ");
  433. msg.append("deleted").append(pkgName.get());
  434. resp.updateStatus().setDescription(msg.str());
  435. return true;
  436. }
  437. bool CWsPackageProcessEx::onActivatePackage(IEspContext &context, IEspActivatePackageRequest &req, IEspActivatePackageResponse &resp)
  438. {
  439. resp.updateStatus().setCode(0);
  440. StringBuffer pkgName(req.getPackageName());
  441. StringBuffer pkgMapName(req.getPackageMapName());
  442. activatePackageMapInfo(pkgName.str(), pkgMapName.str(), true);
  443. return true;
  444. }
  445. bool CWsPackageProcessEx::onDeActivatePackage(IEspContext &context, IEspDeActivatePackageRequest &req, IEspDeActivatePackageResponse &resp)
  446. {
  447. resp.updateStatus().setCode(0);
  448. StringBuffer pkgName(req.getPackageName());
  449. StringBuffer pkgMapName(req.getPackageMapName());
  450. activatePackageMapInfo(pkgName.str(), pkgMapName.str(), false);
  451. return true;
  452. }
  453. bool CWsPackageProcessEx::onListPackage(IEspContext &context, IEspListPackageRequest &req, IEspListPackageResponse &resp)
  454. {
  455. resp.updateStatus().setCode(0);
  456. IArrayOf<IConstPackageListMapData> results;
  457. listPkgInfo(req.getCluster(), &results);
  458. resp.setPkgListMapData(results);
  459. return true;
  460. }
  461. bool CWsPackageProcessEx::onGetPackage(IEspContext &context, IEspGetPackageRequest &req, IEspGetPackageResponse &resp)
  462. {
  463. resp.updateStatus().setCode(0);
  464. StringAttr cluster(req.getCluster());
  465. StringAttr pkgName(req.getPackageName());
  466. StringBuffer info;
  467. getPkgInfo(cluster.length() ? cluster.get() : NULL, pkgName.length() ? pkgName.get() : NULL, info);
  468. resp.setInfo(info);
  469. return true;
  470. }
  471. bool CWsPackageProcessEx::onCopyFiles(IEspContext &context, IEspCopyFilesRequest &req, IEspCopyFilesResponse &resp)
  472. {
  473. resp.updateStatus().setCode(0);
  474. StringBuffer info(req.getInfo());
  475. StringAttr process(req.getProcess());
  476. StringAttr pkgName(req.getPackageName());
  477. StringAttr lookupDaliIp(req.getDaliIp());
  478. if (process.length() == 0)
  479. throw MakeStringException(PKG_MISSING_PARAM, "CWsPackageProcessEx::onCopyFiles process parameter not set.");
  480. Owned<IUserDescriptor> userdesc;
  481. const char *user = context.queryUserId();
  482. const char *password = context.queryPassword();
  483. if (user && *user && *password && *password)
  484. {
  485. userdesc.setown(createUserDescriptor());
  486. userdesc->set(user, password);
  487. }
  488. StringBuffer host;
  489. short port;
  490. context.getServAddress(host, port);
  491. Owned<IPropertyTree> packageTree = createPTreeFromXMLString(info.str());
  492. copyPackageSubFiles(LINK(packageTree), process, lookupDaliIp, req.getOverWrite(), userdesc, host, port);
  493. StringBuffer msg;
  494. msg.append("Successfully loaded ").append(pkgName.get());
  495. resp.updateStatus().setDescription(msg.str());
  496. return true;
  497. }