ws_smcService.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442
  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 "ldapsecurity.ipp"
  16. #include "ws_smcService.hpp"
  17. #include "wshelpers.hpp"
  18. #include "dalienv.hpp"
  19. #include "WUWrapper.hpp"
  20. #include "wujobq.hpp"
  21. #include "dfuwu.hpp"
  22. #include "exception_util.hpp"
  23. static const char* FEATURE_URL = "SmcAccess";
  24. const char* THORQUEUE_FEATURE = "ThorQueueAccess";
  25. const char* PERMISSIONS_FILENAME = "espsmc_permissions.xml";
  26. void AccessSuccess(IEspContext& context, char const * msg,...) __attribute__((format(printf, 2, 3)));
  27. void AccessSuccess(IEspContext& context, char const * msg,...)
  28. {
  29. StringBuffer buf;
  30. buf.appendf("User %s: ",context.queryUserId());
  31. va_list args;
  32. va_start(args, msg);
  33. buf.valist_appendf(msg, args);
  34. va_end(args);
  35. AUDIT(AUDIT_TYPE_ACCESS_SUCCESS,buf.str());
  36. }
  37. void AccessFailure(IEspContext& context, char const * msg,...) __attribute__((format(printf, 2, 3)));
  38. void AccessFailure(IEspContext& context, char const * msg,...)
  39. {
  40. StringBuffer buf;
  41. buf.appendf("User %s: ",context.queryUserId());
  42. va_list args;
  43. va_start(args, msg);
  44. buf.valist_appendf(msg, args);
  45. va_end(args);
  46. AUDIT(AUDIT_TYPE_ACCESS_FAILURE,buf.str());
  47. }
  48. struct QueueWrapper
  49. {
  50. QueueWrapper(const char* cluster)
  51. {
  52. StringBuffer name;
  53. name<<cluster<<".thor";
  54. queue.setown(createJobQueue(name.str()));
  55. }
  56. QueueWrapper(int clusterType, const char* cluster)
  57. {
  58. if (!cluster || !*cluster)
  59. return;
  60. const char* type = eqThorCluster;
  61. if (clusterType < 1)
  62. type = eqRoxieCluster;
  63. CTpWrapper dummy;
  64. IArrayOf<IEspTpLogicalCluster> clusters;
  65. dummy.getTargetClusterList(clusters, type, cluster);
  66. if (clusters.length() < 1)
  67. return;
  68. IEspTpLogicalCluster &cluster0 = clusters.item(0);
  69. const char *name0 = cluster0.getName();
  70. if (!name0 || !*name0)
  71. return;
  72. StringBuffer name;
  73. name<<name0<<".thor";
  74. queue.setown(createJobQueue(name.str()));
  75. }
  76. QueueWrapper(const char* clusterName, const char* queueName)
  77. {
  78. StringBuffer name;
  79. name<<clusterName<<"."<<queueName;
  80. queue.setown(createJobQueue(name.str()));
  81. }
  82. operator IJobQueue*() { return queue.get(); }
  83. IJobQueue* operator->() { return queue.get(); }
  84. Owned<IJobQueue> queue;
  85. };
  86. struct QueueLock
  87. {
  88. QueueLock(IJobQueue* q): queue(q) { queue->lock(); }
  89. ~QueueLock()
  90. {
  91. queue->unlock();
  92. }
  93. Linked<IJobQueue> queue;
  94. };
  95. void CWsSMCEx::init(IPropertyTree *cfg, const char *process, const char *service)
  96. {
  97. if (!daliClientActive())
  98. {
  99. ERRLOG("No Dali Connection Active.");
  100. throw MakeStringException(-1, "No Dali Connection Active. Please Specify a Dali to connect to in you configuration file");
  101. }
  102. m_BannerAction = 0;
  103. m_EnableChatURL = false;
  104. m_BannerSize = "4";
  105. m_BannerColor = "red";
  106. m_BannerScroll = "2";
  107. StringBuffer xpath;
  108. xpath.appendf("Software/EspProcess[@name='%s']/@portalurl", process);
  109. const char* portalURL = cfg->queryProp(xpath.str());
  110. if (portalURL && *portalURL)
  111. m_PortalURL.append(portalURL);
  112. }
  113. static void countProgress(IPropertyTree *t,unsigned &done,unsigned &total)
  114. {
  115. total = 0;
  116. done = 0;
  117. Owned<IPropertyTreeIterator> it = t->getElements("DFT/progress");
  118. ForEach(*it) {
  119. IPropertyTree &e=it->query();
  120. if (e.getPropInt("@done",0))
  121. done++;
  122. total++;
  123. }
  124. }
  125. struct CActiveWorkunitWrapper: public CActiveWorkunit
  126. {
  127. CActiveWorkunitWrapper(IEspContext &context, const char* wuid,unsigned index=0): CActiveWorkunit("","")
  128. {
  129. double version = context.getClientVersion();
  130. CWUWrapper wu(wuid, context);
  131. SCMStringBuffer state,owner,jobname;
  132. setWuid(wuid);
  133. if(index)
  134. state.s.append("queued(").append(index).append(")");
  135. else
  136. wu->getStateDesc(state);
  137. setState(state.str());
  138. setStateID(wu->getState());
  139. if ((version > 1.09) && (wu->getState() == WUStateFailed))
  140. setWarning("The job will ultimately not complete. Please check ECLAgent.");
  141. setOwner(wu->getUser(owner).str());
  142. setJobname(wu->getJobName(jobname).str());
  143. switch(wu->getPriority())
  144. {
  145. case PriorityClassHigh: setPriority("high"); break;
  146. default:
  147. case PriorityClassNormal: setPriority("normal"); break;
  148. case PriorityClassLow: setPriority("low"); break;
  149. }
  150. if (version > 1.08 && wu->isPausing())
  151. {
  152. setIsPausing(true);
  153. }
  154. }
  155. CActiveWorkunitWrapper(const char* wuid,const char* owner, const char* jobname, const char* state, const char* priority): CActiveWorkunit("","")
  156. {
  157. setWuid(wuid);
  158. setState(state);
  159. setOwner(owner);
  160. setJobname(jobname);
  161. setPriority(priority);
  162. }
  163. };
  164. bool CWsSMCEx::onIndex(IEspContext &context, IEspSMCIndexRequest &req, IEspSMCIndexResponse &resp)
  165. {
  166. resp.setRedirectUrl("/");
  167. return true;
  168. }
  169. static int stringcmp(const char **a, const char **b)
  170. {
  171. return strcmp(*a, *b);
  172. }
  173. bool CWsSMCEx::isInWuList(IArrayOf<IEspActiveWorkunit>& aws, const char* wuid)
  174. {
  175. bool bFound = false;
  176. if (wuid && *wuid && (aws.length() > 0))
  177. {
  178. ForEachItemIn(k, aws)
  179. {
  180. IEspActiveWorkunit& wu = aws.item(k);
  181. const char* wuid0 = wu.getWuid();
  182. const char* server0 = wu.getServer();
  183. if (wuid0 && !strcmp(wuid0, wuid) && (!server0 || strcmp(server0, "ECLagent")))
  184. {
  185. bFound = true;
  186. break;
  187. }
  188. }
  189. }
  190. return bFound;
  191. }
  192. bool CWsSMCEx::onActivity(IEspContext &context, IEspActivityRequest &req, IEspActivityResponse& resp)
  193. {
  194. context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, true);
  195. try
  196. {
  197. const char* build_ver = getBuildVersion();
  198. resp.setBuild(build_ver);
  199. double version = context.getClientVersion();
  200. CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
  201. if(req.getFromSubmitBtn() && secmgr && secmgr->isSuperUser(context.queryUser()))
  202. {
  203. StringBuffer chatURLStr, bannerStr;
  204. const char* chatURL = req.getChatURL();
  205. const char* banner = req.getBannerContent();
  206. //Only display valid strings
  207. if (chatURL)
  208. {
  209. const char* pStr = chatURL;
  210. for (unsigned i = 0; i < strlen(chatURL); i++)
  211. {
  212. if ((pStr[0] > 31) && (pStr[0] < 127))
  213. chatURLStr.append(pStr[0]);
  214. pStr++;
  215. }
  216. }
  217. if (banner)
  218. {
  219. const char* pStr = banner;
  220. for (unsigned i = 0; i < strlen(banner); i++)
  221. {
  222. if ((pStr[0] > 31) && (pStr[0] < 127))
  223. bannerStr.append(pStr[0]);
  224. pStr++;
  225. }
  226. }
  227. chatURLStr.trim();
  228. bannerStr.trim();
  229. if (!req.getBannerAction_isNull() && req.getBannerAction() && (bannerStr.length() < 1))
  230. {
  231. throw MakeStringException(ECLWATCH_MISSING_BANNER_CONTENT, "If a Banner is enabled, the Banner content must be specified.");
  232. }
  233. if (!req.getEnableChatURL_isNull() && req.getEnableChatURL() && (chatURLStr.length() < 1))
  234. {
  235. throw MakeStringException(ECLWATCH_MISSING_CHAT_URL, "If a Chat is enabled, the Chat URL must be specified.");
  236. }
  237. m_ChatURL = chatURLStr;
  238. m_Banner = bannerStr;
  239. const char* bannerSize = req.getBannerSize();
  240. if (bannerSize && *bannerSize)
  241. m_BannerSize.clear().append(bannerSize);
  242. const char* bannerColor = req.getBannerColor();
  243. if (bannerColor && *bannerColor)
  244. m_BannerColor.clear().append(bannerColor);
  245. const char* bannerScroll = req.getBannerScroll();
  246. if (bannerScroll && *bannerScroll)
  247. m_BannerScroll.clear().append(bannerScroll);
  248. m_BannerAction = req.getBannerAction();
  249. if(!req.getEnableChatURL_isNull())
  250. m_EnableChatURL = req.getEnableChatURL();
  251. }
  252. if (version > 1.05)
  253. {
  254. int UserPermission = -1;
  255. CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
  256. if(secmgr && secmgr->isSuperUser(context.queryUser()))
  257. UserPermission = 0;
  258. resp.setUserPermission(UserPermission);
  259. resp.setShowBanner(m_BannerAction);
  260. resp.setShowChatURL(m_EnableChatURL);
  261. resp.setBannerContent(m_Banner.str());
  262. resp.setBannerSize(m_BannerSize.str());
  263. resp.setBannerColor(m_BannerColor.str());
  264. resp.setChatURL(m_ChatURL.str());
  265. if (version > 1.07)
  266. {
  267. resp.setBannerScroll(m_BannerScroll.str());
  268. }
  269. }
  270. Owned<IRemoteConnection> conn = querySDS().connect("/Status/Servers",myProcessSession(),RTM_LOCK_READ,30000);
  271. StringBuffer runningQueueNames[256];
  272. int runningQueues = 0;
  273. int runningJobsInQueue[256];
  274. for (int i = 0; i < 256; i++)
  275. runningJobsInQueue[i] = 0;
  276. IArrayOf<IEspActiveWorkunit> aws;
  277. if (conn.get())
  278. {
  279. Owned<IPropertyTreeIterator> it(conn->queryRoot()->getElements("Server"));
  280. ForEach(*it)
  281. {
  282. StringBuffer instance;
  283. StringBuffer qname;
  284. int serverID = -1;
  285. IPropertyTree& node = it->query();
  286. const char* name = node.queryProp("@name");
  287. if(node.hasProp("@queue"))
  288. {
  289. const char* queue=node.queryProp("@queue");
  290. const char* thor=strstr(queue,".thor");
  291. if(thor)
  292. {
  293. qname.append(thor-queue,queue);
  294. node.getProp("@thorname",instance);
  295. }
  296. else
  297. qname.append(queue);
  298. }
  299. else if (name && !stricmp(name, "ECLAgent"))
  300. {
  301. qname.append(name);
  302. }
  303. if((instance.length()==0)&& name && *name)
  304. {
  305. instance.append( !strcmp(name, "ECLagent") ? "ECL agent" : name);
  306. instance.append(" on ").append(node.queryProp("@node"));
  307. }
  308. if (qname.length() > 0)
  309. {
  310. int i = 0;
  311. bool bFound = false;
  312. while (i < runningQueues)
  313. {
  314. const char* serverName = runningQueueNames[i].str();
  315. if (serverName && !stricmp(serverName, qname.str()))
  316. {
  317. bFound = true;
  318. serverID = i;
  319. break;
  320. }
  321. i++;
  322. }
  323. if (!bFound)
  324. {
  325. runningQueueNames[runningQueues] = qname;
  326. runningQueues++;
  327. serverID = runningQueues - 1;
  328. }
  329. }
  330. Owned<IPropertyTreeIterator> wuids(node.getElements("WorkUnit"));
  331. ForEach(*wuids)
  332. {
  333. const char* wuid=wuids->query().queryProp(NULL);
  334. if(!wuid)
  335. continue;
  336. try
  337. {
  338. IEspActiveWorkunit* wu=new CActiveWorkunitWrapper(context,wuid);
  339. const char* servername = node.queryProp("@name");
  340. wu->setServer(servername);
  341. wu->setInstance(instance.str());
  342. wu->setQueueName(qname.str());
  343. double version = context.getClientVersion();
  344. if (version > 1.01)
  345. {
  346. if (wu->getStateID() == WUStateRunning)
  347. {
  348. int sg_duration = node.getPropInt("@sg_duration", -1);
  349. const char* graph = node.queryProp("@graph");
  350. int subgraph = node.getPropInt("@subgraph", -1);
  351. if (subgraph > -1 && sg_duration > -1)
  352. {
  353. StringBuffer durationStr;
  354. StringBuffer subgraphStr;
  355. durationStr.appendf("%d min", sg_duration);
  356. subgraphStr.appendf("%d", subgraph);
  357. wu->setGraphName(graph);
  358. wu->setDuration(durationStr.str());
  359. wu->setGID(subgraphStr.str());
  360. }
  361. int memoryBlocked = node.getPropInt("@memoryBlocked ", 0);
  362. if (memoryBlocked != 0)
  363. {
  364. wu->setMemoryBlocked(1);
  365. }
  366. if (serverID > -1)
  367. {
  368. runningJobsInQueue[serverID]++;
  369. }
  370. }
  371. }
  372. aws.append(*wu);
  373. }
  374. catch (IException *e)
  375. {
  376. StringBuffer msg;
  377. Owned<IEspActiveWorkunit> wu(new CActiveWorkunitWrapper(wuid, "", "", e->errorMessage(msg).str(), "normal"));
  378. wu->setServer(node.queryProp("@name"));
  379. wu->setInstance(instance.str());
  380. wu->setQueueName(qname.str());
  381. aws.append(*wu.getLink());
  382. }
  383. }
  384. }
  385. }
  386. SecAccessFlags access;
  387. bool doCommand=(context.authorizeFeature(THORQUEUE_FEATURE, access) && access>=SecAccess_Full);
  388. CTpWrapper dummy;
  389. IArrayOf<IEspTpCluster> clusters;
  390. dummy.getClusterProcessList(eqThorCluster,clusters,true);
  391. IArrayOf<IEspThorCluster> ThorClusters;
  392. ForEachItemIn(x, clusters)
  393. {
  394. IEspTpCluster& cluster = clusters.item(x);
  395. IEspThorCluster* returnCluster = new CThorCluster("","");
  396. returnCluster->setClusterName(cluster.getName());
  397. returnCluster->setQueueName(cluster.getQueueName());
  398. if (version > 1.08)
  399. {
  400. bool bThorLCR = dummy.getClusterLCR(eqThorCluster, cluster.getName());
  401. if (bThorLCR)
  402. returnCluster->setThorLCR("withLCR");
  403. else
  404. returnCluster->setThorLCR("noLCR");
  405. }
  406. int i = 0;
  407. int serverID = -1;
  408. const char* queueName = cluster.getQueueName();
  409. if (queueName && (runningQueues > 0))
  410. {
  411. for (int i = 0; i < runningQueues; i++)
  412. {
  413. const char* serverName = runningQueueNames[i].str();
  414. if (serverName && !stricmp(serverName, queueName))
  415. {
  416. serverID = i;
  417. break;
  418. }
  419. }
  420. }
  421. IArrayOf<IEspTpLogicalCluster> clusters1;
  422. dummy.getTargetClusterList(clusters1, eqThorCluster, cluster.getName());
  423. const char* queuename1 = cluster.getQueueName();
  424. if (clusters1.length() > 0)
  425. {
  426. IEspTpLogicalCluster& logicalCluster = clusters1.item(0);
  427. queuename1 = logicalCluster.getName();
  428. }
  429. QueueWrapper queue(queuename1);
  430. CJobQueueContents contents;
  431. queue->copyItems(contents);
  432. Owned<IJobQueueIterator> iter = contents.getIterator();
  433. unsigned count=0;
  434. ForEach(*iter)
  435. {
  436. if (!isInWuList(aws, iter->query().queryWUID()))
  437. {
  438. try
  439. {
  440. Owned<IEspActiveWorkunit> wu(new CActiveWorkunitWrapper(context, iter->query().queryWUID(),++count));
  441. wu->setServer("ThorMaster");
  442. wu->setInstance(cluster.getName());
  443. wu->setQueueName(cluster.getQueueName());
  444. aws.append(*wu.getLink());
  445. }
  446. catch (IException *e)
  447. {
  448. StringBuffer msg;
  449. Owned<IEspActiveWorkunit> wu(new CActiveWorkunitWrapper(iter->query().queryWUID(), "", "", e->errorMessage(msg).str(), "normal"));
  450. wu->setServer("ThorMaster");
  451. wu->setInstance(cluster.getName());
  452. wu->setQueueName(cluster.getQueueName());
  453. aws.append(*wu.getLink());
  454. }
  455. }
  456. }
  457. int qStatus = 1;
  458. if(queue->stopped())
  459. {
  460. returnCluster->setQueueStatus("stopped");
  461. qStatus = 3;
  462. }
  463. else if (queue->paused())
  464. {
  465. returnCluster->setQueueStatus("paused");
  466. qStatus = 2;
  467. }
  468. else
  469. {
  470. returnCluster->setQueueStatus("running");
  471. }
  472. if (version > 1.06)
  473. {
  474. int color_type = 6;
  475. if (serverID < 0)
  476. {
  477. if (qStatus > 1)
  478. color_type = 3;
  479. else
  480. color_type = 5;
  481. }
  482. else if (runningJobsInQueue[serverID] > 0)
  483. {
  484. if (qStatus > 1)
  485. color_type = 1;
  486. else
  487. color_type = 4;
  488. }
  489. else if (qStatus > 1)
  490. {
  491. color_type = 2;
  492. }
  493. returnCluster->setQueueStatus2(color_type);
  494. }
  495. returnCluster->setDoCommand(doCommand);
  496. ThorClusters.append(*returnCluster);
  497. }
  498. if (version > 1.06)
  499. {
  500. IArrayOf<IEspRoxieCluster> RoxieClusters;
  501. IArrayOf<IEspTpCluster> clusters1;
  502. dummy.getClusterProcessList(eqRoxieCluster,clusters1,true);
  503. ForEachItemIn(x1, clusters1)
  504. {
  505. IEspTpCluster& cluster = clusters1.item(x1);
  506. IEspRoxieCluster* returnCluster = new CRoxieCluster("","");
  507. returnCluster->setClusterName(cluster.getName());
  508. returnCluster->setQueueName(cluster.getQueueName());
  509. IArrayOf<IEspTpLogicalCluster> clusters1;
  510. dummy.getTargetClusterList(clusters1, eqRoxieCluster, cluster.getName());
  511. const char* queuename1 = cluster.getQueueName();
  512. if (clusters1.length() > 0)
  513. {
  514. IEspTpLogicalCluster& logicalCluster = clusters1.item(0);
  515. queuename1 = logicalCluster.getName();
  516. }
  517. QueueWrapper queue(queuename1);
  518. CJobQueueContents contents;
  519. queue->copyItems(contents);
  520. Owned<IJobQueueIterator> iter = contents.getIterator();
  521. unsigned count=0;
  522. ForEach(*iter)
  523. {
  524. try
  525. {
  526. Owned<IEspActiveWorkunit> wu(new CActiveWorkunitWrapper(context, iter->query().queryWUID(),++count));
  527. wu->setServer("RoxieServer");
  528. wu->setInstance(cluster.getName());
  529. wu->setQueueName(cluster.getQueueName());
  530. aws.append(*wu.getLink());
  531. }
  532. catch (IException *e)
  533. {
  534. StringBuffer msg;
  535. Owned<IEspActiveWorkunit> wu(new CActiveWorkunitWrapper(iter->query().queryWUID(), "", "", e->errorMessage(msg).str(), "normal"));
  536. wu->setServer("RoxieServer");
  537. wu->setInstance(cluster.getName());
  538. wu->setQueueName(cluster.getQueueName());
  539. aws.append(*wu.getLink());
  540. }
  541. }
  542. int qStatus = 1;
  543. if(queue->stopped())
  544. {
  545. returnCluster->setQueueStatus("stopped");
  546. qStatus = 3;
  547. }
  548. else if (queue->paused())
  549. {
  550. returnCluster->setQueueStatus("paused");
  551. qStatus = 2;
  552. }
  553. else
  554. {
  555. returnCluster->setQueueStatus("running");
  556. }
  557. RoxieClusters.append(*returnCluster);
  558. }
  559. resp.setRoxieClusters(RoxieClusters);
  560. }
  561. IArrayOf<IConstTpEclServer> eclccservers;
  562. dummy.getTpEclCCServers(eclccservers);
  563. ForEachItemIn(x1, eclccservers)
  564. {
  565. IConstTpEclServer& eclccserver = eclccservers.item(x1);
  566. const char* serverName = eclccserver.getName();
  567. if (!serverName || !*serverName)
  568. continue;
  569. SCMStringBuffer queueName;
  570. getEclCCServerQueueNames(queueName, serverName);
  571. if (queueName.length() < 1)
  572. continue;
  573. Owned <IStringIterator> targetClusters = getTargetClusters(eqEclCCServer, serverName);
  574. if (!targetClusters->first())
  575. continue;
  576. ForEach (*targetClusters)
  577. {
  578. SCMStringBuffer targetCluster;
  579. targetClusters->str(targetCluster);
  580. QueueWrapper queue(targetCluster.str(), queueName.str());
  581. CJobQueueContents contents;
  582. queue->copyItems(contents);
  583. unsigned count=0;
  584. Owned<IJobQueueIterator> iter = contents.getIterator();
  585. ForEach(*iter)
  586. {
  587. if (isInWuList(aws, iter->query().queryWUID()))
  588. continue;
  589. Owned<IEspActiveWorkunit> wu(new CActiveWorkunitWrapper(context, iter->query().queryWUID(),++count));
  590. wu->setServer("ECLCCserver");
  591. wu->setInstance(serverName);
  592. wu->setQueueName(serverName);
  593. aws.append(*wu.getLink());
  594. }
  595. }
  596. }
  597. Owned<IPropertyTree> pEnvRoot = dummy.getEnvironment("");
  598. if (!pEnvRoot)
  599. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO,"Failed to get environment information.");
  600. StringBuffer dirxpath;
  601. dirxpath.append("Software/DfuServerProcess");
  602. Owned<IPropertyTreeIterator> services = pEnvRoot->getElements(dirxpath);
  603. if (services->first())
  604. {
  605. do
  606. {
  607. IPropertyTree &serviceTree = services->query();
  608. const char *queuename = serviceTree.queryProp("@queue");
  609. if (queuename && *queuename)
  610. {
  611. StringArray queues;
  612. loop
  613. {
  614. StringAttr subq;
  615. const char *comma = strchr(queuename,',');
  616. if (comma)
  617. subq.set(queuename,comma-queuename);
  618. else
  619. subq.set(queuename);
  620. bool added;
  621. const char *s = strdup(subq.get());
  622. queues.bAdd(s, stringcmp, added);
  623. if (!added)
  624. free((void *)s);
  625. if (!comma)
  626. break;
  627. queuename = comma+1;
  628. if (!*queuename)
  629. break;
  630. }
  631. ForEachItemIn(q, queues)
  632. {
  633. const char *queuename = queues.item(q);
  634. StringAttrArray wulist;
  635. unsigned running = queuedJobs(queuename, wulist);
  636. ForEachItemIn(i, wulist)
  637. {
  638. const char *wuid = wulist.item(i).text.get();
  639. try
  640. {
  641. StringBuffer jname, uname, state;
  642. Owned<IConstDFUWorkUnit> wu = getDFUWorkUnitFactory()->openWorkUnit(wuid, false);
  643. if (wu)
  644. {
  645. wu->getUser(uname);
  646. wu->getJobName(jname);
  647. if (i<running)
  648. state.append("running");
  649. else
  650. state.append("queued");
  651. Owned<IEspActiveWorkunit> wu1(new CActiveWorkunitWrapper(wuid, uname.str(), jname.str(), state.str(), "normal"));
  652. wu1->setServer("DFUserver");
  653. wu1->setInstance(queuename);
  654. wu1->setQueueName(queuename);
  655. aws.append(*wu1.getLink());
  656. }
  657. }
  658. catch (IException *e)
  659. {
  660. StringBuffer msg;
  661. Owned<IEspActiveWorkunit> wu1(new CActiveWorkunitWrapper(wuid, "", "", e->errorMessage(msg).str(), "normal"));
  662. wu1->setServer("DFUserver");
  663. wu1->setInstance(queuename);
  664. wu1->setQueueName(queuename);
  665. aws.append(*wu1.getLink());
  666. }
  667. }
  668. }
  669. }
  670. } while (services->next());
  671. }
  672. resp.setThorClusters(ThorClusters);
  673. resp.setRunning(aws);
  674. clusters.kill();
  675. dummy.getClusterProcessList(eqHoleCluster,clusters);
  676. IArrayOf<IEspHoleCluster> HoleClusters;
  677. ForEachItemIn(y, clusters)
  678. {
  679. IEspTpCluster& cluster = clusters.item(y);
  680. IEspHoleCluster* returnCluster = new CHoleCluster("","");
  681. returnCluster->setClusterName(cluster.getName());
  682. returnCluster->setDataModel(cluster.getDataModel());
  683. HoleClusters.append(*returnCluster);
  684. }
  685. resp.setHoleClusters(HoleClusters);
  686. IArrayOf<IEspDFUJob> jobs;
  687. conn.setown(querySDS().connect("DFU/RECOVERY",myProcessSession(),0, INFINITE));
  688. if (conn)
  689. {
  690. Owned<IPropertyTreeIterator> it(conn->queryRoot()->getElements("job"));
  691. ForEach(*it)
  692. {
  693. IPropertyTree &e=it->query();
  694. if (e.getPropBool("Running",false))
  695. {
  696. unsigned done;
  697. unsigned total;
  698. countProgress(&e,done,total);
  699. Owned<IEspDFUJob> job = new CDFUJob("","");
  700. job->setTimeStarted(e.queryProp("@time_started"));
  701. job->setDone(done);
  702. job->setTotal(total);
  703. StringBuffer cmd;
  704. cmd.append(e.queryProp("@command")).append(" ").append(e.queryProp("@command_parameters"));
  705. job->setCommand(cmd.str());
  706. jobs.append(*job.getLink());
  707. }
  708. }
  709. }
  710. resp.setDFUJobs(jobs);
  711. }
  712. catch(IException* e)
  713. {
  714. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  715. }
  716. return true;
  717. }
  718. void CWsSMCEx::addCapabilities(IPropertyTree* pFeatureNode, const char* access,
  719. IArrayOf<IEspCapability>& capabilities)
  720. {
  721. StringBuffer xpath(access);
  722. xpath.append("/Capability");
  723. Owned<IPropertyTreeIterator> it = pFeatureNode->getElements(xpath.str());
  724. ForEach(*it)
  725. {
  726. IPropertyTree* pCapabilityNode = &it->query();
  727. IEspCapability* pCapability = new CCapability("ws_smc");
  728. pCapability->setName( pCapabilityNode->queryProp("@name") );
  729. pCapability->setDescription( pCapabilityNode->queryProp("@description") );
  730. capabilities.append(*pCapability);
  731. }
  732. }
  733. static void checkAccess(IEspContext &context, const char* feature,int level)
  734. {
  735. if (!context.validateFeatureAccess(feature, level, false))
  736. throw MakeStringException(ECLWATCH_THOR_QUEUE_ACCESS_DENIED, "Failed to access the queue functions. Permission denied.");
  737. }
  738. bool CWsSMCEx::onMoveJobDown(IEspContext &context, IEspSMCJobRequest &req, IEspSMCJobResponse &resp)
  739. {
  740. try
  741. {
  742. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  743. QueueWrapper queue(req.getClusterType(), req.getCluster());
  744. QueueLock lock(queue);
  745. unsigned index=queue->findRank(req.getWuid());
  746. if(index<queue->ordinality())
  747. {
  748. IJobQueueItem * item0 = queue->getItem(index);
  749. IJobQueueItem * item = queue->getItem(index+1);
  750. if(item && item0 && (item0->getPriority() == item->getPriority()))
  751. queue->moveAfter(req.getWuid(),item->queryWUID());
  752. }
  753. AccessSuccess(context, "Changed job priority %s",req.getWuid());
  754. resp.setRedirectUrl("/WsSMC/");
  755. }
  756. catch(IException* e)
  757. {
  758. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  759. }
  760. return true;
  761. }
  762. bool CWsSMCEx::onMoveJobUp(IEspContext &context, IEspSMCJobRequest &req, IEspSMCJobResponse &resp)
  763. {
  764. try
  765. {
  766. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  767. QueueWrapper queue(req.getClusterType(), req.getCluster());
  768. QueueLock lock(queue);
  769. unsigned index=queue->findRank(req.getWuid());
  770. if(index>0 && index<queue->ordinality())
  771. {
  772. IJobQueueItem * item0 = queue->getItem(index);
  773. IJobQueueItem * item = queue->getItem(index-1);
  774. if(item && item0 && (item0->getPriority() == item->getPriority()))
  775. queue->moveBefore(req.getWuid(),item->queryWUID());
  776. }
  777. AccessSuccess(context, "Changed job priority %s",req.getWuid());
  778. resp.setRedirectUrl("/WsSMC/");
  779. }
  780. catch(IException* e)
  781. {
  782. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  783. }
  784. return true;
  785. }
  786. bool CWsSMCEx::onMoveJobBack(IEspContext &context, IEspSMCJobRequest &req, IEspSMCJobResponse &resp)
  787. {
  788. try
  789. {
  790. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  791. QueueWrapper queue(req.getClusterType(), req.getCluster());
  792. QueueLock lock(queue);
  793. unsigned index=queue->findRank(req.getWuid());
  794. if(index<queue->ordinality())
  795. {
  796. int priority0 = queue->getItem(index)->getPriority();
  797. unsigned biggestIndoxInSamePriority = index;
  798. unsigned nextIndex = biggestIndoxInSamePriority + 1;
  799. while (nextIndex<queue->ordinality())
  800. {
  801. IJobQueueItem * item = queue->getItem(nextIndex);
  802. if (priority0 != item->getPriority())
  803. {
  804. break;
  805. }
  806. biggestIndoxInSamePriority = nextIndex;
  807. nextIndex++;
  808. }
  809. if (biggestIndoxInSamePriority != index)
  810. {
  811. IJobQueueItem * item = queue->getItem(biggestIndoxInSamePriority);
  812. queue->moveAfter(req.getWuid(),item->queryWUID());
  813. }
  814. }
  815. AccessSuccess(context, "Changed job priority %s",req.getWuid());
  816. resp.setRedirectUrl("/WsSMC/");
  817. }
  818. catch(IException* e)
  819. {
  820. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  821. }
  822. return true;
  823. }
  824. bool CWsSMCEx::onMoveJobFront(IEspContext &context, IEspSMCJobRequest &req, IEspSMCJobResponse &resp)
  825. {
  826. try
  827. {
  828. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  829. QueueWrapper queue(req.getClusterType(), req.getCluster());
  830. QueueLock lock(queue);
  831. unsigned index=queue->findRank(req.getWuid());
  832. if(index>0 && index<queue->ordinality())
  833. {
  834. int priority0 = queue->getItem(index)->getPriority();
  835. unsigned smallestIndoxInSamePriority = index;
  836. int nextIndex = smallestIndoxInSamePriority - 1;
  837. while (nextIndex >= 0)
  838. {
  839. IJobQueueItem * item = queue->getItem(nextIndex);
  840. if (priority0 != item->getPriority())
  841. {
  842. break;
  843. }
  844. smallestIndoxInSamePriority = nextIndex;
  845. nextIndex--;
  846. }
  847. if (smallestIndoxInSamePriority != index)
  848. {
  849. IJobQueueItem * item = queue->getItem(smallestIndoxInSamePriority);
  850. queue->moveBefore(req.getWuid(),item->queryWUID());
  851. }
  852. }
  853. AccessSuccess(context, "Changed job priority %s",req.getWuid());
  854. resp.setRedirectUrl("/WsSMC/");
  855. }
  856. catch(IException* e)
  857. {
  858. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  859. }
  860. return true;
  861. }
  862. bool CWsSMCEx::onRemoveJob(IEspContext &context, IEspSMCJobRequest &req, IEspSMCJobResponse &resp)
  863. {
  864. try
  865. {
  866. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  867. secAbortWorkUnit(req.getWuid(), *context.querySecManager(), *context.queryUser());
  868. QueueWrapper queue(req.getClusterType(), req.getCluster());
  869. QueueLock lock(queue);
  870. unsigned index=queue->findRank(req.getWuid());
  871. if(index<queue->ordinality())
  872. {
  873. if(!queue->cancelInitiateConversation(req.getWuid()))
  874. throw MakeStringException(ECLWATCH_CANNOT_DELETE_WORKUNIT,"Failed to remove the workunit %s",req.getWuid());
  875. }
  876. AccessSuccess(context, "Removed job %s",req.getWuid());
  877. resp.setRedirectUrl("/WsSMC/");
  878. }
  879. catch(IException* e)
  880. {
  881. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  882. }
  883. return true;
  884. }
  885. bool CWsSMCEx::onStopQueue(IEspContext &context, IEspSMCQueueRequest &req, IEspSMCQueueResponse &resp)
  886. {
  887. try
  888. {
  889. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  890. QueueWrapper(req.getClusterType(), req.getCluster())->stop();
  891. AccessSuccess(context, "Stopped queue %s",req.getCluster());
  892. resp.setRedirectUrl("/WsSMC/");
  893. }
  894. catch(IException* e)
  895. {
  896. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  897. }
  898. return true;
  899. }
  900. bool CWsSMCEx::onResumeQueue(IEspContext &context, IEspSMCQueueRequest &req, IEspSMCQueueResponse &resp)
  901. {
  902. try
  903. {
  904. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  905. QueueWrapper(req.getClusterType(), req.getCluster())->resume();
  906. AccessSuccess(context, "Resumed queue %s",req.getCluster());
  907. resp.setRedirectUrl("/WsSMC/");
  908. }
  909. catch(IException* e)
  910. {
  911. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  912. }
  913. return true;
  914. }
  915. bool CWsSMCEx::onPauseQueue(IEspContext &context, IEspSMCQueueRequest &req, IEspSMCQueueResponse &resp)
  916. {
  917. try
  918. {
  919. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  920. QueueWrapper(req.getClusterType(), req.getCluster())->pause();
  921. AccessSuccess(context, "Paused queue %s",req.getCluster());
  922. resp.setRedirectUrl("/WsSMC/");
  923. }
  924. catch(IException* e)
  925. {
  926. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  927. }
  928. return true;
  929. }
  930. bool CWsSMCEx::onClearQueue(IEspContext &context, IEspSMCQueueRequest &req, IEspSMCQueueResponse &resp)
  931. {
  932. try
  933. {
  934. checkAccess(context,THORQUEUE_FEATURE,SecAccess_Full);
  935. QueueWrapper queue(req.getClusterType(), req.getCluster());
  936. {
  937. QueueLock lock(queue);
  938. for(unsigned i=0;i<queue->ordinality();i++)
  939. secAbortWorkUnit(queue->getItem(i)->queryWUID(), *context.querySecManager(), *context.queryUser());
  940. queue->clear();
  941. }
  942. AccessSuccess(context, "Cleared queue %s",req.getCluster());
  943. resp.setRedirectUrl("/WsSMC/");
  944. }
  945. catch(IException* e)
  946. {
  947. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  948. }
  949. return true;
  950. }
  951. bool CWsSMCEx::onSetJobPriority(IEspContext &context, IEspSMCPriorityRequest &req, IEspSMCPriorityResponse &resp)
  952. {
  953. try
  954. {
  955. Owned<IWorkUnitFactory> factory = getSecWorkUnitFactory(*context.querySecManager(), *context.queryUser());
  956. Owned<IWorkUnit> lw = factory->updateWorkUnit(req.getWuid());
  957. if(stricmp(req.getPriority(),"high")==0)
  958. lw->setPriority(PriorityClassHigh);
  959. else if(stricmp(req.getPriority(),"normal")==0)
  960. lw->setPriority(PriorityClassNormal);
  961. else if(stricmp(req.getPriority(),"low")==0)
  962. lw->setPriority(PriorityClassLow);
  963. // set job priority
  964. int priority = lw->getPriorityValue();
  965. QueueWrapper queue(req.getClusterType(), req.getCluster());
  966. QueueLock lock(queue);
  967. queue->changePriority(req.getWuid(),priority);
  968. resp.setRedirectUrl("/WsSMC/");
  969. }
  970. catch(IException* e)
  971. {
  972. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  973. }
  974. return true;
  975. }
  976. bool CWsSMCEx::onGetThorQueueAvailability(IEspContext &context, IEspGetThorQueueAvailabilityRequest &req, IEspGetThorQueueAvailabilityResponse& resp)
  977. {
  978. try
  979. {
  980. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  981. throw MakeStringException(ECLWATCH_SMC_ACCESS_DENIED, "Failed to get Thor Queue availability. Permission denied.");
  982. CTpWrapper dummy;
  983. IArrayOf<IEspTpCluster> clusters;
  984. dummy.getClusterProcessList(eqThorCluster,clusters,true);
  985. IArrayOf<IEspThorCluster> ThorClusters;
  986. ForEachItemIn(x, clusters)
  987. {
  988. IEspTpCluster& cluster = clusters.item(x);
  989. IEspThorCluster* returnCluster = new CThorCluster("","");
  990. returnCluster->setClusterName(cluster.getName());
  991. returnCluster->setQueueName(cluster.getQueueName());
  992. QueueWrapper queue(cluster.getQueueName());
  993. if(queue->stopped())
  994. returnCluster->setQueueStatus("stopped");
  995. else if (queue->paused())
  996. returnCluster->setQueueStatus("paused");
  997. else
  998. returnCluster->setQueueStatus("running");
  999. unsigned enqueued=0;
  1000. unsigned connected=0;
  1001. unsigned waiting=0;
  1002. queue->getStats(connected,waiting,enqueued);
  1003. returnCluster->setQueueAvailable(waiting);
  1004. returnCluster->setJobsRunning(connected - waiting);
  1005. returnCluster->setJobsInQueue(enqueued);
  1006. ThorClusters.append(*returnCluster);
  1007. }
  1008. resp.setThorClusters(ThorClusters);
  1009. }
  1010. catch(IException* e)
  1011. {
  1012. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1013. }
  1014. return true;
  1015. }
  1016. bool CWsSMCEx::onSetBanner(IEspContext &context, IEspSetBannerRequest &req, IEspSetBannerResponse& resp)
  1017. {
  1018. try
  1019. {
  1020. CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
  1021. if(!secmgr || !secmgr->isSuperUser(context.queryUser()))
  1022. throw MakeStringException(ECLWATCH_SUPER_USER_ACCESS_DENIED, "access denied, administrators only.");
  1023. StringBuffer chatURLStr, bannerStr;
  1024. const char* chatURL = req.getChatURL();
  1025. const char* banner = req.getBannerContent();
  1026. //Only display valid strings
  1027. if (chatURL)
  1028. {
  1029. const char* pStr = chatURL;
  1030. for (unsigned i = 0; i < strlen(chatURL); i++)
  1031. {
  1032. if ((pStr[0] > 31) && (pStr[0] < 127))
  1033. chatURLStr.append(pStr[0]);
  1034. pStr++;
  1035. }
  1036. }
  1037. if (banner)
  1038. {
  1039. const char* pStr = banner;
  1040. for (unsigned i = 0; i < strlen(banner); i++)
  1041. {
  1042. if ((pStr[0] > 31) && (pStr[0] < 127))
  1043. bannerStr.append(pStr[0]);
  1044. pStr++;
  1045. }
  1046. }
  1047. chatURLStr.trim();
  1048. bannerStr.trim();
  1049. if (!req.getBannerAction_isNull() && req.getBannerAction() && (bannerStr.length() < 1))
  1050. {
  1051. throw MakeStringException(ECLWATCH_MISSING_BANNER_CONTENT, "If a Banner is enabled, the Banner content must be specified.");
  1052. }
  1053. if (!req.getEnableChatURL_isNull() && req.getEnableChatURL() && (!req.getChatURL() || !*req.getChatURL()))
  1054. {
  1055. throw MakeStringException(ECLWATCH_MISSING_CHAT_URL, "If a Chat is enabled, the Chat URL must be specified.");
  1056. }
  1057. m_ChatURL = chatURLStr;
  1058. m_Banner = bannerStr;
  1059. const char* bannerSize = req.getBannerSize();
  1060. if (bannerSize && *bannerSize)
  1061. m_BannerSize.clear().append(bannerSize);
  1062. const char* bannerColor = req.getBannerColor();
  1063. if (bannerColor && *bannerColor)
  1064. m_BannerColor.clear().append(bannerColor);
  1065. const char* bannerScroll = req.getBannerScroll();
  1066. if (bannerScroll && *bannerScroll)
  1067. m_BannerScroll.clear().append(bannerScroll);
  1068. m_BannerAction = 0;
  1069. if(!req.getBannerAction_isNull())
  1070. m_BannerAction = req.getBannerAction();
  1071. m_EnableChatURL = 0;
  1072. if(!req.getEnableChatURL_isNull())
  1073. m_EnableChatURL = req.getEnableChatURL();
  1074. resp.setRedirectUrl("/WsSMC/Activity");
  1075. }
  1076. catch(IException* e)
  1077. {
  1078. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1079. }
  1080. return true;
  1081. }
  1082. bool CWsSMCEx::onNotInCommunityEdition(IEspContext &context, IEspNotInCommunityEditionRequest &req, IEspNotInCommunityEditionResponse &resp)
  1083. {
  1084. return true;
  1085. }
  1086. bool CWsSMCEx::onBrowseResources(IEspContext &context, IEspBrowseResourcesRequest & req, IEspBrowseResourcesResponse & resp)
  1087. {
  1088. try
  1089. {
  1090. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1091. throw MakeStringException(ECLWATCH_SMC_ACCESS_DENIED, "Failed to Browse Resources. Permission denied.");
  1092. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  1093. Owned<IConstEnvironment> constEnv = factory->openEnvironmentByFile();
  1094. //The resource files will be downloaded from the same box of ESP (not dali)
  1095. StringBuffer ipStr;
  1096. IpAddress ipaddr = queryHostIP();
  1097. ipaddr.getIpText(ipStr);
  1098. if (ipStr.length() > 0)
  1099. {
  1100. resp.setNetAddress(ipStr.str());
  1101. Owned<IConstMachineInfo> machine = constEnv->getMachineByAddress(ipStr.str());
  1102. if (machine)
  1103. {
  1104. int os = machine->getOS();
  1105. resp.setOS(os);
  1106. }
  1107. }
  1108. if (m_PortalURL.length() > 0)
  1109. resp.setPortalURL(m_PortalURL.str());
  1110. //Now, get a list of resources stored inside the ESP box
  1111. IArrayOf<IEspHPCCResourceRepository> resourceRepositories;
  1112. Owned<IPropertyTree> pEnvRoot = &constEnv->getPTree();
  1113. const char* ossInstall = pEnvRoot->queryProp("EnvSettings/path");
  1114. if (!ossInstall || !*ossInstall)
  1115. {
  1116. WARNLOG("Failed to get EnvSettings/Path in environment settings.");
  1117. return true;
  1118. }
  1119. StringBuffer path;
  1120. path.appendf("%s/componentfiles/files/downloads", ossInstall);
  1121. Owned<IFile> f = createIFile(path.str());
  1122. if(!f->exists() || !f->isDirectory())
  1123. {
  1124. WARNLOG("Invalid resource folder");
  1125. return true;
  1126. }
  1127. Owned<IDirectoryIterator> di = f->directoryFiles(NULL, false, true);
  1128. if(di.get() == NULL)
  1129. {
  1130. WARNLOG("Resource folder is empty.");
  1131. return true;
  1132. }
  1133. ForEach(*di)
  1134. {
  1135. if (!di->isDir())
  1136. continue;
  1137. StringBuffer folder, path0, tmpBuf;
  1138. di->getName(folder);
  1139. if (folder.length() == 0)
  1140. continue;
  1141. path0.appendf("%s/%s/description.xml", path.str(), folder.str());
  1142. Owned<IFile> f0 = createIFile(path0.str());
  1143. if(!f0->exists())
  1144. {
  1145. WARNLOG("Description file not found for %s", folder.str());
  1146. continue;
  1147. }
  1148. OwnedIFileIO rIO = f0->openShared(IFOread,IFSHfull);
  1149. if(!rIO)
  1150. {
  1151. WARNLOG("Failed to open the description file for %s", folder.str());
  1152. continue;
  1153. }
  1154. offset_t fileSize = f0->size();
  1155. tmpBuf.ensureCapacity((unsigned)fileSize);
  1156. tmpBuf.setLength((unsigned)fileSize);
  1157. size32_t nRead = rIO->read(0, (size32_t) fileSize, (char*)tmpBuf.str());
  1158. if (nRead != fileSize)
  1159. {
  1160. WARNLOG("Failed to read the description file for %s", folder.str());
  1161. continue;
  1162. }
  1163. Owned<IPropertyTree> desc = createPTreeFromXMLString(tmpBuf.str());
  1164. if (!desc)
  1165. {
  1166. WARNLOG("Invalid description file for %s", folder.str());
  1167. continue;
  1168. }
  1169. Owned<IPropertyTreeIterator> fileIterator = desc->getElements("file");
  1170. if (!fileIterator->first())
  1171. {
  1172. WARNLOG("Invalid description file for %s", folder.str());
  1173. continue;
  1174. }
  1175. IArrayOf<IEspHPCCResource> resourcs;
  1176. do {
  1177. IPropertyTree &fileItem = fileIterator->query();
  1178. const char* filename = fileItem.queryProp("filename");
  1179. if (!filename || !*filename)
  1180. continue;
  1181. const char* name0 = fileItem.queryProp("name");
  1182. const char* description0 = fileItem.queryProp("description");
  1183. const char* version0 = fileItem.queryProp("version");
  1184. Owned<IEspHPCCResource> onefile = createHPCCResource();
  1185. onefile->setFileName(filename);
  1186. if (name0 && *name0)
  1187. onefile->setName(name0);
  1188. if (description0 && *description0)
  1189. onefile->setDescription(description0);
  1190. if (version0 && *version0)
  1191. onefile->setVersion(version0);
  1192. resourcs.append(*onefile.getLink());
  1193. } while (fileIterator->next());
  1194. if (resourcs.ordinality())
  1195. {
  1196. StringBuffer path1;
  1197. path1.appendf("%s/%s", path.str(), folder.str());
  1198. Owned<IEspHPCCResourceRepository> oneRepository = createHPCCResourceRepository();
  1199. oneRepository->setName(folder.str());
  1200. oneRepository->setPath(path1.str());
  1201. oneRepository->setHPCCResources(resourcs);
  1202. resourceRepositories.append(*oneRepository.getLink());
  1203. }
  1204. }
  1205. if (resourceRepositories.ordinality())
  1206. resp.setHPCCResourceRepositories(resourceRepositories);
  1207. }
  1208. catch(IException* e)
  1209. {
  1210. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1211. }
  1212. return true;
  1213. }
  1214. int CWsSMCSoapBindingEx::onGetForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method)
  1215. {
  1216. try
  1217. {
  1218. if(stricmp(method,"NotInCommunityEdition")==0)
  1219. {
  1220. StringBuffer page, url, link;
  1221. request->getParameter("EEPortal", url);
  1222. if (url.length() > 0)
  1223. link.appendf("Further information can be found at <a href=\"%s\" target=\"_blank\">%s</a>.", url.str(), url.str());
  1224. page.append(
  1225. "<html>"
  1226. "<head>"
  1227. "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
  1228. "<link rel=\"stylesheet\" type=\"text/css\" href=\"/esp/files/default.css\"/>"
  1229. "<link rel=\"stylesheet\" type=\"text/css\" href=\"/esp/files/yui/build/fonts/fonts-min.css\" />"
  1230. "<title>Advanced feature in Enterprise Edition</title>"
  1231. "</head>"
  1232. "<body>"
  1233. "<h3 style=\"text-align:centre;\">Advanced feature in the Enterprise Edition</h4>"
  1234. "<p style=\"text-align:centre;\">This feature is only available with the Enterprise Edition. ");
  1235. if (link.length() > 0)
  1236. page.append(link.str());
  1237. page.append("</p></body>"
  1238. "</html>");
  1239. response->setContent(page.str());
  1240. response->setContentType("text/html");
  1241. response->send();
  1242. return 0;
  1243. }
  1244. }
  1245. catch(IException* e)
  1246. {
  1247. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1248. }
  1249. return onGetForm(context, request, response, service, method);
  1250. }