ws_workunitsService.cpp 119 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369
  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. #include "ws_workunitsService.hpp"
  15. #include "ws_fs.hpp"
  16. #include "jlib.hpp"
  17. #include "daclient.hpp"
  18. #include "dalienv.hpp"
  19. #include "dadfs.hpp"
  20. #include "daaudit.hpp"
  21. #include "exception_util.hpp"
  22. #include "wujobq.hpp"
  23. #include "eventqueue.hpp"
  24. #include "fileview.hpp"
  25. #include "hqlerror.hpp"
  26. #include "sacmd.hpp"
  27. #include "wuwebview.hpp"
  28. #include "portlist.h"
  29. #include "dllserver.hpp"
  30. #include "schedulectrl.hpp"
  31. #include "scheduleread.hpp"
  32. #include "roxiemanager.hpp"
  33. #include "dadfs.hpp"
  34. #include "dfuwu.hpp"
  35. #include "thorplugin.hpp"
  36. #ifdef _USE_ZLIB
  37. #include "zcrypt.hpp"
  38. #endif
  39. #define ESP_WORKUNIT_DIR "workunits/"
  40. class NewWsWorkunit : public Owned<IWorkUnit>
  41. {
  42. public:
  43. NewWsWorkunit(IWorkUnitFactory *factory, IEspContext &context)
  44. {
  45. create(factory, context);
  46. }
  47. NewWsWorkunit(IEspContext &context)
  48. {
  49. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  50. create(factory, context);
  51. }
  52. ~NewWsWorkunit() { if (get()) get()->commit(); }
  53. void create(IWorkUnitFactory *factory, IEspContext &context)
  54. {
  55. setown(factory->createWorkUnit(NULL, "ws_workunits", context.queryUserId()));
  56. if(!get())
  57. throw MakeStringException(ECLWATCH_CANNOT_CREATE_WORKUNIT,"Could not create workunit.");
  58. get()->setUser(context.queryUserId());
  59. }
  60. };
  61. void submitWsWorkunit(IEspContext& context, IConstWorkUnit* cw, const char* cluster, const char* snapshot, int maxruntime, bool compile, bool resetWorkflow)
  62. {
  63. ensureWsWorkunitAccess(context, *cw, SecAccess_Write);
  64. switch(cw->getState())
  65. {
  66. case WUStateRunning:
  67. case WUStateDebugPaused:
  68. case WUStateDebugRunning:
  69. case WUStateCompiling:
  70. case WUStateAborting:
  71. case WUStateBlocked:
  72. {
  73. SCMStringBuffer descr;
  74. throw MakeStringException(ECLWATCH_CANNOT_SUBMIT_WORKUNIT, "Cannot submit the workunit. Workunit state is '%s'.", cw->getStateDesc(descr).str());
  75. }
  76. }
  77. SCMStringBuffer wuid;
  78. cw->getWuid(wuid);
  79. WorkunitUpdate wu(&cw->lock());
  80. if(!wu.get())
  81. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT, "Cannot update workunit %s.", wuid.str());
  82. wu->clearExceptions();
  83. if(notEmpty(cluster))
  84. wu->setClusterName(cluster);
  85. if(notEmpty(snapshot))
  86. wu->setSnapshot(snapshot);
  87. wu->setState(WUStateSubmitted);
  88. if (maxruntime)
  89. wu->setDebugValueInt("maxRunTime",maxruntime,true);
  90. if (resetWorkflow)
  91. {
  92. wu->resetWorkflow();
  93. if (!compile)
  94. wu->schedule();
  95. }
  96. wu->commit();
  97. wu.clear();
  98. if (!compile)
  99. runWorkUnit(wuid.str());
  100. else if (context.querySecManager())
  101. secSubmitWorkUnit(wuid.str(), *context.querySecManager(), *context.queryUser());
  102. else
  103. submitWorkUnit(wuid.str(), context.queryUserId(), context.queryPassword());
  104. AuditSystemAccess(context.queryUserId(), true, "Submitted %s", wuid.str());
  105. }
  106. void submitWsWorkunit(IEspContext& context, const char *wuid, const char* cluster, const char* snapshot, int maxruntime, bool compile, bool resetWorkflow)
  107. {
  108. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  109. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
  110. return submitWsWorkunit(context, cw, cluster, snapshot, maxruntime, compile, resetWorkflow);
  111. }
  112. typedef enum _WuActionType
  113. {
  114. ActionDelete=0,
  115. ActionProtect,
  116. ActionAbort,
  117. ActionRestore,
  118. ActionEventSchedule,
  119. ActionEventDeschedule,
  120. ActionChangeState,
  121. ActionPause,
  122. ActionPauseNow,
  123. ActionResume,
  124. ActionUnknown
  125. } WsWuActionType;
  126. bool doAction(IEspContext& context, StringArray& wuids, int action, IProperties* params, IArrayOf<IConstWUActionResult>* results)
  127. {
  128. if (!wuids.length())
  129. return true;
  130. Owned<IMultiException> me = MakeMultiException();
  131. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  132. bool bAllSuccess = true;
  133. for(aindex_t i=0; i<wuids.length();i++)
  134. {
  135. const char* wuid=wuids.item(i);
  136. if (isEmpty(wuid))
  137. continue;
  138. try
  139. {
  140. if (action == ActionRestore)
  141. {
  142. StringBuffer strAction("Restore");
  143. SocketEndpoint ep;
  144. getSashaNode(ep);
  145. Owned<ISashaCommand> cmd = createSashaCommand();
  146. cmd->setAction(SCA_RESTORE);
  147. cmd->addId(wuid);
  148. Owned<INode> node = createINode(ep);
  149. if (!node)
  150. throw MakeStringException(ECLWATCH_INODE_NOT_FOUND,"INode not found.");
  151. StringBuffer s;
  152. if (!cmd->send(node, 1*60*1000))
  153. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_ARCHIVE_SERVER,"Cannot connect to Archive server at %s.", ep.getUrlStr(s).str());
  154. if (cmd->numIds()==0)
  155. {
  156. WARNLOG("Could not Archive/restore %s",wuid);
  157. me->append(*MakeStringException(0,"Cannot archive/restore workunit %s.", wuid));
  158. }
  159. StringBuffer reply;
  160. cmd->getId(0,reply);
  161. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid);
  162. ensureWsWorkunitAccess(context, wuid, SecAccess_Write);
  163. if (results)
  164. {
  165. Owned<IEspWUActionResult> res = createWUActionResult("", "");
  166. res->setWuid(wuid);
  167. res->setAction(strAction.str());
  168. res->setResult("Success");
  169. results->append(*res.getClear());
  170. }
  171. }
  172. else
  173. {
  174. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  175. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
  176. StringBuffer strAction;
  177. Owned<IEspWUActionResult> res = createWUActionResult("", "");
  178. res->setWuid(wuid);
  179. res->setResult("Success");
  180. if ((action == ActionDelete) && (cw->getState() == WUStateWait))
  181. throw MakeStringException(ECLWATCH_CANNOT_DELETE_WORKUNIT,"Cannot delete a workunit which is in a 'Wait' status.");
  182. try
  183. {
  184. switch(action)
  185. {
  186. case ActionPause:
  187. {
  188. ensureWsWorkunitAccess(context, *cw, SecAccess_Full);
  189. WorkunitUpdate wu(&cw->lock());
  190. strAction = "Pause";
  191. wu->setAction(WUActionPause);
  192. break;
  193. }
  194. case ActionPauseNow:
  195. {
  196. ensureWsWorkunitAccess(context, *cw, SecAccess_Full);
  197. strAction = "PauseNow";
  198. WorkunitUpdate wu(&cw->lock());
  199. wu->setAction(WUActionPauseNow);
  200. break;
  201. }
  202. case ActionResume:
  203. {
  204. ensureWsWorkunitAccess(context, *cw, SecAccess_Full);
  205. strAction = "Resume";
  206. WorkunitUpdate wu(&cw->lock());
  207. wu->setAction(WUActionResume);
  208. break;
  209. }
  210. case ActionDelete:
  211. ensureWsWorkunitAccess(context, *cw, SecAccess_Full);
  212. strAction = "Delete";
  213. {
  214. int state = cw->getState();
  215. switch (state)
  216. {
  217. case WUStateWait:
  218. throw MakeStringException(ECLWATCH_CANNOT_DELETE_WORKUNIT,"Cannot delete a workunit which is in a 'Wait' status.");
  219. case WUStateAborted:
  220. case WUStateCompleted:
  221. case WUStateFailed:
  222. case WUStateArchived:
  223. case WUStateCompiled:
  224. case WUStateUploadingFiles:
  225. break;
  226. default:
  227. {
  228. WorkunitUpdate wu(&cw->lock());
  229. wu->setState(WUStateFailed);
  230. }
  231. }
  232. cw.clear();
  233. factory->deleteWorkUnitEx(wuid);
  234. AuditSystemAccess(context.queryUserId(), true, "Deleted %s", wuid);
  235. }
  236. break;
  237. case ActionAbort:
  238. ensureWsWorkunitAccess(context, *cw, SecAccess_Full);
  239. strAction = "Abort";
  240. {
  241. if (cw->getState() == WUStateWait)
  242. {
  243. WorkunitUpdate wu(&cw->lock());
  244. wu->deschedule();
  245. wu->setState(WUStateAborted);
  246. }
  247. else
  248. secAbortWorkUnit(wuid, *context.querySecManager(), *context.queryUser());
  249. AuditSystemAccess(context.queryUserId(), true, "Aborted %s", wuid);
  250. }
  251. break;
  252. case ActionProtect:
  253. strAction = "Protect";
  254. cw->protect(!params || params->getPropBool("Protect",true));
  255. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid);
  256. break;
  257. case ActionChangeState:
  258. strAction = "ChangeState";
  259. {
  260. if (params)
  261. {
  262. WUState state = (WUState) params->getPropInt("State");
  263. if (state > WUStateUnknown && state < WUStateSize)
  264. {
  265. WorkunitUpdate wu(&cw->lock());
  266. wu->setState(state);
  267. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid);
  268. }
  269. }
  270. }
  271. break;
  272. case ActionEventSchedule:
  273. strAction = "EventSchedule";
  274. {
  275. WorkunitUpdate wu(&cw->lock());
  276. wu->schedule();
  277. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid);
  278. }
  279. break;
  280. case ActionEventDeschedule:
  281. strAction = "EventDeschedule";
  282. {
  283. WorkunitUpdate wu(&cw->lock());
  284. wu->deschedule();
  285. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid);
  286. }
  287. break;
  288. }
  289. }
  290. catch (IException *e)
  291. {
  292. bAllSuccess = false;
  293. StringBuffer eMsg;
  294. StringBuffer failedMsg("Failed: ");
  295. res->setResult(failedMsg.append(e->errorMessage(eMsg)).str());
  296. WARNLOG("Failed to %s workunit: %s, %s", strAction.str(), wuid, eMsg.str());
  297. AuditSystemAccess(context.queryUserId(), false, "Failed to %s %s", strAction.str(), wuid);
  298. e->Release();
  299. }
  300. if (results)
  301. {
  302. res->setAction(strAction.str());
  303. results->append(*res.getClear());
  304. }
  305. }
  306. }
  307. catch (IException *E)
  308. {
  309. me->append(*E);
  310. }
  311. catch (...)
  312. {
  313. me->append(*MakeStringException(0,"Unknown exception wuid=%s",wuid));
  314. }
  315. }
  316. if(me->ordinality())
  317. throw me.getLink();
  318. int timeToWait = 0;
  319. if (params)
  320. timeToWait = params->getPropInt("BlockTillFinishTimer");
  321. if (timeToWait != 0)
  322. {
  323. for(aindex_t i=0; i<wuids.length();i++)
  324. {
  325. const char* wuid=wuids.item(i);
  326. if (isEmpty(wuid))
  327. continue;
  328. waitForWorkUnitToComplete(wuid, timeToWait);
  329. }
  330. }
  331. return bAllSuccess;
  332. }
  333. MapStringTo<int> wuActionTable;
  334. void CWsWorkunitsEx::init(IPropertyTree *cfg, const char *process, const char *service)
  335. {
  336. if (!daliClientActive())
  337. {
  338. ERRLOG("No Dali Connection Active.");
  339. throw MakeStringException(-1, "No Dali Connection Active. Please Specify a Dali to connect to in you configuration file");
  340. }
  341. setPasswordsFromSDS();
  342. DBGLOG("Initializing %s service [process = %s]", service, process);
  343. wuActionTable.setValue("delete", ActionDelete);
  344. wuActionTable.setValue("abort", ActionAbort);
  345. wuActionTable.setValue("pausenow", ActionPauseNow);
  346. wuActionTable.setValue("pause", ActionPause);
  347. wuActionTable.setValue("resume", ActionResume);
  348. wuActionTable.setValue("protect", ActionProtect);
  349. wuActionTable.setValue("unprotect", ActionProtect);
  350. wuActionTable.setValue("restore", ActionRestore);
  351. wuActionTable.setValue("reschedule", ActionEventSchedule);
  352. wuActionTable.setValue("deschedule", ActionEventDeschedule);
  353. wuActionTable.setValue("settofailed", ActionChangeState);
  354. awusCacheMinutes = AWUS_CACHE_MIN_DEFAULT;
  355. VStringBuffer xpath("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/AWUsCacheMinutes", process, service);
  356. cfg->getPropInt(xpath.str(), awusCacheMinutes);
  357. dataCache.setown(new DataCache(DATA_SIZE));
  358. archivedWuCache.setown(new ArchivedWuCache(AWUS_CACHE_SIZE));
  359. //Create a folder for temporarily holding gzip files by WUResultBin()
  360. Owned<IFile> tmpdir = createIFile(TEMPZIPDIR);
  361. if(!tmpdir->exists())
  362. tmpdir->createDirectory();
  363. recursiveCreateDirectory(ESP_WORKUNIT_DIR);
  364. m_sched.start();
  365. }
  366. bool CWsWorkunitsEx::onWUCreate(IEspContext &context, IEspWUCreateRequest &req, IEspWUCreateResponse &resp)
  367. {
  368. try
  369. {
  370. if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
  371. throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
  372. NewWsWorkunit wu(context);
  373. SCMStringBuffer wuid;
  374. resp.updateWorkunit().setWuid(wu->getWuid(wuid).str());
  375. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid.str());
  376. }
  377. catch(IException* e)
  378. {
  379. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  380. }
  381. return true;
  382. }
  383. static bool origValueChanged(const char *newValue, const char *origValue, StringBuffer &s, bool nillable=true)
  384. {
  385. if (!nillable && isEmpty(newValue))
  386. return false;
  387. if(newValue && origValue)
  388. {
  389. if (!streq(origValue, newValue))
  390. {
  391. s.append(newValue).trim();
  392. return true;
  393. }
  394. return false;
  395. }
  396. if (newValue)
  397. {
  398. s.append(newValue).trim();
  399. return true;
  400. }
  401. return (origValue!=NULL);
  402. }
  403. bool CWsWorkunitsEx::onWUUpdate(IEspContext &context, IEspWUUpdateRequest &req, IEspWUUpdateResponse &resp)
  404. {
  405. try
  406. {
  407. ensureWsWorkunitAccess(context, req.getWuid(), SecAccess_Write);
  408. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  409. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  410. if(!cw)
  411. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",req.getWuid());
  412. if(req.getProtected() != req.getProtectedOrig())
  413. {
  414. cw->protect(req.getProtected());
  415. cw.clear();
  416. cw.setown(factory->openWorkUnit(req.getWuid(), false));
  417. if(!cw)
  418. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",req.getWuid());
  419. }
  420. if ((req.getState() == WUStateRunning)||(req.getState() == WUStateDebugPaused)||(req.getState() == WUStateDebugRunning))
  421. {
  422. WsWuInfo winfo(context, cw);
  423. winfo.getInfo(resp.updateWorkunit(), WUINFO_All);
  424. resp.setRedirectUrl(StringBuffer("/WsWorkunits/WUInfo?Wuid=").append(req.getWuid()).str());
  425. AuditSystemAccess(context.queryUserId(), true, "Updated %s", req.getWuid());
  426. return true;
  427. }
  428. WorkunitUpdate wu(&cw->lock());
  429. if(!req.getState_isNull() && (req.getStateOrig_isNull() || req.getState() != req.getStateOrig()))
  430. {
  431. if (!req.getStateOrig_isNull() && cw->getState() != (WUState) req.getStateOrig())
  432. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT, "Cannot update workunit %s because its state has been changed internally. Please refresh the page and try again.", req.getWuid());
  433. WUState state = (WUState) req.getState();
  434. if(state < WUStateSize)
  435. wu->setState(state);
  436. }
  437. StringBuffer s;
  438. if (origValueChanged(req.getJobname(), req.getJobnameOrig(), s))
  439. wu->setJobName(s.trim().str());
  440. if (origValueChanged(req.getDescription(), req.getDescriptionOrig(), s.clear()))
  441. wu->setDebugValue("description", (req.getDescription()) ? s.trim().str() : NULL, true);
  442. double version = context.getClientVersion();
  443. if (version > 1.04)
  444. {
  445. if (origValueChanged(req.getClusterSelection(), req.getClusterOrig(), s.clear(), false))
  446. {
  447. if (req.getState() == WUStateBlocked)
  448. switchWorkUnitQueue(wu.get(), s.str());
  449. else if ((req.getState() != WUStateSubmitted) && (req.getState() != WUStateRunning) && (req.getState() != WUStateDebugPaused) && (req.getState() != WUStateDebugRunning))
  450. wu->setClusterName(s.str());
  451. }
  452. }
  453. const char *xmlParams = req.getXmlParams();
  454. if (notEmpty(xmlParams))
  455. wu->setXmlParams(xmlParams);
  456. if (notEmpty(req.getQueryText()))
  457. {
  458. Owned<IWUQuery> query=wu->updateQuery();
  459. query->setQueryText(req.getQueryText());
  460. }
  461. if (version > 1.34 && notEmpty(req.getQueryMainDefinition()))
  462. {
  463. Owned<IWUQuery> query=wu->updateQuery();
  464. query->setQueryMainDefinition(req.getQueryMainDefinition());
  465. }
  466. if (!req.getResultLimit_isNull())
  467. wu->setResultLimit(req.getResultLimit());
  468. if (!req.getAction_isNull())
  469. {
  470. WUAction action = (WUAction) req.getAction();
  471. if(action < WUActionSize)
  472. wu->setAction(action);
  473. }
  474. if (!req.getPriorityClass_isNull())
  475. {
  476. WUPriorityClass priority = (WUPriorityClass) req.getPriorityClass();
  477. if(priority<PriorityClassSize)
  478. wu->setPriority(priority);
  479. }
  480. if (!req.getPriorityLevel_isNull())
  481. wu->setPriorityLevel(req.getPriorityLevel());
  482. if (origValueChanged(req.getScope(), req.getScopeOrig(), s.clear(), false))
  483. wu->setWuScope(s.str());
  484. ForEachItemIn(di, req.getDebugValues())
  485. {
  486. IConstDebugValue& item = req.getDebugValues().item(di);
  487. if (notEmpty(item.getName()))
  488. wu->setDebugValue(item.getName(), item.getValue(), true);
  489. }
  490. ForEachItemIn(ai, req.getApplicationValues())
  491. {
  492. IConstApplicationValue& item=req.getApplicationValues().item(ai);
  493. if(notEmpty(item.getApplication()) && notEmpty(item.getName()))
  494. wu->setApplicationValue(item.getApplication(), item.getName(), item.getValue(), true);
  495. }
  496. wu->commit();
  497. wu.clear();
  498. WsWuInfo winfo(context, cw);
  499. winfo.getInfo(resp.updateWorkunit(), WUINFO_All);
  500. StringBuffer thorSlaveIP;
  501. if (version > 1.24 && notEmpty(req.getThorSlaveIP()))
  502. thorSlaveIP = req.getThorSlaveIP();
  503. if (thorSlaveIP.length() > 0)
  504. {
  505. StringBuffer url;
  506. url.appendf("/WsWorkunits/WUInfo?Wuid=%s&ThorSlaveIP=%s", req.getWuid(), thorSlaveIP.str());
  507. resp.setRedirectUrl(url.str());
  508. }
  509. else
  510. resp.setRedirectUrl(StringBuffer("/WsWorkunits/WUInfo?Wuid=").append(req.getWuid()).str());
  511. AuditSystemAccess(context.queryUserId(), true, "Updated %s", req.getWuid());
  512. }
  513. catch(IException* e)
  514. {
  515. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  516. }
  517. return true;
  518. }
  519. bool CWsWorkunitsEx::onWUCreateAndUpdate(IEspContext &context, IEspWUUpdateRequest &req, IEspWUUpdateResponse &resp)
  520. {
  521. try
  522. {
  523. if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
  524. throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
  525. NewWsWorkunit wu(context);
  526. SCMStringBuffer wuid;
  527. wu->getWuid(wuid);
  528. req.setWuid(wuid.str());
  529. }
  530. catch(IException* e)
  531. {
  532. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  533. }
  534. return onWUUpdate(context, req, resp);
  535. }
  536. static inline StringBuffer &appendUrlParameter(StringBuffer &url, const char *name, const char *value, bool &first)
  537. {
  538. if (notEmpty(value))
  539. {
  540. url.append(first ? '?' : '&').append(name).append('=').append(value);
  541. first=false;
  542. }
  543. return url;
  544. }
  545. bool CWsWorkunitsEx::onWUAction(IEspContext &context, IEspWUActionRequest &req, IEspWUActionResponse &resp)
  546. {
  547. try
  548. {
  549. StringBuffer sAction(req.getActionType());
  550. if (!sAction.length())
  551. throw MakeStringException(ECLWATCH_INVALID_INPUT,"Action not defined.");
  552. int *action=wuActionTable.getValue(sAction.toLowerCase().str());
  553. if (!action)
  554. throw MakeStringException(ECLWATCH_INVALID_INPUT,"Invalid Action '%s'.", sAction.str());
  555. Owned<IProperties> params = createProperties(true);
  556. params->setProp("BlockTillFinishTimer", req.getBlockTillFinishTimer());
  557. if (*action==ActionProtect)
  558. params->setProp("Protect", streq(sAction.str(), "protect"));
  559. if (*action==ActionChangeState && streq(sAction.str(), "settofailed"))
  560. params->setProp("State",4);
  561. IArrayOf<IConstWUActionResult> results;
  562. if (doAction(context, req.getWuids(), *action, params, &results) && *action!=ActionDelete)
  563. {
  564. StringBuffer redirect;
  565. if(req.getPageFrom() && strieq(req.getPageFrom(), "wuid"))
  566. redirect.append("/WsWorkunits/WUInfo?Wuid=").append(req.getWuids().item(0));
  567. else if (req.getPageFrom() && strieq(req.getPageFrom(), "scheduler"))
  568. {
  569. redirect.set("/WsWorkunits/WUShowScheduled");
  570. bool first=true;
  571. appendUrlParameter(redirect, "Cluster", req.getEventServer(), first);
  572. appendUrlParameter(redirect, "EventName", req.getEventName(), first);
  573. }
  574. else
  575. {
  576. redirect.append("/WsWorkunits/WUQuery");
  577. bool first=true;
  578. appendUrlParameter(redirect, "PageSize", req.getPageSize(), first);
  579. appendUrlParameter(redirect, "PageStartFrom", req.getCurrentPage(), first);
  580. appendUrlParameter(redirect, "Sortby", req.getSortby(), first);
  581. appendUrlParameter(redirect, "Descending", req.getDescending() ? "1" : "0", first);
  582. appendUrlParameter(redirect, "State", req.getState(), first);
  583. appendUrlParameter(redirect, "Cluster", req.getCluster(), first);
  584. appendUrlParameter(redirect, "Owner", req.getOwner(), first);
  585. appendUrlParameter(redirect, "StartDate", req.getStartDate(), first);
  586. appendUrlParameter(redirect, "EndDate", req.getEndDate(), first);
  587. appendUrlParameter(redirect, "ECL", req.getECL(), first);
  588. appendUrlParameter(redirect, "Jobname", req.getJobname(), first);
  589. }
  590. resp.setRedirectUrl(redirect.str());
  591. }
  592. else
  593. resp.setActionResults(results);
  594. }
  595. catch(IException* e)
  596. {
  597. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  598. }
  599. return true;
  600. }
  601. bool CWsWorkunitsEx::onWUDelete(IEspContext &context, IEspWUDeleteRequest &req, IEspWUDeleteResponse &resp)
  602. {
  603. try
  604. {
  605. IArrayOf<IConstWUActionResult> results;
  606. Owned<IProperties> params = createProperties(true);
  607. params->setProp("BlockTillFinishTimer", req.getBlockTillFinishTimer());
  608. if (!doAction(context,req.getWuids(), ActionDelete, params, &results))
  609. resp.setActionResults(results);
  610. }
  611. catch(IException* e)
  612. {
  613. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  614. }
  615. return true;
  616. }
  617. bool CWsWorkunitsEx::onWUAbort(IEspContext &context, IEspWUAbortRequest &req, IEspWUAbortResponse &resp)
  618. {
  619. try
  620. {
  621. IArrayOf<IConstWUActionResult> results;
  622. Owned<IProperties> params = createProperties(true);
  623. params->setProp("BlockTillFinishTimer", req.getBlockTillFinishTimer());
  624. if (!doAction(context,req.getWuids(), ActionAbort, params, &results))
  625. resp.setActionResults(results);
  626. }
  627. catch(IException* e)
  628. {
  629. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  630. }
  631. return true;
  632. }
  633. bool CWsWorkunitsEx::onWUProtect(IEspContext &context, IEspWUProtectRequest &req, IEspWUProtectResponse &resp)\
  634. {
  635. try
  636. {
  637. IArrayOf<IConstWUActionResult> results;
  638. Owned<IProperties> params(createProperties(true));
  639. params->setProp("Protect", req.getProtect());
  640. params->setProp("BlockTillFinishTimer", 0);
  641. if (!doAction(context,req.getWuids(), ActionProtect, params, &results))
  642. resp.setActionResults(results);
  643. }
  644. catch(IException* e)
  645. {
  646. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  647. }
  648. return true;
  649. }
  650. bool CWsWorkunitsEx::onWUResubmit(IEspContext &context, IEspWUResubmitRequest &req, IEspWUResubmitResponse &resp)
  651. {
  652. try
  653. {
  654. Owned<IMultiException> me = MakeMultiException();
  655. SCMStringBuffer wuid;
  656. for(aindex_t i=0; i<req.getWuids().length();i++)
  657. {
  658. wuid.set(req.getWuids().item(i));
  659. ensureWsWorkunitAccess(context, wuid.str(), SecAccess_Write);
  660. try
  661. {
  662. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  663. if(req.getCloneWorkunit() || req.getRecompile())
  664. {
  665. Owned<IConstWorkUnit> src(factory->openWorkUnit(wuid.str(), false));
  666. NewWsWorkunit wu(factory, context);
  667. wu->getWuid(wuid);
  668. queryExtendedWU(wu)->copyWorkUnit(src);
  669. SCMStringBuffer token;
  670. wu->setSecurityToken(createToken(wuid.str(), context.queryUserId(), context.queryPassword(), token).str());
  671. }
  672. Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str(), false));
  673. submitWsWorkunit(context, cw, NULL, NULL, 0, req.getRecompile(), req.getResetWorkflow());
  674. }
  675. catch (IException *E)
  676. {
  677. me->append(*E);
  678. }
  679. catch (...)
  680. {
  681. me->append(*MakeStringException(0,"Unknown exception submitting %s",wuid.str()));
  682. }
  683. }
  684. if(me->ordinality())
  685. throw me.getLink();
  686. int timeToWait = req.getBlockTillFinishTimer();
  687. if (timeToWait != 0)
  688. {
  689. for(aindex_t i=0; i<req.getWuids().length(); i++)
  690. waitForWorkUnitToComplete(req.getWuids().item(i), timeToWait);
  691. }
  692. if(req.getWuids().length()==1)
  693. {
  694. resp.setRedirectUrl(StringBuffer("/WsWorkunits/WUInfo?Wuid=").append(wuid).str());
  695. }
  696. }
  697. catch(IException* e)
  698. {
  699. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  700. }
  701. return true;
  702. }
  703. bool CWsWorkunitsEx::onWUPushEvent(IEspContext &context, IEspWUPushEventRequest &req, IEspWUPushEventResponse &resp)
  704. {
  705. try
  706. {
  707. const char *name = req.getEventName();
  708. const char *text = req.getEventText();
  709. const char *target = NULL;
  710. if (notEmpty(name) && notEmpty(text))
  711. {
  712. Owned<IScheduleEventPusher> pusher(getScheduleEventPusher());
  713. pusher->push(name, text, target);
  714. StringBuffer redirect("/WsWorkunits/WUShowScheduled");
  715. bool first=true;
  716. appendUrlParameter(redirect, "PushEventName", name, first);
  717. appendUrlParameter(redirect, "PushEventText", text, first);
  718. resp.setRedirectUrl(redirect.str());
  719. return true;
  720. }
  721. }
  722. catch(IException* e)
  723. {
  724. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  725. }
  726. return false;
  727. }
  728. bool CWsWorkunitsEx::onWUSchedule(IEspContext &context, IEspWUScheduleRequest &req, IEspWUScheduleResponse &resp)
  729. {
  730. try
  731. {
  732. DBGLOG("Schedule workunit: %s", req.getWuid());
  733. const char* cluster = req.getCluster();
  734. if (isEmpty(cluster))
  735. throw MakeStringException(ECLWATCH_INVALID_INPUT,"No Cluster defined.");
  736. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  737. WorkunitUpdate wu(factory->updateWorkUnit(req.getWuid()));
  738. ensureWsWorkunitAccess(context, *wu.get(), SecAccess_Write);
  739. switch(wu->getState())
  740. {
  741. case WUStateDebugPaused:
  742. case WUStateDebugRunning:
  743. case WUStateRunning:
  744. case WUStateAborting:
  745. case WUStateBlocked:
  746. {
  747. SCMStringBuffer descr;
  748. throw MakeStringException(ECLWATCH_CANNOT_SCHEDULE_WORKUNIT, "Cannot schedule the workunit. Workunit state is '%s'.", wu->getStateDesc(descr).str());
  749. }
  750. }
  751. wu->clearExceptions();
  752. wu->setClusterName(cluster);
  753. if (notEmpty(req.getWhen()))
  754. {
  755. WsWuDateTime dt;
  756. dt.setString(req.getWhen());
  757. wu->setTimeScheduled(dt);
  758. }
  759. if(notEmpty(req.getSnapshot()))
  760. wu->setSnapshot(req.getSnapshot());
  761. wu->setState(WUStateScheduled);
  762. if (req.getMaxRunTime())
  763. wu->setDebugValueInt("maxRunTime", req.getMaxRunTime(), true);
  764. SCMStringBuffer token;
  765. wu->setSecurityToken(createToken(req.getWuid(), context.queryUserId(), context.queryPassword(), token).str());
  766. AuditSystemAccess(context.queryUserId(), true, "Scheduled %s", req.getWuid());
  767. }
  768. catch(IException* e)
  769. {
  770. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  771. }
  772. return true;
  773. }
  774. bool CWsWorkunitsEx::onWUSubmit(IEspContext &context, IEspWUSubmitRequest &req, IEspWUSubmitResponse &resp)
  775. {
  776. try
  777. {
  778. if (isEmpty(req.getWuid()))
  779. throw MakeStringException(ECLWATCH_INVALID_INPUT, "No workunit ID provided.");
  780. DBGLOG("Submit workunit: %s", req.getWuid());
  781. if (isEmpty(req.getCluster()))
  782. throw MakeStringException(ECLWATCH_INVALID_INPUT,"No Cluster defined.");
  783. submitWsWorkunit(context, req.getWuid(), req.getCluster(), req.getSnapshot(), req.getMaxRunTime(), true, false);
  784. if (req.getBlockTillFinishTimer() != 0)
  785. waitForWorkUnitToComplete(req.getWuid(), req.getBlockTillFinishTimer());
  786. resp.setRedirectUrl(StringBuffer("/WsWorkunits/WUInfo?Wuid=").append(req.getWuid()).str());
  787. }
  788. catch(IException* e)
  789. {
  790. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  791. }
  792. return true;
  793. }
  794. bool CWsWorkunitsEx::onWURun(IEspContext &context, IEspWURunRequest &req, IEspWURunResponse &resp)
  795. {
  796. try
  797. {
  798. SCMStringBuffer wuid;
  799. wuid.set(req.getWuid());
  800. bool cloneWorkunit=req.getCloneWorkunit();
  801. if (!wuid.length() && notEmpty(req.getQuerySet()) && notEmpty(req.getQuery()))
  802. {
  803. cloneWorkunit=true;
  804. Owned<IPropertyTree> qstree = getQueryRegistry(req.getQuerySet(), true);
  805. if (qstree)
  806. {
  807. IPropertyTree *query = NULL;
  808. VStringBuffer xpath("Alias[@name=\"%s\"]", req.getQuery());
  809. IPropertyTree *alias = qstree->queryPropTree(xpath.str());
  810. if (alias)
  811. {
  812. const char *quid = alias->queryProp("@id");
  813. if (!quid)
  814. throw MakeStringException(-1, "Alias %s/%s has no Query defined", req.getQuerySet(), req.getQuery());
  815. xpath.clear().appendf("Query[@id='%s']", quid);
  816. query = qstree->queryPropTree(xpath.str());
  817. if (!query)
  818. throw MakeStringException(-1, "Alias %s/%s refers to a non existing query %s", req.getQuerySet(), req.getQuery(), quid);
  819. }
  820. else
  821. {
  822. xpath.clear().appendf("Query[@id=\"%s\"]", req.getQuery());
  823. query = qstree->queryPropTree(xpath.str());
  824. }
  825. if (query)
  826. {
  827. if (query->getPropBool("@suspended"))
  828. throw MakeStringException(-1, "Query %s/%s is currently suspended", req.getQuerySet(), req.getQuery());
  829. wuid.set(query->queryProp("@wuid"));
  830. }
  831. else
  832. throw MakeStringException(-1, "Query %s/%s not found", req.getQuerySet(), req.getQuery());
  833. }
  834. else
  835. throw MakeStringException(-1, "QuerySet %s not found", req.getQuerySet());
  836. }
  837. if (!wuid.length())
  838. throw MakeStringException(ECLWATCH_MISSING_PARAMS,"Workunit or Query required");
  839. ensureWsWorkunitAccess(context, wuid.str(), SecAccess_Write);
  840. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  841. if(cloneWorkunit)
  842. {
  843. Owned<IConstWorkUnit> src(factory->openWorkUnit(wuid.str(), false));
  844. NewWsWorkunit wu(factory, context);
  845. wu->getWuid(wuid);
  846. queryExtendedWU(wu)->copyWorkUnit(src);
  847. SCMStringBuffer token;
  848. wu->setSecurityToken(createToken(wuid.str(), context.queryUserId(), context.queryPassword(), token).str());
  849. }
  850. Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str(), false));
  851. if (!cw)
  852. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.", wuid.str());
  853. if (notEmpty(req.getInput()))
  854. {
  855. Owned<IWuWebView> web = createWuWebView(*cw, NULL, getCFD(), true);
  856. web->addInputsFromXml(req.getInput());
  857. }
  858. submitWsWorkunit(context, cw, req.getCluster(), NULL, 0, false, true);
  859. cw.clear();
  860. int timeToWait = req.getWait();
  861. if (timeToWait != 0)
  862. waitForWorkUnitToComplete(wuid.str(), timeToWait);
  863. cw.set(factory->openWorkUnit(wuid.str(), false));
  864. if (!cw)
  865. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.", wuid.str());
  866. SCMStringBuffer stateDesc;
  867. resp.setState(cw->getStateDesc(stateDesc).str());
  868. resp.setWuid(wuid.str());
  869. if (cw->getState()==WUStateCompleted)
  870. {
  871. SCMStringBuffer result;
  872. getFullWorkUnitResultsXML(context.queryUserId(), context.queryPassword(), cw.get(), result, false, ExceptionSeverityInformation);
  873. resp.setResults(result.str());
  874. }
  875. }
  876. catch(IException* e)
  877. {
  878. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  879. }
  880. return true;
  881. }
  882. bool CWsWorkunitsEx::onWUWaitCompiled(IEspContext &context, IEspWUWaitRequest &req, IEspWUWaitResponse &resp)
  883. {
  884. try
  885. {
  886. secWaitForWorkUnitToCompile(req.getWuid(), *context.querySecManager(), *context.queryUser(), req.getWait());
  887. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  888. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  889. resp.setStateID(cw->getState());
  890. }
  891. catch(IException* e)
  892. {
  893. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  894. }
  895. return true;
  896. }
  897. bool CWsWorkunitsEx::onWUWaitComplete(IEspContext &context, IEspWUWaitRequest &req, IEspWUWaitResponse &resp)
  898. {
  899. try
  900. {
  901. resp.setStateID(secWaitForWorkUnitToComplete(req.getWuid(), *context.querySecManager(), *context.queryUser(), req.getWait(), req.getReturnOnWait()));
  902. }
  903. catch(IException* e)
  904. {
  905. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  906. }
  907. return true;
  908. }
  909. bool CWsWorkunitsEx::onWUCDebug(IEspContext &context, IEspWUDebugRequest &req, IEspWUDebugResponse &resp)
  910. {
  911. try
  912. {
  913. StringBuffer result;
  914. secDebugWorkunit(req.getWuid(), *context.querySecManager(), *context.queryUser(), req.getCommand(), result);
  915. resp.setResult(result);
  916. }
  917. catch(IException* e)
  918. {
  919. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  920. }
  921. return true;
  922. }
  923. bool CWsWorkunitsEx::onWUSyntaxCheckECL(IEspContext &context, IEspWUSyntaxCheckRequest &req, IEspWUSyntaxCheckResponse &resp)
  924. {
  925. try
  926. {
  927. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  928. NewWsWorkunit wu(factory, context);
  929. wu->setAction(WUActionCheck);
  930. if(notEmpty(req.getModuleName()) && notEmpty(req.getAttributeName()))
  931. {
  932. wu->setApplicationValue("SyntaxCheck", "ModuleName", req.getModuleName(), true);
  933. wu->setApplicationValue("SyntaxCheck", "AttributeName", req.getAttributeName(), true);
  934. }
  935. ForEachItemIn(di, req.getDebugValues())
  936. {
  937. IConstDebugValue& item=req.getDebugValues().item(di);
  938. if(notEmpty(item.getName()))
  939. wu->setDebugValue(item.getName(), item.getValue(), true);
  940. }
  941. Owned<IWUQuery> query = wu->updateQuery();
  942. query->setQueryText(req.getECL());
  943. SCMStringBuffer wuid;
  944. wu->getWuid(wuid);
  945. wu->commit();
  946. wu.clear();
  947. submitWsWorkunit(context, wuid.str(), req.getCluster(), req.getSnapshot(), 0, true, false);
  948. waitForWorkUnitToComplete(wuid.str(), req.getTimeToWait());
  949. Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str(), false));
  950. WsWUExceptions errors(*cw);
  951. resp.setErrors(errors);
  952. cw.clear();
  953. factory->deleteWorkUnit(wuid.str());
  954. }
  955. catch(IException* e)
  956. {
  957. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  958. }
  959. return true;
  960. }
  961. bool CWsWorkunitsEx::onWUCompileECL(IEspContext &context, IEspWUCompileECLRequest &req, IEspWUCompileECLResponse &resp)
  962. {
  963. try
  964. {
  965. ensureWsCreateWorkunitAccess(context);
  966. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  967. NewWsWorkunit wu(factory, context);
  968. if(req.getIncludeComplexity())
  969. {
  970. wu->setAction(WUActionCompile);
  971. wu->setDebugValueInt("calculateComplexity",1,true);
  972. }
  973. else
  974. wu->setAction(WUActionCheck);
  975. if(req.getModuleName() && req.getAttributeName())
  976. {
  977. wu->setApplicationValue("SyntaxCheck","ModuleName",req.getModuleName(),true);
  978. wu->setApplicationValue("SyntaxCheck","AttributeName",req.getAttributeName(),true);
  979. }
  980. if(req.getIncludeDependencies())
  981. wu->setApplicationValueInt("SyntaxCheck","IncludeDependencies",1,true);
  982. Owned<IWUQuery> query = wu->updateQuery();
  983. query->setQueryText(req.getECL());
  984. SCMStringBuffer wuid;
  985. wu->getWuid(wuid);
  986. wu.clear();
  987. submitWsWorkunit(context, wuid.str(), req.getCluster(), req.getSnapshot(), 0, true, false);
  988. waitForWorkUnitToComplete(wuid.str(),req.getTimeToWait());
  989. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
  990. SCMStringBuffer s;
  991. cw->getDebugValue("__Calculated__Complexity__",s);
  992. if(s.length())
  993. resp.setComplexity(s.str());
  994. WsWUExceptions errors(*cw);
  995. resp.setErrors(errors);
  996. if(!errors.ErrCount())
  997. {
  998. IArrayOf<IEspWUECLAttribute> dependencies;
  999. for(unsigned count=1;;count++)
  1000. {
  1001. SCMStringBuffer xml;
  1002. cw->getApplicationValue("SyntaxCheck",StringBuffer("Dependency").append(count).str(),xml);
  1003. if(!xml.length())
  1004. break;
  1005. Owned<IPropertyTree> dep=createPTreeFromXMLString(xml.str(), ipt_caseInsensitive);
  1006. if(!dep)
  1007. continue;
  1008. Owned<IEspWUECLAttribute> att = createWUECLAttribute("","");
  1009. att->setModuleName(dep->queryProp("@module"));
  1010. att->setAttributeName(dep->queryProp("@name"));
  1011. int flags = dep->getPropInt("@flags",0);
  1012. if(flags & ob_locked)
  1013. {
  1014. if(flags & ob_lockedself)
  1015. att->setIsCheckedOut(true);
  1016. else
  1017. att->setIsLocked(true);
  1018. }
  1019. if(flags & ob_sandbox)
  1020. att->setIsSandbox(true);
  1021. if(flags & ob_orphaned)
  1022. att->setIsOrphaned(true);
  1023. dependencies.append(*att.getLink());
  1024. }
  1025. resp.setDependencies(dependencies);
  1026. }
  1027. cw.clear();
  1028. factory->deleteWorkUnit(wuid.str());
  1029. }
  1030. catch(IException* e)
  1031. {
  1032. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1033. }
  1034. return true;
  1035. }
  1036. bool CWsWorkunitsEx::onWUGetDependancyTrees(IEspContext& context, IEspWUGetDependancyTreesRequest& req, IEspWUGetDependancyTreesResponse& resp)
  1037. {
  1038. try
  1039. {
  1040. DBGLOG("WUGetDependancyTrees");
  1041. unsigned int timeMilliSec = 500;
  1042. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  1043. NewWsWorkunit wu(factory, context);
  1044. wu->setAction(WUActionCheck);
  1045. if (notEmpty(req.getCluster()))
  1046. wu->setClusterName(req.getCluster());
  1047. if (notEmpty(req.getSnapshot()))
  1048. wu->setSnapshot(req.getSnapshot());
  1049. wu->setDebugValue("gatherDependenciesSelection",notEmpty(req.getItems()) ? req.getItems() : NULL,true);
  1050. if (context.getClientVersion() > 1.12)
  1051. {
  1052. wu->setDebugValueInt("gatherDependencies", 1, true);
  1053. const char *timeout = req.getTimeoutMilliSec();
  1054. if (notEmpty(timeout))
  1055. {
  1056. const char *finger = timeout;
  1057. while (*finger)
  1058. {
  1059. if (!isdigit(*finger++))
  1060. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Incorrect timeout value");
  1061. }
  1062. timeMilliSec = atol(timeout);
  1063. }
  1064. }
  1065. SCMStringBuffer wuid;
  1066. wu->getWuid(wuid);
  1067. wu->commit();
  1068. wu.clear();
  1069. ensureWsWorkunitAccess(context, wuid.str(), SecAccess_Read);
  1070. submitWsWorkunit(context, wuid.str(), req.getCluster(), req.getSnapshot(), 0, true, false);
  1071. int state = waitForWorkUnitToComplete(wuid.str(), timeMilliSec);
  1072. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
  1073. WsWUExceptions errors(*cw);
  1074. resp.setErrors(errors);
  1075. MemoryBuffer temp;
  1076. MemoryBuffer2IDataVal xmlresult(temp);
  1077. Owned<IConstWUResult> result = wu->getResultBySequence(0);
  1078. if (result)
  1079. {
  1080. result->getResultRaw(xmlresult, NULL, NULL);
  1081. resp.setDependancyTrees(temp);
  1082. }
  1083. wu.setown(&cw->lock());
  1084. wu->setState(WUStateAborted);
  1085. wu->commit();
  1086. wu.clear();
  1087. factory->deleteWorkUnit(wuid.str());
  1088. }
  1089. catch(IException* e)
  1090. {
  1091. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1092. }
  1093. return true;
  1094. }
  1095. bool getWsWuInfoFromSasha(IEspContext &context, SocketEndpoint &ep, const char* wuid, IEspECLWorkunit *info)
  1096. {
  1097. Owned<INode> node = createINode(ep);
  1098. Owned<ISashaCommand> cmd = createSashaCommand();
  1099. cmd->addId(wuid);
  1100. cmd->setAction(SCA_GET);
  1101. if (!cmd->send(node, 1*60*1000))
  1102. {
  1103. StringBuffer url;
  1104. DBGLOG("Could not connect to Sasha server at %s", ep.getUrlStr(url).str());
  1105. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_ARCHIVE_SERVER,"Cannot connect to archive server at %s.", url.str());
  1106. }
  1107. if (cmd->numIds()==0)
  1108. {
  1109. DBGLOG("Could not read archived workunit %s",wuid);
  1110. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT,"Cannot read workunit %s.",wuid);
  1111. }
  1112. unsigned num = cmd->numResults();
  1113. if (num < 1)
  1114. return false;
  1115. StringBuffer res;
  1116. cmd->getResult(0, res);
  1117. if(res.length() < 1)
  1118. return false;
  1119. Owned<IPropertyTree> wpt = createPTreeFromXMLString(res.str());
  1120. if (!wpt)
  1121. return false;
  1122. const char * owner = wpt->queryProp("@submitID");
  1123. ensureWsWorkunitAccessByOwnerId(context, owner, SecAccess_Read);
  1124. info->setWuid(wuid);
  1125. info->setArchived(true);
  1126. if (notEmpty(owner))
  1127. info->setOwner(owner);
  1128. const char * state = wpt->queryProp("@state");
  1129. if (notEmpty(state))
  1130. info->setState(state);
  1131. const char * cluster = wpt->queryProp("@clusterName");
  1132. if (notEmpty(cluster))
  1133. info->setCluster(cluster);
  1134. const char * scope = wpt->queryProp("@scope");
  1135. if (notEmpty(scope))
  1136. info->setScope(scope);
  1137. const char * jobName = wpt->queryProp("@jobName");
  1138. if (notEmpty(jobName))
  1139. info->setJobname(jobName);
  1140. const char * description = wpt->queryProp("Debug/description");
  1141. if (notEmpty(description))
  1142. info->setDescription(description);
  1143. const char * queryText = wpt->queryProp("Query/Text");
  1144. if (notEmpty(queryText))
  1145. info->updateQuery().setText(queryText);
  1146. const char * protectedWU = wpt->queryProp("@protected");
  1147. info->setProtected((protectedWU && *protectedWU!='0'));
  1148. return true;
  1149. }
  1150. #define WUDETAILS_REFRESH_MINS 1
  1151. void getArchivedWUInfo(IEspContext &context, IEspWUInfoRequest &req, IEspWUInfoResponse &resp)
  1152. {
  1153. const char *wuid = req.getWuid();
  1154. if (isEmpty(req.getWuid()))
  1155. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Workunit ID not specified.");
  1156. Owned<IEnvironmentFactory> envFactory = getEnvironmentFactory();
  1157. Owned<IConstEnvironment> constEnv = envFactory->openEnvironmentByFile();
  1158. Owned<IPropertyTree> root = &constEnv->getPTree();
  1159. if (!root)
  1160. throw MakeStringExceptionDirect(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment info");
  1161. Owned<IPropertyTreeIterator> instances = root->getElements("Software/SashaServerProcess/Instance");
  1162. ForEach(*instances)
  1163. {
  1164. IPropertyTree &instance = instances->query();
  1165. SocketEndpoint ep(instance.queryProp("@netAddress"), instance.getPropInt("@port", 8877));
  1166. if (getWsWuInfoFromSasha(context, ep, req.getWuid(), &resp.updateWorkunit()))
  1167. {
  1168. resp.setAutoRefresh(WUDETAILS_REFRESH_MINS);
  1169. resp.setCanCompile(false);
  1170. return;
  1171. }
  1172. }
  1173. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT, "Cannot find workunit %s.", wuid);
  1174. return;
  1175. }
  1176. #define WUDETAILS_REFRESH_MINS 1
  1177. bool CWsWorkunitsEx::onWUInfo(IEspContext &context, IEspWUInfoRequest &req, IEspWUInfoResponse &resp)
  1178. {
  1179. try
  1180. {
  1181. if (req.getType() && strieq(req.getType(), "archived workunits"))
  1182. getArchivedWUInfo(context, req, resp);
  1183. else
  1184. {
  1185. try
  1186. {
  1187. unsigned flags=0;
  1188. if (req.getTruncateEclTo64k())
  1189. flags|=WUINFO_TruncateEclTo64k;
  1190. if (req.getIncludeExceptions())
  1191. flags|=WUINFO_IncludeExceptions;
  1192. if (req.getIncludeGraphs())
  1193. flags|=WUINFO_IncludeGraphs;
  1194. if (req.getIncludeSourceFiles())
  1195. flags|=WUINFO_IncludeSourceFiles;
  1196. if (req.getIncludeResults())
  1197. flags|=WUINFO_IncludeResults;
  1198. if (req.getIncludeVariables())
  1199. flags|=WUINFO_IncludeVariables;
  1200. if (req.getIncludeTimers())
  1201. flags|=WUINFO_IncludeTimers;
  1202. if (req.getIncludeDebugValues())
  1203. flags|=WUINFO_IncludeDebugValues;
  1204. if (req.getIncludeApplicationValues())
  1205. flags|=WUINFO_IncludeApplicationValues;
  1206. if (req.getIncludeWorkflows())
  1207. flags|=WUINFO_IncludeWorkflows;
  1208. if (!req.getSuppressResultSchemas())
  1209. flags|=WUINFO_IncludeEclSchemas;
  1210. WsWuInfo winfo(context, req.getWuid());
  1211. winfo.getInfo(resp.updateWorkunit(), flags);
  1212. if (req.getIncludeResultsViewNames())
  1213. {
  1214. StringArray views;
  1215. winfo.getResultViews(views, WUINFO_IncludeResultsViewNames);
  1216. resp.setResultViews(views);
  1217. }
  1218. switch (resp.getWorkunit().getStateID())
  1219. {
  1220. case WUStateCompiling:
  1221. case WUStateCompiled:
  1222. case WUStateScheduled:
  1223. case WUStateSubmitted:
  1224. case WUStateRunning:
  1225. case WUStateAborting:
  1226. case WUStateWait:
  1227. case WUStateUploadingFiles:
  1228. case WUStateDebugPaused:
  1229. case WUStateDebugRunning:
  1230. resp.setAutoRefresh(WUDETAILS_REFRESH_MINS);
  1231. break;
  1232. case WUStateBlocked:
  1233. resp.setAutoRefresh(WUDETAILS_REFRESH_MINS*5);
  1234. break;
  1235. }
  1236. resp.setCanCompile(notEmpty(context.queryUserId()));
  1237. if (context.getClientVersion() > 1.24 && notEmpty(req.getThorSlaveIP()))
  1238. resp.setThorSlaveIP(req.getThorSlaveIP());
  1239. }
  1240. catch (IException *e)
  1241. {
  1242. StringBuffer errMsg;
  1243. if (strnicmp(e->errorMessage(errMsg), "Could not open workunit", 23))
  1244. throw e;
  1245. getArchivedWUInfo(context, req, resp);
  1246. }
  1247. }
  1248. }
  1249. catch(IException* e)
  1250. {
  1251. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1252. }
  1253. return true;
  1254. }
  1255. bool CWsWorkunitsEx::onWUInfoDetails(IEspContext &context, IEspWUInfoRequest &req, IEspWUInfoResponse &resp)
  1256. {
  1257. return onWUInfo(context, req, resp);
  1258. }
  1259. bool CWsWorkunitsEx::onWUResultView(IEspContext &context, IEspWUResultViewRequest &req, IEspWUResultViewResponse &resp)
  1260. {
  1261. ensureWsWorkunitAccess(context, req.getWuid(), SecAccess_Read);
  1262. Owned<IWuWebView> wv = createWuWebView(req.getWuid(), NULL, getCFD(), true);
  1263. StringBuffer html;
  1264. wv->renderSingleResult(req.getViewName(), req.getResultName(), html);
  1265. resp.setResult(html.str());
  1266. resp.setResult_mimetype("text/html");
  1267. return true;
  1268. }
  1269. void doWUQueryBySingleWuid(IEspContext &context, const char *wuid, IEspWUQueryResponse &resp)
  1270. {
  1271. Owned<IEspECLWorkunit> info= createECLWorkunit("","");
  1272. WsWuInfo winfo(context, wuid);
  1273. winfo.getCommon(*info, 0);
  1274. IArrayOf<IEspECLWorkunit> results;
  1275. results.append(*info.getClear());
  1276. resp.setWorkunits(results);
  1277. resp.setPageSize(1);
  1278. resp.setCount(1);
  1279. }
  1280. void doWUQueryByFile(IEspContext &context, const char *logicalFile, IEspWUQueryResponse &resp)
  1281. {
  1282. StringBuffer wuid;
  1283. getWuidFromLogicalFileName(context, logicalFile, wuid);
  1284. if (!wuid.length())
  1285. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT,"Cannot find the workunit for file %s.", logicalFile);
  1286. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  1287. Owned<IConstWorkUnit> cw= factory->openWorkUnit(wuid.str(), false);
  1288. if (!cw)
  1289. throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot find the workunit for file %s.", logicalFile);
  1290. if (getWsWorkunitAccess(context, *cw) < SecAccess_Read)
  1291. throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED,"Cannot access the workunit for file %s.",logicalFile);
  1292. SCMStringBuffer parent;
  1293. if (!cw->getParentWuid(parent).length())
  1294. doWUQueryBySingleWuid(context, wuid.str(), resp);
  1295. resp.setFirst(false);
  1296. resp.setPageSize(1);
  1297. resp.setCount(1);
  1298. }
  1299. void doWUQueryByXPath(IEspContext &context, IEspWUQueryRequest & req, IEspWUQueryResponse & resp)
  1300. {
  1301. IArrayOf<IEspECLWorkunit> results;
  1302. WsWuSearch wlist(context,req.getOwner(),req.getState(),req.getCluster(),req.getStartDate(),req.getEndDate(),req.getECL(),req.getJobname(),req.getApplicationName(),req.getApplicationKey(),req.getApplicationData());
  1303. int count=(int)req.getPageSize();
  1304. if (!count)
  1305. count=100;
  1306. WsWuSearch::iterator begin, end;
  1307. if(notEmpty(req.getAfter()))
  1308. {
  1309. begin=wlist.locate(req.getAfter());
  1310. end=min(begin+count,wlist.end());
  1311. }
  1312. else if (notEmpty(req.getBefore()))
  1313. {
  1314. end=wlist.locate(req.getBefore());
  1315. begin=max(end-count,wlist.begin());
  1316. }
  1317. else
  1318. {
  1319. begin=wlist.begin();
  1320. end=min(begin+count,wlist.end());
  1321. }
  1322. if(begin>wlist.begin() && begin<wlist.end())
  1323. resp.setCurrent(begin->c_str());
  1324. if (context.getClientVersion() > 1.02)
  1325. {
  1326. resp.setPageStartFrom(begin - wlist.begin() + 1);
  1327. resp.setNumWUs((int)wlist.getSize());
  1328. resp.setCount(end - begin);
  1329. }
  1330. if(end<wlist.end())
  1331. resp.setNext(end->c_str());
  1332. for(;begin!=end;begin++)
  1333. {
  1334. Owned<IEspECLWorkunit> info = createECLWorkunit("","");
  1335. WsWuInfo winfo(context, req.getWuid());
  1336. winfo.getCommon(*info, 0);
  1337. results.append(*info);
  1338. }
  1339. resp.setPageSize(abs(count));
  1340. resp.setWorkunits(results);
  1341. return;
  1342. }
  1343. bool addWUQueryFilter(WUSortField *filters, unsigned short &count, MemoryBuffer &buff, const char *name, WUSortField value)
  1344. {
  1345. if (isEmpty(name))
  1346. return false;
  1347. filters[count++] = value;
  1348. buff.append(name);
  1349. return true;
  1350. }
  1351. bool addWUQueryFilterTime(WUSortField *filters, unsigned short &count, MemoryBuffer &buff, const char *stime, WUSortField value)
  1352. {
  1353. if (isEmpty(stime))
  1354. return false;
  1355. CDateTime dt;
  1356. dt.setString(stime, NULL, true);
  1357. unsigned year, month, day, hour, minute, second, nano;
  1358. dt.getDate(year, month, day, true);
  1359. dt.getTime(hour, minute, second, nano, true);
  1360. VStringBuffer wuid("W%4d%02d%02d-%02d%02d%02d",year,month,day,hour,minute,second);
  1361. filters[count++] = value;
  1362. buff.append(wuid.str());
  1363. return true;
  1364. }
  1365. void doWUQueryWithSort(IEspContext &context, IEspWUQueryRequest & req, IEspWUQueryResponse & resp)
  1366. {
  1367. SecAccessFlags accessOwn;
  1368. SecAccessFlags accessOthers;
  1369. getUserWuAccessFlags(context, accessOwn, accessOthers, true);
  1370. double version = context.getClientVersion();
  1371. IArrayOf<IEspECLWorkunit> results;
  1372. int begin = 0;
  1373. unsigned int count = 100;
  1374. int pagesize = 100;
  1375. if (version > 1.01)
  1376. {
  1377. pagesize = (int)req.getPageSize();
  1378. if (!req.getCount_isNull())
  1379. pagesize = req.getCount();
  1380. if(pagesize < 1)
  1381. pagesize = 100;
  1382. begin = (int)req.getPageStartFrom();
  1383. }
  1384. else
  1385. {
  1386. count=(unsigned)req.getCount();
  1387. if(!count)
  1388. count=100;
  1389. if (notEmpty(req.getAfter()))
  1390. begin=atoi(req.getAfter());
  1391. else if (notEmpty(req.getBefore()))
  1392. begin=atoi(req.getBefore())-count;
  1393. if (begin < 0)
  1394. begin = 0;
  1395. pagesize = count;
  1396. }
  1397. WUSortField sortorder[2] = {(WUSortField) (WUSFwuid | WUSFreverse), WUSFterm};
  1398. if(notEmpty(req.getSortby()))
  1399. {
  1400. const char *sortby = req.getSortby();
  1401. if (strieq(sortby, "Owner"))
  1402. sortorder[0] = WUSFuser;
  1403. else if (strieq(sortby, "JobName"))
  1404. sortorder[0] = WUSFjob;
  1405. else if (strieq(sortby, "Cluster"))
  1406. sortorder[0] = WUSFcluster;
  1407. else if (strieq(sortby, "RoxieCluster"))
  1408. sortorder[0] = WUSFroxiecluster;
  1409. else if (strieq(sortby, "Protected"))
  1410. sortorder[0] = WUSFprotected;
  1411. else if (strieq(sortby, "State"))
  1412. sortorder[0] = WUSFstate;
  1413. else if (strieq(sortby, "ThorTime"))
  1414. sortorder[0] = (WUSortField) (WUSFtotalthortime+WUSFnumeric);
  1415. else
  1416. sortorder[0] = WUSFwuid;
  1417. bool descending = req.getDescending();
  1418. if (descending)
  1419. sortorder[0] = (WUSortField) (sortorder[0] | WUSFreverse);
  1420. }
  1421. WUSortField filters[10];
  1422. unsigned short filterCount = 0;
  1423. MemoryBuffer filterbuf;
  1424. bool bDoubleCheckState = false;
  1425. if(req.getState())
  1426. {
  1427. addWUQueryFilter(filters, filterCount, filterbuf, strieq(req.getState(), "unknown") ? "" : req.getState(), WUSFstate);
  1428. if (strieq(req.getState(), "submitted"))
  1429. bDoubleCheckState = true;
  1430. }
  1431. addWUQueryFilter(filters, filterCount, filterbuf, req.getCluster(), WUSFcluster);
  1432. if(version > 1.07)
  1433. addWUQueryFilter(filters, filterCount, filterbuf, req.getRoxieCluster(), WUSFroxiecluster);
  1434. addWUQueryFilter(filters, filterCount, filterbuf, req.getLogicalFile(), WUSFfileread);
  1435. addWUQueryFilter(filters, filterCount, filterbuf, req.getOwner(), (WUSortField) (WUSFuser | WUSFnocase));
  1436. addWUQueryFilter(filters, filterCount, filterbuf, req.getJobname(), (WUSortField) (WUSFjob | WUSFnocase));
  1437. addWUQueryFilterTime(filters, filterCount, filterbuf, req.getStartDate(), WUSFwuid);
  1438. addWUQueryFilterTime(filters, filterCount, filterbuf, req.getEndDate(), WUSFwuidhigh);
  1439. filters[filterCount] = WUSFterm;
  1440. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  1441. unsigned numWUs = factory->numWorkUnitsFiltered(filters, filterbuf.bufferBase());
  1442. Owned<IConstWorkUnitIterator> it = factory->getWorkUnitsSorted(sortorder, filters, filterbuf.bufferBase(), begin, pagesize+1, "", NULL);
  1443. unsigned actualCount = 0;
  1444. ForEach(*it)
  1445. {
  1446. actualCount++;
  1447. IConstWorkUnit& cw = it->query();
  1448. if (chooseWuAccessFlagsByOwnership(context.queryUserId(), cw, accessOwn, accessOthers) < SecAccess_Read)
  1449. continue;
  1450. if (bDoubleCheckState && (cw.getState() != WUStateSubmitted))
  1451. continue;
  1452. SCMStringBuffer parent;
  1453. if (!cw.getParentWuid(parent).length())
  1454. {
  1455. Owned<IEspECLWorkunit> info = createECLWorkunit("","");
  1456. WsWuInfo winfo(context, cw.getWuid(parent).str());
  1457. winfo.getCommon(*info, 0);
  1458. results.append(*info.getClear());
  1459. }
  1460. }
  1461. if (version > 1.02)
  1462. {
  1463. resp.setPageStartFrom(begin+1);
  1464. resp.setNumWUs(numWUs);
  1465. if (results.length() > (aindex_t)pagesize)
  1466. results.pop();
  1467. if(begin + pagesize < numWUs)
  1468. {
  1469. resp.setNextPage(begin + pagesize);
  1470. resp.setPageEndAt(begin + pagesize);
  1471. int last = begin + pagesize;
  1472. while (numWUs > (unsigned) last + pagesize)
  1473. last += pagesize;
  1474. resp.setLastPage(last);
  1475. }
  1476. else
  1477. {
  1478. resp.setNextPage(-1);
  1479. resp.setPageEndAt(numWUs);
  1480. }
  1481. if(begin > 0)
  1482. {
  1483. resp.setFirst(false);
  1484. if (begin - pagesize > 0)
  1485. resp.setPrevPage(begin - pagesize);
  1486. else
  1487. resp.setPrevPage(0);
  1488. }
  1489. resp.setPageSize(pagesize);
  1490. }
  1491. else
  1492. {
  1493. if(begin>0 && actualCount > 0)
  1494. {
  1495. char buf[10];
  1496. itoa(begin, buf, 10);
  1497. resp.setCurrent(buf);
  1498. }
  1499. if(count<actualCount)
  1500. {
  1501. char buf[10];
  1502. itoa(begin+count, buf, 10);
  1503. resp.setNext(buf);
  1504. resp.setNumWUs(numWUs);
  1505. if (results.length() > count)
  1506. results.pop();
  1507. }
  1508. if(begin == 0 && actualCount <= count)
  1509. resp.setFirst(false);
  1510. resp.setCount(count);
  1511. }
  1512. resp.setWorkunits(results);
  1513. return;
  1514. }
  1515. void doWUQueryFromArchive(IEspContext &context, ArchivedWuCache &archivedWuCache, int cacheTime, IEspWUQueryRequest & req, IEspWUQueryResponse & resp)
  1516. {
  1517. SecAccessFlags accessOwn;
  1518. SecAccessFlags accessOthers;
  1519. getUserWuAccessFlags(context, accessOwn, accessOthers, true);
  1520. __int64 pageSize = req.getPageSize();
  1521. if(pageSize < 1)
  1522. pageSize=100;
  1523. __int64 displayStart = req.getPageStartFrom();
  1524. __int64 displayEnd = displayStart + pageSize;
  1525. unsigned dateLimit = 0;
  1526. bool hasNextPage = true;
  1527. SocketEndpoint ep;
  1528. getSashaNode(ep);
  1529. Owned<INode> sashaserver = createINode(ep);
  1530. CDateTime wuTimeFrom, wuTimeTo;
  1531. if(notEmpty(req.getEndDate()))
  1532. wuTimeTo.setString(req.getEndDate(), NULL, true);
  1533. else
  1534. wuTimeTo.setNow();
  1535. if(notEmpty(req.getStartDate()))
  1536. {
  1537. wuTimeFrom.setString(req.getStartDate(), NULL, true);
  1538. dateLimit = 1;
  1539. }
  1540. IArrayOf<IEspECLWorkunit> results;
  1541. StringBuffer filter;
  1542. addToQueryString(filter, "cluster", req.getCluster(), ';');
  1543. addToQueryString(filter, "owner", req.getOwner(), ';');
  1544. addToQueryString(filter, "jobName", req.getJobname(), ';');
  1545. addToQueryString(filter, "state", req.getState(), ';');
  1546. StringBuffer s;
  1547. if (!req.getLastNDays_isNull() && req.getLastNDays()>0)
  1548. addToQueryString(filter, "LastNDays", s.clear().append(req.getLastNDays()).str(), ';');
  1549. else
  1550. {
  1551. addToQueryString(filter, "wuTimeFrom", req.getStartDate(), ';');
  1552. addToQueryString(filter, "wuTimeTo", req.getEndDate(), ';');
  1553. }
  1554. addToQueryString(filter, "displayStart", s.append(displayStart).str(), ';');
  1555. addToQueryString(filter, "pageSize", s.clear().append(pageSize).str(), ';');
  1556. Owned<ArchivedWuCacheElement> found = archivedWuCache.lookup(context, filter, "AddWhenAvailable", cacheTime);
  1557. if (found)
  1558. {
  1559. hasNextPage = found->m_hasNextPage;
  1560. if (found->m_results.length())
  1561. {
  1562. ForEachItemIn(ai, found->m_results)
  1563. {
  1564. Owned<IEspECLWorkunit> info= createECLWorkunit("","");
  1565. info->copy(found->m_results.item(ai));
  1566. results.append(*info.getClear());
  1567. }
  1568. }
  1569. }
  1570. else
  1571. {
  1572. IArrayOf<IEspECLWorkunit> resultList;
  1573. CDateTime timeTo = wuTimeTo;
  1574. __int64 totalWus = 0;
  1575. bool complete = false;
  1576. while (!complete)
  1577. {
  1578. CDateTime timeFrom = timeTo;
  1579. timeFrom.adjustTime(-1439); //one day earlier
  1580. if (dateLimit > 0 && wuTimeFrom > timeFrom)
  1581. timeFrom = wuTimeFrom;
  1582. unsigned year0, month0, day0, hour0, minute0, second0, nano0;
  1583. timeFrom.getDate(year0, month0, day0, true);
  1584. timeFrom.getTime(hour0, minute0, second0, nano0, true);
  1585. VStringBuffer wuFrom("%4d%02d%02d%02d%02d", year0, month0, day0, hour0, minute0);
  1586. unsigned year, month, day, hour, minute, second, nano;
  1587. timeTo.getDate(year, month, day, true);
  1588. timeTo.getTime(hour, minute, second, nano, true);
  1589. VStringBuffer wuTo("%4d%02d%02d%02d%02d", year, month, day, hour, minute);
  1590. __int64 begin = 0;
  1591. unsigned limit = 1000;
  1592. bool continueSashaLoop = true;
  1593. while (continueSashaLoop)
  1594. {
  1595. Owned<ISashaCommand> cmd = createSashaCommand();
  1596. cmd->setAction(SCA_LIST);
  1597. cmd->setOnline(false);
  1598. cmd->setArchived(true);
  1599. cmd->setAfter(wuFrom.str());
  1600. cmd->setBefore(wuTo.str());
  1601. cmd->setStart((unsigned)begin);
  1602. cmd->setLimit(limit);
  1603. if (notEmpty(req.getCluster()))
  1604. cmd->setCluster(req.getCluster());
  1605. if (notEmpty(req.getOwner()))
  1606. cmd->setOwner(req.getOwner());
  1607. if (notEmpty(req.getJobname()))
  1608. cmd->setJobName(req.getJobname());
  1609. if (notEmpty(req.getState()))
  1610. cmd->setState(req.getState());
  1611. cmd->setOutputFormat("owner,jobname,cluster,state");
  1612. if (!cmd->send(sashaserver))
  1613. {
  1614. StringBuffer msg("Cannot connect to archive server at ");
  1615. sashaserver->endpoint().getUrlStr(msg);
  1616. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_ARCHIVE_SERVER, "%s", msg.str());
  1617. }
  1618. unsigned actualCount = cmd->numIds();
  1619. if (actualCount < 1)
  1620. break;
  1621. totalWus += actualCount;
  1622. if (actualCount < limit)
  1623. continueSashaLoop = false;
  1624. for (unsigned ii=0; ii<actualCount; ii++)
  1625. {
  1626. const char *csline = cmd->queryId(ii);
  1627. if (!csline)
  1628. continue;
  1629. StringArray wuidArray;
  1630. CslToStringArray(csline, wuidArray, false);
  1631. if (chooseWuAccessFlagsByOwnership(context.queryUserId(), cmd->queryOwner(), accessOwn, accessOthers) < SecAccess_Read)
  1632. continue;
  1633. const char* wuid = wuidArray.item(0);
  1634. if (isEmpty(wuid))
  1635. continue;
  1636. __int64 addToPos = -1;
  1637. ForEachItemIn(ridx, resultList)
  1638. {
  1639. IEspECLWorkunit& w = resultList.item(ridx);
  1640. if (isEmpty(w.getWuid()))
  1641. continue;
  1642. if (strcmp(wuid, w.getWuid())>0)
  1643. {
  1644. addToPos = ridx;
  1645. break;
  1646. }
  1647. }
  1648. if (addToPos < 0 && (ridx > displayEnd))
  1649. continue;
  1650. Owned<IEspECLWorkunit> info= createECLWorkunit("","");
  1651. info->setWuid(wuid);
  1652. if (notEmpty(wuidArray.item(1)))
  1653. info->setOwner(wuidArray.item(1));
  1654. if (notEmpty(wuidArray.item(2)))
  1655. info->setJobname(wuidArray.item(2));
  1656. if (notEmpty(wuidArray.item(3)))
  1657. info->setCluster(wuidArray.item(3));
  1658. if (notEmpty(wuidArray.item(4)))
  1659. info->setState(wuidArray.item(4));
  1660. if (addToPos < 0)
  1661. resultList.append(*info.getClear());
  1662. else
  1663. resultList.add(*info.getClear(), (aindex_t) addToPos);
  1664. if (resultList.length() > displayEnd)
  1665. resultList.pop();
  1666. }
  1667. begin += limit;
  1668. }
  1669. timeTo.adjustTime(-1440);//one day earlier
  1670. if (dateLimit > 0 && wuTimeFrom > timeTo) //we reach the date limit
  1671. {
  1672. if (totalWus <= displayEnd)
  1673. hasNextPage = false;
  1674. complete = true;
  1675. }
  1676. else if ( resultList.length() >= displayEnd) //we have all we need
  1677. complete = true;
  1678. }
  1679. if (displayEnd > resultList.length())
  1680. displayEnd = resultList.length();
  1681. for (aindex_t i = (aindex_t)displayStart; i < (aindex_t)displayEnd; i++)
  1682. {
  1683. Owned<IEspECLWorkunit> info = createECLWorkunit("","");
  1684. info->copy(resultList.item(i));
  1685. results.append(*info.getClear());
  1686. }
  1687. archivedWuCache.add(filter, "AddWhenAvailable", hasNextPage, results);
  1688. }
  1689. resp.setPageStartFrom(displayStart+1);
  1690. resp.setPageEndAt(displayEnd);
  1691. if(dateLimit < 1 || hasNextPage)
  1692. resp.setNextPage(displayStart + pageSize);
  1693. else
  1694. resp.setNextPage(-1);
  1695. if(displayStart > 0)
  1696. {
  1697. resp.setFirst(false);
  1698. if (displayStart - pageSize > 0)
  1699. resp.setPrevPage(displayStart - pageSize);
  1700. else
  1701. resp.setPrevPage(0);
  1702. }
  1703. resp.setPageSize(pageSize);
  1704. resp.setWorkunits(results);
  1705. resp.setType("archived only");
  1706. return;
  1707. }
  1708. bool CWsWorkunitsEx::onWUQuery(IEspContext &context, IEspWUQueryRequest & req, IEspWUQueryResponse & resp)
  1709. {
  1710. try
  1711. {
  1712. DBGLOG("Started CWsWorkunitsEx::onWUQuery\n");
  1713. if (req.getType() && strieq(req.getType(), "archived workunits"))
  1714. doWUQueryFromArchive(context, *archivedWuCache, awusCacheMinutes, req, resp);
  1715. else if(notEmpty(req.getWuid()))
  1716. doWUQueryBySingleWuid(context, req.getWuid(), resp);
  1717. else if (notEmpty(req.getECL()) || notEmpty(req.getApplicationName()) || notEmpty(req.getApplicationKey()) || notEmpty(req.getApplicationData()))
  1718. doWUQueryByXPath(context, req, resp);
  1719. else if (notEmpty(req.getLogicalFile()) && req.getLogicalFileSearchType() && strieq(req.getLogicalFileSearchType(), "Created"))
  1720. doWUQueryByFile(context, req.getLogicalFile(), resp);
  1721. else
  1722. doWUQueryWithSort(context, req, resp);
  1723. resp.setState(req.getState());
  1724. resp.setCluster(req.getCluster());
  1725. resp.setRoxieCluster(req.getRoxieCluster());
  1726. resp.setOwner(req.getOwner());
  1727. resp.setStartDate(req.getStartDate());
  1728. resp.setEndDate(req.getEndDate());
  1729. double version = context.getClientVersion();
  1730. StringBuffer basicQuery;
  1731. addToQueryString(basicQuery, "State", req.getState());
  1732. addToQueryString(basicQuery, "Cluster", req.getCluster());
  1733. if (version > 1.07)
  1734. addToQueryString(basicQuery, "RoxieCluster", req.getRoxieCluster());
  1735. addToQueryString(basicQuery, "Owner", req.getOwner());
  1736. addToQueryString(basicQuery, "StartDate", req.getStartDate());
  1737. addToQueryString(basicQuery, "EndDate", req.getEndDate());
  1738. if (version > 1.25 && req.getLastNDays() > -1)
  1739. addToQueryString(basicQuery, "LastNDays", StringBuffer().append(req.getLastNDays()).str());
  1740. addToQueryString(basicQuery, "ECL", req.getECL());
  1741. addToQueryString(basicQuery, "Jobname", req.getJobname());
  1742. addToQueryString(basicQuery, "Type", req.getType());
  1743. if (addToQueryString(basicQuery, "LogicalFile", req.getLogicalFile()))
  1744. addToQueryString(basicQuery, "LogicalFileSearchType", req.getLogicalFileSearchType());
  1745. resp.setFilters(basicQuery.str());
  1746. if (notEmpty(req.getSortby()) && !strstr(basicQuery.str(), StringBuffer(req.getSortby()).append('=').str()))
  1747. {
  1748. resp.setSortby(req.getSortby());
  1749. addToQueryString(basicQuery, "Sortby", req.getSortby());
  1750. if (req.getDescending())
  1751. {
  1752. resp.setDescending(req.getDescending());
  1753. addToQueryString(basicQuery, "Descending", "1");
  1754. }
  1755. }
  1756. resp.setBasicQuery(basicQuery.str());
  1757. StringBuffer s;
  1758. if(notEmpty(req.getECL()))
  1759. resp.setECL(Utils::url_encode(req.getECL(), s).str());
  1760. if(notEmpty(req.getJobname()))
  1761. resp.setJobname(Utils::url_encode(req.getJobname(), s.clear()).str());
  1762. }
  1763. catch(IException* e)
  1764. {
  1765. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1766. }
  1767. return true;
  1768. }
  1769. void appendResultSet(MemoryBuffer& mb, INewResultSet* result, const char *name, __int64 start, unsigned& count, __int64& total, bool bin)
  1770. {
  1771. if (!result)
  1772. return;
  1773. const IResultSetMetaData &meta = result->getMetaData();
  1774. Owned<IResultSetCursor> cursor(result->createCursor());
  1775. total=result->getNumRows();
  1776. if(bin)
  1777. count = getResultBin(mb, result, (unsigned)start, count);
  1778. else
  1779. {
  1780. struct MemoryBuffer2IStringVal : public CInterface, implements IStringVal
  1781. {
  1782. MemoryBuffer2IStringVal(MemoryBuffer & _buffer) : buffer(_buffer) {}
  1783. IMPLEMENT_IINTERFACE;
  1784. virtual const char * str() const { UNIMPLEMENTED; }
  1785. virtual void set(const char *val) { buffer.append(strlen(val),val); }
  1786. virtual void clear() { } // support appending only
  1787. virtual void setLen(const char *val, unsigned length) { buffer.append(length, val); }
  1788. virtual unsigned length() const { return buffer.length(); };
  1789. MemoryBuffer & buffer;
  1790. } adaptor(mb);
  1791. count = getResultXml(adaptor, result, name, (unsigned) start, count, "myschema");
  1792. }
  1793. }
  1794. void getWsWuResult(IEspContext &context, const char* wuid, const char *name, const char *logical, unsigned index, __int64 start, unsigned& count, __int64& total, IStringVal& resname, bool bin, MemoryBuffer& mb)
  1795. {
  1796. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  1797. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
  1798. Owned<IConstWUResult> result;
  1799. if (notEmpty(name))
  1800. result.setown(cw->getResultByName(name));
  1801. else if (notEmpty(logical))
  1802. {
  1803. Owned<IConstWUResultIterator> it = &cw->getResults();
  1804. ForEach(*it)
  1805. {
  1806. IConstWUResult &r = it->query();
  1807. SCMStringBuffer filename;
  1808. if(strieq(r.getResultLogicalName(filename).str(), logical))
  1809. {
  1810. result.setown(LINK(&r));
  1811. break;
  1812. }
  1813. }
  1814. }
  1815. else
  1816. result.setown(cw->getResultBySequence(index));
  1817. if (!result)
  1818. throw MakeStringException(ECLWATCH_CANNOT_GET_WU_RESULT,"Cannot open the workunit result.");
  1819. if (!resname.length())
  1820. result->getResultName(resname);
  1821. Owned<IResultSetFactory> resultSetFactory;
  1822. if (context.querySecManager())
  1823. resultSetFactory.setown(getSecResultSetFactory(*context.querySecManager(), *context.queryUser()));
  1824. else
  1825. resultSetFactory.setown(getResultSetFactory(context.queryUserId(), context.queryPassword()));
  1826. SCMStringBuffer logicalName;
  1827. result->getResultLogicalName(logicalName);
  1828. Owned<INewResultSet> rs;
  1829. if (logicalName.length())
  1830. {
  1831. SCMStringBuffer cluster; //MORE is this wrong cluster?
  1832. rs.setown(resultSetFactory->createNewFileResultSet(logicalName.str(), cw->getClusterName(cluster).str()));
  1833. }
  1834. else
  1835. rs.setown(resultSetFactory->createNewResultSet(result, wuid));
  1836. appendResultSet(mb, rs, name, start, count, total, bin);
  1837. }
  1838. void openSaveFile(IEspContext &context, int opt, const char* filename, const char* origMimeType, MemoryBuffer& buf, IEspWULogFileResponse &resp)
  1839. {
  1840. if (opt < 1)
  1841. {
  1842. resp.setThefile(buf);
  1843. resp.setThefile_mimetype(origMimeType);
  1844. }
  1845. else if (opt < 2)
  1846. {
  1847. StringBuffer headerStr("attachment;");
  1848. if (filename && *filename)
  1849. headerStr.appendf("filename=%s", filename);
  1850. MemoryBuffer buf0;
  1851. unsigned i = 0;
  1852. char* p = (char*) buf.toByteArray();
  1853. while (i < buf.length())
  1854. {
  1855. if (p[0] != 10)
  1856. buf0.append(p[0]);
  1857. else
  1858. buf0.append(0x0d);
  1859. p++;
  1860. i++;
  1861. }
  1862. resp.setThefile(buf);
  1863. resp.setThefile_mimetype(origMimeType);
  1864. context.addCustomerHeader("Content-disposition", headerStr.str());
  1865. }
  1866. else
  1867. {
  1868. #ifndef _USE_ZLIB
  1869. throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA,"The data cannot be compressed.");
  1870. #else
  1871. StringBuffer fileNameStr, headerStr("attachment;");
  1872. if (notEmpty(filename))
  1873. {
  1874. fileNameStr.append(filename);
  1875. headerStr.append("filename=").append(filename).append((opt>2) ? ".gz" : ".zip");
  1876. }
  1877. else
  1878. fileNameStr.append("file");
  1879. StringBuffer ifname;
  1880. ifname.appendf("%s%sT%xAT%x", TEMPZIPDIR, PATHSEPSTR, (unsigned)(memsize_t)GetCurrentThreadId(), msTick()).append((opt>2)? "" : ".zip");
  1881. IZZIPor* Zipor = createZZIPor();
  1882. int ret = 0;
  1883. if (opt > 2)
  1884. ret = Zipor->gzipToFile(buf.length(), (void*)buf.toByteArray(), ifname.str());
  1885. else
  1886. ret = Zipor->zipToFile(buf.length(), (void*)buf.toByteArray(), fileNameStr.str(), ifname.str());
  1887. releaseIZ(Zipor);
  1888. if (ret < 0)
  1889. {
  1890. Owned<IFile> rFile = createIFile(ifname.str());
  1891. if (rFile->exists())
  1892. rFile->remove();
  1893. throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA,"The data cannot be compressed.");
  1894. }
  1895. Owned <IFile> rf = createIFile(ifname.str());
  1896. if (!rf->exists())
  1897. throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA,"The data cannot be compressed.");
  1898. MemoryBuffer out;
  1899. Owned <IFileIO> fio = rf->open(IFOread);
  1900. read(fio, 0, (size32_t) rf->size(), out);
  1901. resp.setThefile(out);
  1902. fio.clear();
  1903. rf->remove();
  1904. resp.setThefile_mimetype((opt > 2) ? "application/x-gzip" : "application/zip");
  1905. context.addCustomerHeader("Content-disposition", headerStr.str());
  1906. #endif
  1907. }
  1908. }
  1909. bool CWsWorkunitsEx::onWUFile(IEspContext &context,IEspWULogFileRequest &req, IEspWULogFileResponse &resp)
  1910. {
  1911. try
  1912. {
  1913. DBGLOG("CWsWorkunitsEx::onWUFile WUID=%s",req.getWuid());
  1914. ensureWsWorkunitAccess(context, req.getWuid(), SecAccess_Read);
  1915. int opt = req.getOption();
  1916. if (notEmpty(req.getWuid()))
  1917. {
  1918. MemoryBuffer mb;
  1919. WsWuInfo winfo(context, req.getWuid());
  1920. if (strieq(File_ArchiveQuery, req.getType()))
  1921. {
  1922. winfo.getWorkunitArchiveQuery(mb);
  1923. openSaveFile(context, opt, "ArchiveQuery.xml", HTTP_TYPE_TEXT_XML, mb, resp);
  1924. }
  1925. else if (strieq(File_Cpp,req.getType()) && notEmpty(req.getName()))
  1926. {
  1927. winfo.getWorkunitCpp(req.getName(), req.getDescription(), req.getIPAddress(),mb);
  1928. openSaveFile(context, opt, req.getName(), HTTP_TYPE_TEXT_PLAIN, mb, resp);
  1929. }
  1930. else if (strieq(File_DLL,req.getType()))
  1931. {
  1932. winfo.getWorkunitDll(mb);
  1933. openSaveFile(context, opt, req.getName(), HTTP_TYPE_OCTET_STREAM, mb, resp);
  1934. }
  1935. else if (strieq(File_Res,req.getType()))
  1936. {
  1937. winfo.getWorkunitResTxt(mb);
  1938. openSaveFile(context, opt, "res.txt", HTTP_TYPE_TEXT_PLAIN, mb, resp);
  1939. }
  1940. else if (strncmp(req.getType(), File_ThorLog, 7) == 0)
  1941. {
  1942. winfo.getWorkunitThorLog(mb);
  1943. openSaveFile(context, opt, "thormaster.log", HTTP_TYPE_TEXT_PLAIN, mb, resp);
  1944. }
  1945. else if (strieq(File_ThorSlaveLog,req.getType()))
  1946. {
  1947. winfo.getWorkunitThorSlaveLog(req.getSlaveIP(), mb);
  1948. openSaveFile(context, opt, "ThorSlave.log", HTTP_TYPE_TEXT_PLAIN, mb, resp);
  1949. }
  1950. else if (strieq(File_EclAgentLog,req.getType()))
  1951. {
  1952. winfo.getWorkunitEclAgentLog(mb);
  1953. openSaveFile(context, opt, "eclagent.log", HTTP_TYPE_TEXT_PLAIN, mb, resp);
  1954. }
  1955. else if (strieq(File_XML,req.getType()))
  1956. {
  1957. winfo.getWorkunitXml(req.getPlainText(), mb);
  1958. resp.setThefile(mb);
  1959. const char* plainText = req.getPlainText();
  1960. if (plainText && (!stricmp(plainText, "yes")))
  1961. resp.setThefile_mimetype(HTTP_TYPE_TEXT_PLAIN);
  1962. else
  1963. resp.setThefile_mimetype(HTTP_TYPE_TEXT_XML);
  1964. }
  1965. }
  1966. }
  1967. catch(IException* e)
  1968. {
  1969. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1970. }
  1971. return true;
  1972. }
  1973. bool CWsWorkunitsEx::onWUResultBin(IEspContext &context,IEspWUResultBinRequest &req, IEspWUResultBinResponse &resp)
  1974. {
  1975. try
  1976. {
  1977. ensureWsWorkunitAccess(context, req.getWuid(), SecAccess_Read);
  1978. MemoryBuffer mb;
  1979. __int64 total=0;
  1980. __int64 start = req.getStart() > 0 ? req.getStart() : 0;
  1981. unsigned count = req.getCount(), requested=count;
  1982. SCMStringBuffer name;
  1983. bool bin = (req.getFormat() && strieq(req.getFormat(),"raw"));
  1984. if (notEmpty(req.getWuid()) && notEmpty(req.getResultName()))
  1985. getWsWuResult(context, req.getWuid(), req.getResultName(), NULL, 0, start, count, total, name, bin, mb);
  1986. else if (notEmpty(req.getWuid()) && (req.getSequence() >= 0))
  1987. getWsWuResult(context, req.getWuid(), NULL, NULL, req.getSequence(), start, count, total, name, bin,mb);
  1988. else if (notEmpty(req.getLogicalName()))
  1989. {
  1990. const char* logicalName = req.getLogicalName();
  1991. StringBuffer wuid;
  1992. getWuidFromLogicalFileName(context, logicalName, wuid);
  1993. if (!wuid.length())
  1994. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT,"Cannot find the workunit for file %s.",logicalName);
  1995. getWsWuResult(context, wuid.str(), NULL, logicalName, 0, start, count, total, name, bin, mb);
  1996. }
  1997. else
  1998. throw MakeStringException(ECLWATCH_CANNOT_GET_WU_RESULT,"Cannot open the workunit result.");
  1999. if(stricmp(req.getFormat(),"xls")==0)
  2000. {
  2001. Owned<IProperties> params(createProperties());
  2002. params->setProp("showCount",0);
  2003. StringBuffer xml;
  2004. xml.append("<WUResultExcel><Result>").append(mb.length(), mb.toByteArray()).append("</Result></WUResultExcel>");
  2005. if (xml.length() > MAXXLSTRANSFER)
  2006. throw MakeStringException(ECLWATCH_TOO_BIG_DATA_SET, "The data set is too big to be converted to an Excel file. Please use the gzip link to download a compressed XML data file.");
  2007. StringBuffer xls;
  2008. xsltTransform(xml.str(), StringBuffer(getCFD()).append("./smc_xslt/result.xslt").str(), params, xls);
  2009. MemoryBuffer out;
  2010. out.setBuffer(xls.length(), (void*)xls.str());
  2011. resp.setResult(out);
  2012. resp.setResult_mimetype("application/vnd.ms-excel");
  2013. }
  2014. #ifdef _USE_ZLIB
  2015. else if(strieq(req.getFormat(),"zip") || strieq(req.getFormat(),"gzip"))
  2016. {
  2017. bool gzip = strieq(req.getFormat(),"gzip");
  2018. StringBuffer xml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  2019. xml.append("<Result>").append(mb.length(),mb.toByteArray()).append("</Result>");
  2020. VStringBuffer ifname("%s%sT%xAT%x%s", TEMPZIPDIR, PATHSEPSTR, (unsigned)(memsize_t)GetCurrentThreadId(), msTick(), gzip ? "" : ".zip");
  2021. IZZIPor* Zipor = createZZIPor();
  2022. int ret = 0;
  2023. if (gzip)
  2024. ret = Zipor->gzipToFile(xml.length(), (void*)xml.str(), ifname.str());
  2025. else
  2026. ret = Zipor->zipToFile(xml.length(), (void*)xml.str(), "WUResult.xml", ifname.str());
  2027. releaseIZ(Zipor);
  2028. if (ret < 0)
  2029. {
  2030. Owned<IFile> rFile = createIFile(ifname.str());
  2031. if (rFile->exists())
  2032. rFile->remove();
  2033. throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA, "The data cannot be compressed.");
  2034. }
  2035. MemoryBuffer out;
  2036. Owned <IFile> rf = createIFile(ifname.str());
  2037. if (rf->exists())
  2038. {
  2039. Owned <IFileIO> fio = rf->open(IFOread);
  2040. read(fio, 0, (size32_t) rf->size(), out);
  2041. resp.setResult(out);
  2042. }
  2043. if (gzip)
  2044. {
  2045. resp.setResult_mimetype("application/x-gzip");
  2046. context.addCustomerHeader("Content-disposition", "attachment;filename=WUResult.xml.gz");
  2047. }
  2048. else
  2049. {
  2050. resp.setResult_mimetype("application/zip");
  2051. context.addCustomerHeader("Content-disposition", "attachment;filename=WUResult.xml.zip");
  2052. }
  2053. Owned<IFile> rFile = createIFile(ifname.str());
  2054. if (rFile->exists())
  2055. rFile->remove();
  2056. }
  2057. #endif
  2058. else
  2059. {
  2060. resp.setResult(mb);
  2061. }
  2062. resp.setName(name.str());
  2063. resp.setWuid(req.getWuid());
  2064. resp.setSequence(req.getSequence());
  2065. resp.setStart(start);
  2066. if (requested > total)
  2067. requested = (unsigned)total;
  2068. resp.setRequested(requested);
  2069. resp.setCount(count);
  2070. resp.setTotal(total);
  2071. resp.setFormat(req.getFormat());
  2072. }
  2073. catch(IException* e)
  2074. {
  2075. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2076. }
  2077. return true;
  2078. }
  2079. bool CWsWorkunitsEx::onWUResultSummary(IEspContext &context, IEspWUResultSummaryRequest &req, IEspWUResultSummaryResponse &resp)
  2080. {
  2081. try
  2082. {
  2083. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2084. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  2085. ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
  2086. resp.setWuid(req.getWuid());
  2087. resp.setSequence(req.getSequence());
  2088. IArrayOf<IEspECLResult> results;
  2089. Owned<IConstWUResult> r = cw->getResultBySequence(req.getSequence());
  2090. if (r)
  2091. {
  2092. WsWuInfo winfo(context, cw);
  2093. winfo.getResult(*r, results, 0);
  2094. resp.setFormat(r->getResultFormat());
  2095. resp.setResult(results.item(0));
  2096. }
  2097. }
  2098. catch(IException* e)
  2099. {
  2100. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2101. }
  2102. return true;
  2103. }
  2104. void getFileResults(IEspContext &context, const char* logicalName, const char* cluster,__int64 start, unsigned& count,__int64& total,IStringVal& resname,bool bin, MemoryBuffer& buf)
  2105. {
  2106. Owned<IResultSetFactory> resultSetFactory;
  2107. if (context.querySecManager())
  2108. resultSetFactory.setown(getSecResultSetFactory(*context.querySecManager(), *context.queryUser()));
  2109. else
  2110. resultSetFactory.setown(getResultSetFactory(context.queryUserId(), context.queryPassword()));
  2111. Owned<INewResultSet> result(resultSetFactory->createNewFileResultSet(logicalName, cluster));
  2112. appendResultSet(buf, result, resname.str(), start, count, total, bin);
  2113. }
  2114. void getWorkunitCluster(IEspContext &context, const char* wuid, SCMStringBuffer& cluster, bool checkArchiveWUs)
  2115. {
  2116. if (isEmpty(wuid))
  2117. return;
  2118. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2119. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
  2120. if (cw)
  2121. cw->getClusterName(cluster);
  2122. else if (checkArchiveWUs)
  2123. {
  2124. Owned<IPropertyTree> wuProps;// = getArchivedWorkUnitProperties(wuid);
  2125. if (wuProps)
  2126. cluster.set(wuProps->queryProp("@clusterName"));
  2127. }
  2128. }
  2129. bool CWsWorkunitsEx::onWUResult(IEspContext &context, IEspWUResultRequest &req, IEspWUResultResponse &resp)
  2130. {
  2131. try
  2132. {
  2133. ensureWsWorkunitAccess(context, req.getWuid(), SecAccess_Read);
  2134. MemoryBuffer mb;
  2135. SCMStringBuffer name;
  2136. __int64 total=0;
  2137. __int64 start = req.getStart() > 0 ? req.getStart() : 0;
  2138. unsigned count=req.getCount() ? req.getCount() : 100, requested=count;
  2139. unsigned seq = req.getSequence();
  2140. VStringBuffer filter("start=%"I64F"d;count=%d", start, count);
  2141. addToQueryString(filter, "clusterName", req.getCluster(), ';');
  2142. addToQueryString(filter, "logicalName", req.getLogicalName(), ';');
  2143. addToQueryString(filter, "wuid", req.getWuid(), ';');
  2144. addToQueryString(filter, "resultName", req.getResultName(), ';');
  2145. filter.appendf(";seq=%d;", seq);
  2146. const char* wuid = req.getWuid();
  2147. const char* logicalName = req.getLogicalName();
  2148. const char* clusterName = req.getCluster();
  2149. const char* resultName = req.getResultName();
  2150. Owned<DataCacheElement> data = dataCache->lookup(context, filter, awusCacheMinutes);
  2151. if (data)
  2152. {
  2153. mb.append(data->m_data.c_str());
  2154. name.set(data->m_name.c_str());
  2155. logicalName = data->m_logicalName.c_str();
  2156. wuid = data->m_wuid.c_str();
  2157. resultName = data->m_resultName.c_str();
  2158. seq = data->m_seq;
  2159. start = data->m_start;
  2160. count = data->m_rowcount;
  2161. requested = (unsigned)data->m_requested;
  2162. total = data->m_total;
  2163. if (notEmpty(logicalName))
  2164. resp.setLogicalName(logicalName);
  2165. else
  2166. {
  2167. if (notEmpty(wuid))
  2168. resp.setWuid(wuid);
  2169. resp.setSequence(seq);
  2170. }
  2171. }
  2172. else
  2173. {
  2174. if(logicalName && *logicalName)
  2175. {
  2176. StringBuffer lwuid;
  2177. getWuidFromLogicalFileName(context, logicalName, lwuid);
  2178. SCMStringBuffer cluster;
  2179. if (lwuid.length())
  2180. getWorkunitCluster(context, lwuid.str(), cluster, true);
  2181. if (cluster.length())
  2182. {
  2183. getFileResults(context, logicalName, cluster.str(), start, count, total, name, false, mb);
  2184. resp.setLogicalName(logicalName);
  2185. }
  2186. else if (notEmpty(clusterName))
  2187. {
  2188. getFileResults(context, logicalName, clusterName, start, count, total, name, false, mb);
  2189. resp.setLogicalName(logicalName);
  2190. }
  2191. else
  2192. throw MakeStringException(ECLWATCH_INVALID_INPUT,"Need valid target cluster to browse file %s.",logicalName);
  2193. }
  2194. else if (notEmpty(wuid) && notEmpty(resultName))
  2195. {
  2196. name.set(resultName);
  2197. getWsWuResult(context, wuid, resultName, NULL, 0, start, count, total, name, false, mb);
  2198. resp.setWuid(wuid);
  2199. resp.setSequence(seq);
  2200. }
  2201. else
  2202. {
  2203. getWsWuResult(context, wuid, NULL, NULL, seq, start, count, total, name, false, mb);
  2204. resp.setWuid(wuid);
  2205. resp.setSequence(seq);
  2206. }
  2207. mb.append(0);
  2208. if (requested > total)
  2209. requested = (unsigned)total;
  2210. dataCache->add(filter, mb.toByteArray(), name.str(), logicalName, wuid, resultName, seq, start, count, requested, total);
  2211. }
  2212. resp.setName(name.str());
  2213. resp.setStart(start);
  2214. if (clusterName && *clusterName)
  2215. resp.setCluster(clusterName);
  2216. resp.setRequested(requested);
  2217. resp.setCount(count);
  2218. resp.setTotal(total);
  2219. resp.setResult(mb.toByteArray());
  2220. context.queryXslParameters()->setProp("escapeResults","1");
  2221. }
  2222. catch(IException* e)
  2223. {
  2224. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2225. }
  2226. return true;
  2227. }
  2228. void getScheduledWUs(IEspContext &context, const char *serverName, const char *eventName, IArrayOf<IEspScheduledWU> & results)
  2229. {
  2230. if (notEmpty(serverName))
  2231. {
  2232. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2233. Owned<IScheduleReader> reader = getScheduleReader(serverName, eventName);
  2234. Owned<IScheduleReaderIterator> it(reader->getIterator());
  2235. while(it->isValidEventName())
  2236. {
  2237. StringBuffer ieventName;
  2238. it->getEventName(ieventName);
  2239. while(it->isValidEventText())
  2240. {
  2241. StringBuffer ieventText;
  2242. it->getEventText(ieventText);
  2243. while(it->isValidWuid())
  2244. {
  2245. StringBuffer wuid;
  2246. it->getWuid(wuid);
  2247. if (wuid.length())
  2248. {
  2249. Owned<IEspScheduledWU> scheduledWU = createScheduledWU("");
  2250. scheduledWU->setWuid(wuid.str());
  2251. scheduledWU->setCluster(serverName);
  2252. if (ieventName.length())
  2253. scheduledWU->setEventName(ieventName.str());
  2254. if (ieventText.str())
  2255. scheduledWU->setEventText(ieventText.str());
  2256. try
  2257. {
  2258. SCMStringBuffer s;
  2259. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
  2260. if (cw)
  2261. scheduledWU->setJobName(cw->getJobName(s).str());
  2262. }
  2263. catch (IException *e)
  2264. {
  2265. e->Release();
  2266. }
  2267. results.append(*scheduledWU.getLink());
  2268. }
  2269. it->nextWuid();
  2270. }
  2271. it->nextEventText();
  2272. }
  2273. it->nextEventName();
  2274. }
  2275. }
  2276. return;
  2277. }
  2278. bool CWsWorkunitsEx::onWUShowScheduled(IEspContext &context, IEspWUShowScheduledRequest & req, IEspWUShowScheduledResponse & resp)
  2279. {
  2280. try
  2281. {
  2282. DBGLOG("WUShowScheduled");
  2283. const char *clusterName = req.getCluster();
  2284. const char *eventName = req.getEventName();
  2285. IArrayOf<IEspScheduledWU> results;
  2286. if(notEmpty(req.getPushEventName()))
  2287. resp.setPushEventName(req.getPushEventName());
  2288. if(notEmpty(req.getPushEventText()))
  2289. resp.setPushEventText(req.getPushEventText());
  2290. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  2291. Owned<IConstEnvironment> environment = factory->openEnvironmentByFile();
  2292. Owned<IPropertyTree> root = &environment->getPTree();
  2293. if (!root)
  2294. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment information.");
  2295. unsigned i = 0;
  2296. Owned<IPropertyTreeIterator> ic = root->getElements("Software/Topology/Cluster");
  2297. IArrayOf<IEspServerInfo> servers;
  2298. ForEach(*ic)
  2299. {
  2300. IPropertyTree &cluster = ic->query();
  2301. const char *iclusterName = cluster.queryProp("@name");
  2302. if (isEmpty(iclusterName))
  2303. continue;
  2304. if(isEmpty(clusterName))
  2305. getScheduledWUs(context, iclusterName, eventName, results);
  2306. else if (strieq(clusterName, iclusterName))
  2307. {
  2308. getScheduledWUs(context, clusterName, eventName, results);
  2309. resp.setClusterSelected(i+1);
  2310. }
  2311. Owned<IEspServerInfo> server = createServerInfo("");
  2312. server->setName(iclusterName);
  2313. servers.append(*server.getLink());
  2314. i++;
  2315. }
  2316. if (servers.length())
  2317. resp.setClusters(servers);
  2318. if (results.length())
  2319. resp.setWorkunits(results);
  2320. bool first=false;
  2321. StringBuffer Query("PageFrom=Scheduler");
  2322. appendUrlParameter(Query, "EventName", eventName, first);
  2323. appendUrlParameter(Query, "ECluster", clusterName, first);
  2324. resp.setQuery(Query.str());
  2325. }
  2326. catch(IException* e)
  2327. {
  2328. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2329. }
  2330. return true;
  2331. }
  2332. bool CWsWorkunitsEx::onWUExport(IEspContext &context, IEspWUExportRequest &req, IEspWUExportResponse &resp)
  2333. {
  2334. try
  2335. {
  2336. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2337. WsWuSearch ws(context, req.getOwner(), req.getState(), req.getCluster(), req.getStartDate(), req.getEndDate(), req.getECL(), req.getJobname());
  2338. StringBuffer xml("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Workunits>");
  2339. for(WsWuSearch::iterator it=ws.begin(); it!=ws.end(); it++)
  2340. {
  2341. Owned<IConstWorkUnit> cw = factory->openWorkUnit(it->c_str(), false);
  2342. if (cw)
  2343. exportWorkUnitToXML(cw, xml);
  2344. }
  2345. xml.append("</Workunits>");
  2346. MemoryBuffer mb;
  2347. mb.setBuffer(xml.length(),(void*)xml.str());
  2348. resp.setExportData(mb);
  2349. resp.setExportData_mimetype(HTTP_TYPE_TEXT_XML);
  2350. }
  2351. catch(IException* e)
  2352. {
  2353. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2354. }
  2355. return true;
  2356. }
  2357. bool CWsWorkunitsEx::onWUListLocalFileRequired(IEspContext& context, IEspWUListLocalFileRequiredRequest& req, IEspWUListLocalFileRequiredResponse& resp)
  2358. {
  2359. try
  2360. {
  2361. const char* wuid = req.getWuid();
  2362. if (isEmpty(wuid))
  2363. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Workunit ID not defined.");
  2364. ensureWsWorkunitAccess(context, wuid, SecAccess_Read);
  2365. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2366. Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
  2367. if (!cw)
  2368. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT, "Workunit %s not found.", wuid);
  2369. IArrayOf<IEspLogicalFileUpload> localFiles;
  2370. Owned<IConstLocalFileUploadIterator> it = cw->getLocalFileUploads();
  2371. ForEach(*it)
  2372. {
  2373. Owned<IConstLocalFileUpload> file = it->get();
  2374. if(!file)
  2375. continue;
  2376. Owned<IEspLogicalFileUpload> up = createLogicalFileUpload();
  2377. SCMStringBuffer s;
  2378. up->setType(file->queryType());
  2379. up->setSource(file->getSource(s).str());
  2380. up->setDestination(file->getDestination(s).str());
  2381. up->setEventTag(file->getEventTag(s).str());
  2382. localFiles.append(*up.getLink());
  2383. }
  2384. resp.setLocalFileUploads(localFiles);
  2385. }
  2386. catch(IException* e)
  2387. {
  2388. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2389. }
  2390. return true;
  2391. }
  2392. typedef enum wsEclTypes_
  2393. {
  2394. wsEclTypeUnknown,
  2395. xsdString,
  2396. xsdBoolean,
  2397. xsdDecimal,
  2398. xsdFloat,
  2399. xsdDouble,
  2400. xsdDuration,
  2401. xsdDateTime,
  2402. xsdTime,
  2403. xsdDate,
  2404. xsdYearMonth,
  2405. xsdYear,
  2406. xsdMonthDay,
  2407. xsdDay,
  2408. xsdMonth,
  2409. xsdHexBinary,
  2410. xsdBase64Binary,
  2411. xsdAnyURI,
  2412. xsdQName,
  2413. xsdNOTATION,
  2414. xsdNormalizedString,
  2415. xsdToken,
  2416. xsdLanguage,
  2417. xsdNMTOKEN,
  2418. xsdNMTOKENS,
  2419. xsdName,
  2420. xsdNCName,
  2421. xsdID,
  2422. xsdIDREF,
  2423. xsdIDREFS,
  2424. xsdENTITY,
  2425. xsdENTITIES,
  2426. xsdInteger,
  2427. xsdNonPositiveInteger,
  2428. xsdNegativeInteger,
  2429. xsdLong,
  2430. xsdInt,
  2431. xsdShort,
  2432. xsdByte,
  2433. xsdNonNegativeInteger,
  2434. xsdUnsignedLong,
  2435. xsdUnsignedInt,
  2436. xsdUnsignedShort,
  2437. xsdUnsignedByte,
  2438. xsdPositiveInteger,
  2439. tnsRawDataFile,
  2440. tnsCsvDataFile,
  2441. tnsEspStringArray,
  2442. tnsEspIntArray,
  2443. tnsXmlDataSet,
  2444. maxWsEclType
  2445. } wsEclType;
  2446. bool CWsWorkunitsEx::onWUAddLocalFileToWorkunit(IEspContext& context, IEspWUAddLocalFileToWorkunitRequest& req, IEspWUAddLocalFileToWorkunitResponse& resp)
  2447. {
  2448. try
  2449. {
  2450. const char* wuid = req.getWuid();
  2451. if (isEmpty(wuid))
  2452. {
  2453. resp.setResult("WUID is not defined!");
  2454. return true;
  2455. }
  2456. ensureWsWorkunitAccess(context, wuid, SecAccess_Write);
  2457. resp.setWuid(wuid);
  2458. const char* varname = req.getName();
  2459. if (isEmpty(varname))
  2460. {
  2461. resp.setResult("Name is not defined!");
  2462. return true;
  2463. }
  2464. resp.setName(varname);
  2465. wsEclType type = (wsEclType) req.getType();
  2466. const char *val = req.getVal();
  2467. unsigned len = req.getLength();
  2468. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2469. WorkunitUpdate wu(factory->updateWorkUnit(wuid));
  2470. if (!wu)
  2471. {
  2472. resp.setResult("Workunit not found!");
  2473. return true;
  2474. }
  2475. Owned<IWUResult> wuRslt = wu->updateResultByName(varname);
  2476. if (isEmpty(val))
  2477. val=req.getDefVal();
  2478. if (notEmpty(val))
  2479. {
  2480. switch (type)
  2481. {
  2482. case xsdBoolean:
  2483. wuRslt->setResultBool((strieq(val, "1") || strieq(val, "true") || strieq(val, "on")));
  2484. wuRslt->setResultStatus(ResultStatusSupplied);
  2485. break;
  2486. case xsdDecimal:
  2487. case xsdFloat:
  2488. case xsdDouble:
  2489. wuRslt->setResultReal(atof(val));
  2490. wuRslt->setResultStatus(ResultStatusSupplied);
  2491. break;
  2492. case xsdInteger:
  2493. case xsdNonPositiveInteger:
  2494. case xsdNegativeInteger:
  2495. case xsdLong:
  2496. case xsdInt:
  2497. case xsdShort:
  2498. case xsdByte:
  2499. case xsdNonNegativeInteger:
  2500. case xsdUnsignedLong:
  2501. case xsdUnsignedInt:
  2502. case xsdUnsignedShort:
  2503. case xsdUnsignedByte:
  2504. case xsdPositiveInteger:
  2505. wuRslt->setResultInt(_atoi64(val));
  2506. wuRslt->setResultStatus(ResultStatusSupplied);
  2507. break;
  2508. case tnsEspIntArray:
  2509. case tnsEspStringArray:
  2510. wuRslt->setResultRaw(len, val, ResultFormatXmlSet);
  2511. break;
  2512. case tnsRawDataFile:
  2513. wuRslt->setResultRaw(len, val, ResultFormatRaw);
  2514. break;
  2515. case tnsXmlDataSet:
  2516. wuRslt->setResultRaw(len, val, ResultFormatXml);
  2517. break;
  2518. case tnsCsvDataFile:
  2519. case xsdBase64Binary: //tbd
  2520. case xsdHexBinary:
  2521. break;
  2522. default:
  2523. wuRslt->setResultString(val, len);
  2524. wuRslt->setResultStatus(ResultStatusSupplied);
  2525. break;
  2526. }
  2527. }
  2528. resp.setResult("Result has been set as required!");
  2529. }
  2530. catch(IException* e)
  2531. {
  2532. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2533. }
  2534. return true;
  2535. }
  2536. void getClusterConfig(char const * clusterType, char const * clusterName, char const * processName, StringBuffer& netAddress)
  2537. {
  2538. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  2539. Owned<IConstEnvironment> environment = factory->openEnvironmentByFile();
  2540. Owned<IPropertyTree> pRoot = &environment->getPTree();
  2541. VStringBuffer xpath("Software/%s[@name='%s']", clusterType, clusterName);
  2542. IPropertyTree* pCluster = pRoot->queryPropTree(xpath.str());
  2543. if (!pCluster)
  2544. throw MakeStringException(ECLWATCH_CLUSTER_NOT_IN_ENV_INFO, "'%s %s' is not defined.", clusterType, clusterName);
  2545. const char* port = pCluster->queryProp(xpath.set(processName).append("@port").str());
  2546. const char* computer = pCluster->queryProp(xpath.set(processName).append("@computer").str());
  2547. if (isEmpty(computer))
  2548. throw MakeStringException(ECLWATCH_INVALID_CLUSTER_INFO, "'%s %s: %s' is not defined.", clusterType, clusterName, processName);
  2549. Owned<IConstMachineInfo> pMachine = environment->getMachine(computer);
  2550. if (pMachine)
  2551. {
  2552. StringBufferAdaptor s(netAddress);
  2553. pMachine->getNetAddress(s);
  2554. #ifdef MACHINE_IP
  2555. if (streq(netAddress.str(), "."))
  2556. netAddress = MACHINE_IP;
  2557. #endif
  2558. netAddress.append(':').append(port);
  2559. }
  2560. return;
  2561. }
  2562. bool CWsWorkunitsEx::onWUProcessGraph(IEspContext &context,IEspWUProcessGraphRequest &req, IEspWUProcessGraphResponse &resp)
  2563. {
  2564. try
  2565. {
  2566. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2567. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  2568. ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
  2569. Owned <IConstWUGraph> graph = cw->getGraph(req.getName());
  2570. Owned <IPropertyTree> xgmml = graph->getXGMMLTree(true); // merge in graph progress information
  2571. StringBuffer xml;
  2572. resp.setTheGraph(toXML(xgmml.get(), xml).str());
  2573. }
  2574. catch(IException* e)
  2575. {
  2576. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2577. }
  2578. return true;
  2579. }
  2580. bool isRunning(IConstWorkUnit &cw)
  2581. {
  2582. // MORE - move into workunit interface
  2583. switch (cw.getState())
  2584. {
  2585. case WUStateFailed:
  2586. case WUStateAborted:
  2587. case WUStateCompleted:
  2588. return false;
  2589. default:
  2590. return true;
  2591. }
  2592. }
  2593. bool CWsWorkunitsEx::onWUGetGraph(IEspContext& context, IEspWUGetGraphRequest& req, IEspWUGetGraphResponse& resp)
  2594. {
  2595. try
  2596. {
  2597. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2598. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  2599. ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
  2600. WUGraphIDType id;
  2601. SCMStringBuffer runningGraph;
  2602. bool running= (isRunning(*cw) && cw->getRunningGraph(runningGraph,id));
  2603. IArrayOf<IEspECLGraphEx> graphs;
  2604. Owned<IConstWUGraphIterator> it = &cw->getGraphs(GraphTypeAny);
  2605. ForEach(*it)
  2606. {
  2607. IConstWUGraph &graph = it->query();
  2608. if(!graph.isValid())
  2609. continue;
  2610. SCMStringBuffer name, label, type;
  2611. graph.getName(name);
  2612. graph.getLabel(label);
  2613. graph.getTypeName(type);
  2614. if(isEmpty(req.getGraphName()) || strieq(name.str(), req.getGraphName()))
  2615. {
  2616. Owned<IEspECLGraphEx> g = createECLGraphEx("","");
  2617. g->setName(name.str());
  2618. g->setLabel(label.str());
  2619. g->setType(type.str());
  2620. if(running && streq(name.str(), runningGraph.str()))
  2621. {
  2622. g->setRunning(true);
  2623. g->setRunningId(id);
  2624. }
  2625. Owned<IPropertyTree> xgmml = graph.getXGMMLTree(true);
  2626. // New functionality, if a subgraph id is specified and we only want to load the xgmml for that subgraph
  2627. // then we need to conditionally pull a propertytree from the xgmml graph one and use that for the xgmml.
  2628. StringBuffer xml;
  2629. if (notEmpty(req.getSubGraphId()))
  2630. {
  2631. VStringBuffer xpath("//node[@id='%s']", req.getSubGraphId());
  2632. toXML(xgmml->queryPropTree(xpath.str()), xml);
  2633. }
  2634. else
  2635. toXML(xgmml, xml);
  2636. g->setGraph(xml.str());
  2637. if (context.getClientVersion() > 1.20)
  2638. {
  2639. Owned<IConstWUGraphProgress> progress = cw->getGraphProgress(name.str());
  2640. if (progress)
  2641. {
  2642. WUGraphState graphstate= progress->queryGraphState();
  2643. if (graphstate == WUGraphComplete)
  2644. g->setComplete(true);
  2645. else if (graphstate == WUGraphFailed)
  2646. g->setFailed(true);
  2647. }
  2648. }
  2649. graphs.append(*g.getClear());
  2650. }
  2651. }
  2652. resp.setGraphs(graphs);
  2653. }
  2654. catch(IException* e)
  2655. {
  2656. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2657. }
  2658. return true;
  2659. }
  2660. bool CWsWorkunitsEx::onGVCAjaxGraph(IEspContext &context, IEspGVCAjaxGraphRequest &req, IEspGVCAjaxGraphResponse &resp)
  2661. {
  2662. try
  2663. {
  2664. resp.setName(req.getName());
  2665. resp.setGraphName(req.getGraphName());
  2666. resp.setGraphType("eclwatch");
  2667. double version = context.getClientVersion();
  2668. if (version > 1.19)
  2669. resp.setSubGraphId(req.getSubGraphId());
  2670. if (version > 1.20)
  2671. resp.setSubGraphOnly(req.getSubGraphOnly());
  2672. }
  2673. catch(IException* e)
  2674. {
  2675. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2676. }
  2677. return true;
  2678. }
  2679. bool CWsWorkunitsEx::onWUGraphInfo(IEspContext &context,IEspWUGraphInfoRequest &req, IEspWUGraphInfoResponse &resp)
  2680. {
  2681. try
  2682. {
  2683. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2684. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  2685. if(!cw)
  2686. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",req.getWuid());
  2687. ensureWsWorkunitAccess(context, *cw, SecAccess_Write);
  2688. resp.setWuid(req.getWuid());
  2689. resp.setName(req.getName());
  2690. resp.setRunning(isRunning(*cw));
  2691. if (notEmpty(req.getGID()))
  2692. resp.setGID(req.getGID());
  2693. if(!req.getBatchWU_isNull())
  2694. resp.setBatchWU(req.getBatchWU());
  2695. }
  2696. catch(IException* e)
  2697. {
  2698. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2699. }
  2700. return true;
  2701. }
  2702. bool CWsWorkunitsEx::onWUGVCGraphInfo(IEspContext &context,IEspWUGVCGraphInfoRequest &req, IEspWUGVCGraphInfoResponse &resp)
  2703. {
  2704. try
  2705. {
  2706. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2707. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  2708. if(!cw)
  2709. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",req.getWuid());
  2710. ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
  2711. resp.setWuid(req.getWuid());
  2712. resp.setName(req.getName());
  2713. resp.setRunning(isRunning(*cw));
  2714. if (notEmpty(req.getGID()))
  2715. resp.setGID(req.getGID());
  2716. if(!req.getBatchWU_isNull())
  2717. resp.setBatchWU(req.getBatchWU());
  2718. StringBuffer xml("<Control><Endpoint><Query id=\"Gordon.Extractor.0\">");
  2719. xml.appendf("<Graph id=\"%s\">", req.getName());
  2720. if (context.getClientVersion() > 1.17)
  2721. {
  2722. xml.append("<Subgraph>");
  2723. xml.append(req.getSubgraphId_isNull() ? 0 : req.getSubgraphId());
  2724. xml.append("</Subgraph>");
  2725. }
  2726. xml.append("</Graph></Query></Endpoint></Control>");
  2727. resp.setTheGraph(xml.str());
  2728. }
  2729. catch(IException* e)
  2730. {
  2731. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2732. }
  2733. return true;
  2734. }
  2735. bool CWsWorkunitsEx::onWUGraphTiming(IEspContext &context, IEspWUGraphTimingRequest &req, IEspWUGraphTimingResponse &resp)
  2736. {
  2737. try
  2738. {
  2739. DBGLOG("WUGraphTiming WUID=%s", req.getWuid());
  2740. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2741. Owned<IConstWorkUnit> cw = factory->openWorkUnit(req.getWuid(), false);
  2742. if(!cw)
  2743. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",req.getWuid());
  2744. ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
  2745. resp.updateWorkunit().setWuid(req.getWuid());
  2746. WsWuInfo winfo(context, cw);
  2747. IArrayOf<IConstECLTimingData> timingData;
  2748. winfo.getGraphTimingData(timingData, 0);
  2749. resp.updateWorkunit().setTimingData(timingData);
  2750. }
  2751. catch(IException* e)
  2752. {
  2753. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2754. }
  2755. return true;
  2756. }
  2757. int CWsWorkunitsSoapBindingEx::onGetForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method)
  2758. {
  2759. try
  2760. {
  2761. StringBuffer xml;
  2762. StringBuffer xslt;
  2763. if(strieq(method,"WUQuery") || strieq(method,"WUJobList"))
  2764. {
  2765. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  2766. Owned<IConstEnvironment> environment = factory->openEnvironmentByFile();
  2767. Owned<IPropertyTree> root = &environment->getPTree();
  2768. if (!root)
  2769. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment information.");
  2770. if(strieq(method,"WUQuery"))
  2771. {
  2772. SecAccessFlags accessOwn;
  2773. SecAccessFlags accessOthers;
  2774. getUserWuAccessFlags(context, accessOwn, accessOthers, false);
  2775. xml.append("<WUQuery>");
  2776. if ((accessOwn == SecAccess_None) && (accessOthers == SecAccess_None))
  2777. xml.appendf("<ErrorMessage>Access to workunit is denied.</ErrorMessage>");
  2778. else
  2779. {
  2780. MapStringTo<bool> added;
  2781. Owned<IPropertyTreeIterator> it = root->getElements("Software/Topology/Cluster");
  2782. ForEach(*it)
  2783. {
  2784. const char *name = it->query().queryProp("@name");
  2785. if (notEmpty(name) && !added.getValue(name))
  2786. {
  2787. added.setValue(name, true);
  2788. appendXMLTag(xml, "Cluster", name);
  2789. }
  2790. }
  2791. }
  2792. xml.append("</WUQuery>");
  2793. xslt.append(getCFD()).append("./smc_xslt/wuid_search.xslt");
  2794. }
  2795. else if (strieq(method,"WUJobList"))
  2796. {
  2797. StringBuffer cluster;
  2798. request->getParameter("Cluster", cluster);
  2799. StringBuffer range;
  2800. request->getParameter("Range",range);
  2801. Owned<IConstWUClusterInfo> clusterInfo = getTargetClusterInfo(cluster);
  2802. xml.append("<WUJobList>");
  2803. if (range.length())
  2804. appendXMLTag(xml, "Range", range.str());
  2805. if (clusterInfo)
  2806. {
  2807. const StringArray &thorInstances = clusterInfo->getThorProcesses();
  2808. ForEachItemIn(i, thorInstances)
  2809. {
  2810. xml.append("<Cluster").append('>').append(thorInstances.item(i)).append("</Cluster>");
  2811. }
  2812. }
  2813. xml.append("<TargetCluster>").append(cluster).append("</TargetCluster>");
  2814. xml.append("</WUJobList>");
  2815. xslt.append(getCFD()).append("./smc_xslt/jobs_search.xslt");
  2816. response->addHeader("Expires", "0");
  2817. }
  2818. }
  2819. if (xslt.length() && xml.length())
  2820. {
  2821. StringBuffer html;
  2822. xsltTransform(xml.str(), xslt.str(), NULL, html);
  2823. response->setContent(html.str());
  2824. response->setContentType(HTTP_TYPE_TEXT_HTML_UTF8);
  2825. response->send();
  2826. return 0;
  2827. }
  2828. }
  2829. catch(IException* e)
  2830. {
  2831. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2832. }
  2833. return onGetNotFound(context, request, response, service);
  2834. }
  2835. void deployArchive(IEspContext &context, IEspWUDeployWorkunitRequest & req, IEspWUDeployWorkunitResponse & resp)
  2836. {
  2837. const MemoryBuffer &obj = req.getObject();
  2838. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2839. WorkunitUpdate wu(factory->createWorkUnit(NULL, "ws_workunits", context.queryUserId()));
  2840. SCMStringBuffer wuid;
  2841. wu->getWuid(wuid);
  2842. wu->setAction(WUActionCompile);
  2843. if (notEmpty(req.getName()))
  2844. wu->setJobName(req.getName());
  2845. Owned<IWUQuery> query=wu->updateQuery();
  2846. StringBuffer text(obj.length(), obj.toByteArray());
  2847. query->setQueryText(text.str());
  2848. query.clear();
  2849. wu->commit();
  2850. wu.clear();
  2851. submitWsWorkunit(context, wuid.str(), req.getCluster(), NULL, 0, true, false);
  2852. waitForWorkUnitToCompile(wuid.str(), req.getWait());
  2853. WsWuInfo winfo(context, wuid.str());
  2854. winfo.getCommon(resp.updateWorkunit(), WUINFO_All);
  2855. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid.str());
  2856. }
  2857. StringBuffer &sharedObjectFileName(StringBuffer &filename, const char *name, const char *ext, unsigned copy)
  2858. {
  2859. filename.append(name);
  2860. if (copy)
  2861. filename.append('-').append(copy);
  2862. if (notEmpty(ext))
  2863. filename.append(ext);
  2864. return filename;
  2865. }
  2866. void writeSharedObject(const char *srcpath, const MemoryBuffer &obj, StringBuffer &dllpath, StringBuffer &dllname)
  2867. {
  2868. StringBuffer name, ext;
  2869. splitFilename(srcpath, NULL, NULL, &name, &ext);
  2870. unsigned copy=0;
  2871. dllpath.clear().append(ESP_WORKUNIT_DIR).append(sharedObjectFileName(dllname.clear(), name.str(), ext.str(), copy++));
  2872. while(checkFileExists(dllpath.str()))
  2873. {
  2874. dllpath.clear().append(ESP_WORKUNIT_DIR).append(sharedObjectFileName(dllname.clear(), name.str(), ext.str(), copy++));
  2875. }
  2876. Owned<IFile> f = createIFile(dllpath.str());
  2877. Owned<IFileIO> io = f->open(IFOcreate);
  2878. io->write(0, obj.length(), obj.toByteArray());
  2879. }
  2880. void deploySharedObject(IEspContext &context, IEspWUDeployWorkunitRequest & req, IEspWUDeployWorkunitResponse & resp)
  2881. {
  2882. if (isEmpty(req.getFileName()))
  2883. throw MakeStringException(ECLWATCH_INVALID_INPUT, "File name required when deploying a shared object.");
  2884. if (isEmpty(req.getCluster()))
  2885. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Cluster name required when deploying a shared object.");
  2886. const MemoryBuffer &obj = req.getObject();
  2887. StringBuffer dllpath, dllname;
  2888. writeSharedObject(req.getFileName(), obj, dllpath, dllname);
  2889. Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
  2890. WorkunitUpdate wu(factory->createWorkUnit(NULL, "ws_workunits", context.queryUserId()));
  2891. SCMStringBuffer wuid;
  2892. wu->getWuid(wuid);
  2893. wu->setClusterName(req.getCluster());
  2894. wu->commit();
  2895. StringBuffer wuXML;
  2896. if (getWorkunitXMLFromFile(dllpath.str(), wuXML))
  2897. {
  2898. Owned<ILocalWorkUnit> embeddedWU = createLocalWorkUnit();
  2899. embeddedWU->loadXML(wuXML);
  2900. queryExtendedWU(wu)->copyWorkUnit(embeddedWU);
  2901. //Owned<IWUQuery> query = workunit->updateQuery();
  2902. //query->setQueryText(eclQuery.s.str());
  2903. }
  2904. StringBuffer dllurl;
  2905. createUNCFilename(dllpath.str(), dllurl);
  2906. unsigned crc = crc_file(dllpath.str());
  2907. Owned<IWUQuery> query = wu->updateQuery();
  2908. associateLocalFile(query, FileTypeDll, dllpath, "Workunit DLL", crc);
  2909. queryDllServer().registerDll(dllname.str(), "Workunit DLL", dllurl.str());
  2910. if (notEmpty(req.getName()))
  2911. wu->setJobName(req.getName());
  2912. wu->setState(WUStateCompiled);
  2913. wu->commit();
  2914. wu.clear();
  2915. WsWuInfo winfo(context, wuid.str());
  2916. winfo.getCommon(resp.updateWorkunit(), WUINFO_All);
  2917. AuditSystemAccess(context.queryUserId(), true, "Updated %s", wuid.str());
  2918. }
  2919. bool CWsWorkunitsEx::onWUDeployWorkunit(IEspContext &context, IEspWUDeployWorkunitRequest & req, IEspWUDeployWorkunitResponse & resp)
  2920. {
  2921. const char *type = req.getObjType();
  2922. try
  2923. {
  2924. if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
  2925. throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
  2926. if (strieq(type, "archive"))
  2927. deployArchive(context, req, resp);
  2928. else if (strieq(type, "shared_object"))
  2929. deploySharedObject(context, req, resp);
  2930. else
  2931. throw MakeStringException(ECLWATCH_INVALID_INPUT, "WUDeployWorkunit '%s' unkown object type.", type);
  2932. }
  2933. catch(IException* e)
  2934. {
  2935. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2936. }
  2937. return true;
  2938. }