ws_smcService.cpp 54 KB

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