ws_fsService.cpp 115 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning (disable : 4786)
  14. #pragma warning (disable : 4129)
  15. #include <math.h>
  16. #include "jsocket.hpp"
  17. #include "dasds.hpp"
  18. #include "dadfs.hpp"
  19. #include "dautils.hpp"
  20. #include "daclient.hpp"
  21. #include "wshelpers.hpp"
  22. #include "dfuwu.hpp"
  23. #include "ws_fsService.hpp"
  24. #ifdef _WIN32
  25. #include "windows.h"
  26. #endif
  27. #include "TpWrapper.hpp"
  28. #include "LogicFileWrapper.hpp"
  29. #include "dfuutil.hpp"
  30. #include "portlist.h"
  31. #include "sacmd.hpp"
  32. #include "exception_util.hpp"
  33. #define DFU_WU_URL "DfuWorkunitsAccess"
  34. #define DFU_EX_URL "DfuExceptionsAccess"
  35. #define FILE_SPRAY_URL "FileSprayAccess"
  36. #define FILE_DESPRAY_URL "FileDesprayAccess"
  37. #define WUDETAILS_REFRESH_MINS 1
  38. void SetResp(StringBuffer &resp, IConstDFUWorkUnit * wu, bool array);
  39. int Schedule::run()
  40. {
  41. try
  42. {
  43. while(true)
  44. {
  45. {
  46. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  47. Owned<IConstDFUWorkUnitIterator> itr = factory->getWorkUnitsByState(DFUstate_scheduled);
  48. itr->first();
  49. while(itr->isValid())
  50. {
  51. Owned<IConstDFUWorkUnit> wu = itr->get();
  52. CDateTime dt, now;
  53. now.setNow();
  54. try
  55. {
  56. wu->getTimeScheduled(dt);
  57. if (now.compare(dt) > 0)
  58. {
  59. StringAttr wuid(wu->queryId());
  60. wu.clear();
  61. submitDFUWorkUnit(wuid.get());
  62. }
  63. }
  64. catch(IException *e)
  65. {
  66. StringBuffer msg;
  67. ERRLOG("Exception %d:%s in WsWorkunits Schedule::run", e->errorCode(), e->errorMessage(msg).str());
  68. e->Release();
  69. }
  70. itr->next();
  71. }
  72. }
  73. sleep(60);
  74. }
  75. }
  76. catch(IException *e)
  77. {
  78. StringBuffer msg;
  79. ERRLOG("Exception %d:%s in WS_FS Schedule::run", e->errorCode(), e->errorMessage(msg).str());
  80. e->Release();
  81. }
  82. catch(...)
  83. {
  84. ERRLOG("Unknown exception in WS_FS Schedule::run");
  85. }
  86. return 0;
  87. }
  88. void CFileSprayEx::init(IPropertyTree *cfg, const char *process, const char *service)
  89. {
  90. StringBuffer xpath;
  91. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/QueueLabel", process, service);
  92. cfg->getProp(xpath.str(), m_QueueLabel);
  93. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/MonitorQueueLabel", process, service);
  94. cfg->getProp(xpath.str(), m_MonitorQueueLabel);
  95. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/RootFolder", process, service);
  96. cfg->getProp(xpath.str(), m_RootFolder);
  97. directories.set(cfg->queryPropTree("Software/Directories"));
  98. StringBuffer prop;
  99. prop.appendf("queueLabel=%s", m_QueueLabel.str());
  100. PrintLog(prop.str());
  101. prop.clear();
  102. prop.appendf("monitorQueueLabel=%s", m_MonitorQueueLabel.str());
  103. PrintLog(prop.str());
  104. prop.clear();
  105. prop.appendf("rootFolder=%s", m_RootFolder.str());
  106. PrintLog(prop.str());
  107. if (!daliClientActive())
  108. {
  109. ERRLOG("No Dali Connection Active.");
  110. throw MakeStringException(-1, "No Dali Connection Active. Please Specify a Dali to connect to in you configuration file");
  111. }
  112. m_sched.start();
  113. }
  114. void ParsePath(const char * fullPath, StringBuffer &ip, StringBuffer &filePath, StringBuffer &title)
  115. {
  116. ip.clear();
  117. filePath.clear();
  118. title.clear();
  119. if(fullPath == NULL || *fullPath == '\0')
  120. return;
  121. const char* ptr = fullPath;
  122. if(*ptr == '\\' && *(ptr+1) == '\\')
  123. {
  124. ptr += 2;
  125. while(*ptr != '\0' && *ptr != '\\')
  126. ptr++;
  127. ip.append(ptr - fullPath - 2, fullPath + 2);
  128. }
  129. filePath.append(ptr);
  130. ptr = fullPath + strlen(fullPath) - 1;
  131. while(ptr > fullPath && *ptr != '\\')
  132. ptr--;
  133. title.append(ptr + 1);
  134. }
  135. const char * const NODATETIME="1970-01-01T00:00:00Z";
  136. // Assign from a dfuwu workunit structure to an esp request workunit structure.
  137. static void DeepAssign(IEspContext &context, IConstDFUWorkUnit *src, IEspDFUWorkunit &dest)
  138. {
  139. if(src == NULL)
  140. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "'Source DFU workunit' doesn't exist.");
  141. if(&dest == NULL)
  142. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "'Destination DFU workunit' not valid.");
  143. Owned<IEnvironmentFactory> envFactory = getEnvironmentFactory();
  144. Owned<IConstEnvironment> constEnv = envFactory->openEnvironmentByFile();
  145. Owned<IPropertyTree> root = &constEnv->getPTree();
  146. if (!root)
  147. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment information.");
  148. double version = context.getClientVersion();
  149. StringBuffer tmp, encoded;
  150. dest.setID(src->queryId());
  151. if (src->getClusterName(tmp.clear()).length()!=0)
  152. {
  153. char *clusterName = (char *)tmp.str();
  154. if (clusterName && *clusterName)
  155. {
  156. StringBuffer clusterNameForDisplay(clusterName);
  157. Owned<IPropertyTreeIterator> clusters= root->getElements("Software/Topology/Cluster");
  158. if (clusters->first())
  159. {
  160. do {
  161. IPropertyTree &cluster = clusters->query();
  162. const char* name = cluster.queryProp("@name");
  163. if (!name || !*name)
  164. continue;
  165. Owned<IPropertyTreeIterator> thorClusters= cluster.getElements(eqThorCluster);
  166. Owned<IPropertyTreeIterator> roxieClusters= cluster.getElements(eqRoxieCluster);
  167. if (thorClusters->first() || roxieClusters->first())
  168. {
  169. if (thorClusters->first())
  170. {
  171. IPropertyTree &thorCluster = thorClusters->query();
  172. const char* process = thorCluster.queryProp("@process");
  173. if (process && *process)
  174. {
  175. if (clusterName && !stricmp(clusterName, process))
  176. {
  177. clusterNameForDisplay.clear().append(name);
  178. break;
  179. }
  180. }
  181. }
  182. if (roxieClusters->first())
  183. {
  184. IPropertyTree &roxieCluster = roxieClusters->query();
  185. const char* process = roxieCluster.queryProp("@process");
  186. if (process && *process)
  187. {
  188. if (clusterName && !stricmp(clusterName, name))
  189. {
  190. clusterNameForDisplay.clear().append(name);
  191. break;
  192. }
  193. }
  194. }
  195. }
  196. } while (clusters->next());
  197. }
  198. dest.setClusterName(clusterNameForDisplay.str());
  199. }
  200. }
  201. if ((version > 1.05) && src->getDFUServerName(tmp.clear()).length())
  202. dest.setDFUServerName(tmp.str());
  203. if (src->getJobName(tmp.clear()).length()!=0)
  204. dest.setJobName(tmp.str());
  205. else
  206. dest.setJobName("");
  207. if (src->getQueue(tmp.clear()).length()!=0)
  208. dest.setQueue(tmp.str());
  209. if (src->getUser(tmp.clear()).length()!=0)
  210. dest.setUser(tmp.str());
  211. dest.setIsProtected(src->isProtected());
  212. dest.setCommand(src->getCommand());
  213. IConstDFUprogress *prog = src->queryProgress();
  214. if (prog != NULL)
  215. {
  216. DFUstate state = prog->getState();
  217. dest.setState(state);
  218. StringBuffer statemsg;
  219. encodeDFUstate(state,statemsg);
  220. dest.setStateMessage(statemsg.str());
  221. CDateTime startAt;
  222. CDateTime stoppAt;
  223. prog->getTimeStarted(startAt);
  224. prog->getTimeStopped(stoppAt);
  225. StringBuffer tmpstr;
  226. startAt.getDateString(tmpstr);
  227. tmpstr.append(" ");
  228. startAt.getTimeString(tmpstr);
  229. dest.setTimeStarted(tmpstr.str());
  230. tmpstr.clear();
  231. stoppAt.getDateString(tmpstr);
  232. tmpstr.append(" ");
  233. stoppAt.getTimeString(tmpstr);
  234. dest.setTimeStopped(tmpstr.str());
  235. StringBuffer prgmsg;
  236. prog->formatProgressMessage(prgmsg);
  237. dest.setProgressMessage(prgmsg.str());
  238. prog->formatSummaryMessage(prgmsg.clear());
  239. dest.setSummaryMessage(prgmsg.str());
  240. unsigned secs = prog->getSecsLeft();
  241. if(secs > 0)
  242. dest.setSecsLeft(secs);
  243. dest.setPercentDone(prog->getPercentDone());
  244. }
  245. IConstDFUoptions *options = src->queryOptions();
  246. if(options)
  247. {
  248. dest.setReplicate(options->getReplicate());
  249. dest.setOverwrite(options->getOverwrite());
  250. }
  251. IConstDFUfileSpec * file = src->querySource();
  252. if (file != NULL)
  253. {
  254. //if (file->getTitle(tmp.clear()).length()!=0)
  255. // dest.setSourceTitle(tmp.str());
  256. StringBuffer lfn;
  257. file->getLogicalName(lfn);
  258. if (lfn.length() != 0)
  259. dest.setSourceLogicalName(lfn.str());
  260. else
  261. dest.setSourceFormat(file->getFormat());
  262. if (file->getRawDirectory(tmp.clear()).length()!=0)
  263. dest.setSourceDirectory(tmp.str());
  264. SocketEndpoint srcdali;
  265. StringBuffer srcdaliip;
  266. file->getForeignDali(srcdali);
  267. srcdali.getIpText(srcdaliip);
  268. if(srcdaliip.length() > 0 && strcmp(srcdaliip.str(), "0.0.0.0") != 0)
  269. dest.setSourceDali(srcdaliip.str());
  270. StringBuffer diffkeyname;
  271. file->getDiffKey(diffkeyname);
  272. if(diffkeyname.length() > 0)
  273. dest.setSourceDiffKeyName(diffkeyname.str());
  274. StringBuffer socket, dir, title;
  275. unsigned np = file->getNumParts(0); // should handle multiple clusters?
  276. if (lfn.length() == 0) { // no logical name
  277. if (np == 1)
  278. {
  279. Owned<IFileDescriptor> info;
  280. try
  281. {
  282. info.setown(file->getFileDescriptor());
  283. if(info)
  284. {
  285. Owned<INode> node = info->getNode(0);
  286. if (node)
  287. {
  288. node->endpoint().getIpText(socket);
  289. dest.setSourceIP(socket.str());
  290. }
  291. const char *defaultdir = info->queryDefaultDir();
  292. if (defaultdir&&*defaultdir)
  293. addPathSepChar(dir.append(defaultdir));
  294. file->getRawFileMask(dir);
  295. dest.setSourceFilePath(dir.str());
  296. }
  297. }
  298. catch(IException *e)
  299. {
  300. EXCLOG(e,"DeepAssign getFileDescriptor");
  301. e->Release();
  302. }
  303. }
  304. }
  305. if (np)
  306. dest.setSourceNumParts(np);
  307. unsigned rs = file->getRecordSize();
  308. if (rs)
  309. dest.setSourceRecordSize(rs);
  310. StringBuffer rowtag;
  311. file->getRowTag(rowtag);
  312. if(rowtag.length() > 0)
  313. dest.setRowTag(rowtag.str());
  314. if (version >= 1.04 && (file->getFormat() == DFUff_csv))
  315. {
  316. StringBuffer separate, terminate, quote, escape;
  317. file->getCsvOptions(separate,terminate,quote, escape);
  318. if(separate.length() > 0)
  319. dest.setSourceCsvSeparate(separate.str());
  320. if(terminate.length() > 0)
  321. dest.setSourceCsvTerminate(terminate.str());
  322. if(quote.length() > 0)
  323. dest.setSourceCsvQuote(quote.str());
  324. if((version >= 1.05) && (escape.length() > 0))
  325. dest.setSourceCsvEscape(escape.str());
  326. }
  327. }
  328. file = src->queryDestination();
  329. if (file != NULL)
  330. {
  331. StringBuffer lfn;
  332. file->getLogicalName(lfn);
  333. if (lfn.length() != 0)
  334. dest.setDestLogicalName(lfn.str());
  335. else
  336. dest.setDestFormat(file->getFormat());
  337. if (file->getRawDirectory(tmp.clear()).length()!=0)
  338. dest.setDestDirectory(tmp.str());
  339. if (file->getGroupName(0,tmp.clear()).length()!=0) // should handle multiple clusters?
  340. {
  341. char *clusterName = (char *)tmp.str();
  342. if (clusterName)
  343. dest.setDestGroupName(clusterName);
  344. }
  345. StringBuffer socket, dir, title;
  346. unsigned np = file->getNumParts(0); // should handle multiple clusters?
  347. if (lfn.length() == 0) { // no logical name
  348. if (np == 1)
  349. {
  350. Owned<IFileDescriptor> info;
  351. try
  352. {
  353. info.setown(file->getFileDescriptor());
  354. if(info)
  355. {
  356. Owned<INode> node = info->getNode(0);
  357. if (node)
  358. {
  359. node->endpoint().getIpText(socket);
  360. dest.setDestIP(socket.str());
  361. }
  362. const char *defaultdir = info->queryDefaultDir();
  363. if (defaultdir&&*defaultdir)
  364. addPathSepChar(dir.append(defaultdir));
  365. file->getRawFileMask(dir);
  366. dest.setDestFilePath(dir.str());
  367. }
  368. }
  369. catch(IException *e)
  370. {
  371. EXCLOG(e,"DeepAssign getFileDescriptor dest");
  372. e->Release();
  373. }
  374. }
  375. }
  376. if (np)
  377. dest.setDestNumParts(np);
  378. unsigned rs = file->getRecordSize();
  379. if (rs)
  380. dest.setDestRecordSize(rs);
  381. dest.setCompress(file->isCompressed());
  382. }
  383. // monitor stuff
  384. IConstDFUmonitor *monitor = src->queryMonitor();
  385. if (monitor) {
  386. monitor->getEventName(tmp.clear());
  387. if (tmp.length())
  388. dest.setMonitorEventName(tmp.str());
  389. bool sub = monitor->getSub();
  390. dest.setMonitorSub(sub);
  391. unsigned sl = monitor->getShotLimit();
  392. if (sl)
  393. dest.setMonitorShotLimit(sl);
  394. }
  395. }
  396. bool CFileSprayEx::ParseLogicalPath(const char * pLogicalPath, const char* cluster,
  397. StringBuffer &folder, StringBuffer &title, StringBuffer &defaultFolder, StringBuffer &defaultReplicateFolder)
  398. {
  399. if(!pLogicalPath || !*pLogicalPath)
  400. return false;
  401. folder.clear();
  402. title.clear();
  403. defaultFolder.clear();
  404. defaultReplicateFolder.clear();
  405. DFD_OS os = DFD_OSdefault;
  406. if(cluster != NULL && *cluster != '\0')
  407. {
  408. StringBuffer basedir;
  409. GroupType groupType;
  410. Owned<IGroup> group = queryNamedGroupStore().lookup(cluster, basedir, groupType);
  411. if (group) {
  412. switch (queryOS(group->queryNode(0).endpoint())) {
  413. case MachineOsW2K:
  414. os = DFD_OSwindows; break;
  415. case MachineOsSolaris:
  416. case MachineOsLinux:
  417. os = DFD_OSunix; break;
  418. }
  419. if (directories.get())
  420. {
  421. switch (groupType)
  422. {
  423. case grp_roxie:
  424. getConfigurationDirectory(directories, "data", "roxie", cluster, defaultFolder);
  425. getConfigurationDirectory(directories, "data2", "roxie", cluster, defaultReplicateFolder);
  426. // MORE - should extend to systems with higher redundancy
  427. break;
  428. case grp_hthor:
  429. getConfigurationDirectory(directories, "data", "hthor", cluster, defaultFolder);
  430. break;
  431. case grp_thor:
  432. default:
  433. getConfigurationDirectory(directories, "data", "thor", cluster, defaultFolder);
  434. getConfigurationDirectory(directories, "mirror", "thor", cluster, defaultReplicateFolder);
  435. }
  436. }
  437. }
  438. else
  439. {
  440. // Error here?
  441. }
  442. }
  443. makePhysicalPartName(pLogicalPath,0,0,folder,false,os,defaultFolder.str());
  444. const char *n = pLogicalPath;
  445. const char* p;
  446. do {
  447. p = strstr(n,"::");
  448. if(p)
  449. n = p+2;
  450. } while(p);
  451. title.append(n);
  452. return true;
  453. }
  454. bool CFileSprayEx::ParseLogicalPath(const char * pLogicalPath, StringBuffer &title)
  455. {
  456. if(!pLogicalPath || !*pLogicalPath)
  457. return false;
  458. title.clear();
  459. const char *n = pLogicalPath;
  460. const char* p;
  461. do {
  462. p = strstr(n,"::");
  463. if(p)
  464. n = p+2;
  465. } while(p);
  466. title.append(n);
  467. return true;
  468. }
  469. DFUclusterPartDiskMapping readClusterMappingSettings(const char *cluster, StringBuffer &dir, int& offset)
  470. {
  471. DFUclusterPartDiskMapping mapping = DFUcpdm_c_only;
  472. Owned<IEnvironmentFactory> envFactory = getEnvironmentFactory();
  473. envFactory->validateCache();
  474. StringBuffer dirxpath;
  475. dirxpath.appendf("Software/RoxieCluster[@name=\"%s\"]",cluster);
  476. Owned<IConstEnvironment> constEnv = envFactory->openEnvironmentByFile();
  477. Owned<IPropertyTree> pEnvRoot = &constEnv->getPTree();
  478. Owned<IPropertyTreeIterator> processes = pEnvRoot->getElements(dirxpath);
  479. if (processes->first())
  480. {
  481. IPropertyTree &processe = processes->query();
  482. const char *slaveConfig = processe.queryProp("@slaveConfig");
  483. if (slaveConfig && *slaveConfig)
  484. {
  485. if (!stricmp(slaveConfig, "simple"))
  486. {
  487. mapping = DFUcpdm_c_only;
  488. }
  489. else if (!stricmp(slaveConfig, "overloaded"))
  490. {
  491. mapping = DFUcpdm_c_then_d;
  492. }
  493. else if (!stricmp(slaveConfig, "full_redundancy"))
  494. {
  495. ;
  496. }
  497. else //circular redundancy
  498. {
  499. mapping = DFUcpdm_c_replicated_by_d;
  500. offset = processe.getPropInt("@cyclicOffset");
  501. }
  502. dir = processe.queryProp("@slaveDataDir");
  503. }
  504. else
  505. {
  506. DBGLOG("Failed to get RoxieCluster settings");
  507. throw MakeStringException(ECLWATCH_INVALID_CLUSTER_INFO, "Failed to get RoxieCluster settings. The workunit will not be created.");
  508. }
  509. }
  510. else
  511. {
  512. DBGLOG("Failed to get RoxieCluster settings");
  513. throw MakeStringException(ECLWATCH_INVALID_CLUSTER_INFO, "Failed to get RoxieCluster settings. The workunit will not be created.");
  514. }
  515. return mapping;
  516. }
  517. void getClusterFromLFN(const char* lfn, StringBuffer& cluster, const char* username, const char* passwd)
  518. {
  519. Owned<IUserDescriptor> udesc;
  520. if(username != NULL && *username != '\0')
  521. {
  522. udesc.setown(createUserDescriptor());
  523. udesc->set(username, passwd);
  524. }
  525. LogicFileWrapper lfw;
  526. lfw.FindClusterName(lfn, cluster, udesc);
  527. }
  528. StringBuffer& constructFileMask(const char* filename, StringBuffer& filemask)
  529. {
  530. filemask.clear().append(filename).toLowerCase().append("._$P$_of_$N$");
  531. return filemask;
  532. }
  533. bool CFileSprayEx::onDFUWUSearch(IEspContext &context, IEspDFUWUSearchRequest & req, IEspDFUWUSearchResponse & resp)
  534. {
  535. try
  536. {
  537. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Read, false))
  538. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to DFU workunit is denied.");
  539. StringArray dfuclusters;
  540. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  541. Owned<IConstEnvironment> environment = factory->openEnvironmentByFile();
  542. Owned<IPropertyTree> root = &environment->getPTree();
  543. if (!root)
  544. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment information.");
  545. Owned<IPropertyTreeIterator> clusterIterator = root->getElements("Software/Topology/Cluster");
  546. if (clusterIterator->first())
  547. {
  548. do {
  549. IPropertyTree &cluster = clusterIterator->query();
  550. const char *clusterName = cluster.queryProp("@name");
  551. if (!clusterName || !*clusterName)
  552. continue;
  553. dfuclusters.append(clusterName);
  554. } while (clusterIterator->next());
  555. }
  556. resp.setClusterNames(dfuclusters);
  557. }
  558. catch(IException* e)
  559. {
  560. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  561. }
  562. return true;
  563. }
  564. int readFromCommaSeparatedString(const char *commaSeparatedString, StringBuffer* output)
  565. {
  566. int numOfItems = 0;
  567. if (commaSeparatedString && *commaSeparatedString)
  568. {
  569. char *pStr = (char *) commaSeparatedString;
  570. while (pStr)
  571. {
  572. char item[1024];
  573. bool bFoundComma = false;
  574. int len = strlen(pStr);
  575. for (int i = 0; i < len; i++)
  576. {
  577. char *pStr1 = pStr + i;
  578. if (pStr1[0] != ',')
  579. continue;
  580. strncpy(item, pStr, pStr1 - pStr);
  581. item[pStr1 - pStr] = 0;
  582. bFoundComma = true;
  583. if (i < len - 1)
  584. pStr = pStr1 + 1;
  585. else
  586. pStr = NULL;
  587. break;
  588. }
  589. if (!bFoundComma && len > 0)
  590. {
  591. strcpy(item, pStr);
  592. pStr = NULL;
  593. }
  594. output[numOfItems] = item;
  595. numOfItems++;
  596. }
  597. }
  598. return numOfItems;
  599. }
  600. bool CFileSprayEx::GetArchivedDFUWorkunits(IEspContext &context, IEspGetDFUWorkunits &req, IEspGetDFUWorkunitsResponse &resp)
  601. {
  602. StringBuffer user;
  603. context.getUserID(user);
  604. StringBuffer sashaAddress;
  605. IArrayOf<IConstTpSashaServer> sashaservers;
  606. CTpWrapper dummy;
  607. dummy.getTpSashaServers(sashaservers);
  608. ForEachItemIn(i, sashaservers)
  609. {
  610. IConstTpSashaServer& sashaserver = sashaservers.item(i);
  611. IArrayOf<IConstTpMachine> &sashaservermachine = sashaserver.getTpMachines();
  612. sashaAddress.append(sashaservermachine.item(0).getNetaddress());
  613. }
  614. SocketEndpoint ep;
  615. ep.set(sashaAddress,DEFAULT_SASHA_PORT);
  616. Owned<INode> sashaserver = createINode(ep);
  617. __int64 count=req.getPageSize();
  618. if(count < 1)
  619. count=100;
  620. __int64 begin=req.getPageStartFrom();
  621. if (begin < 0)
  622. begin = 0;
  623. Owned<ISashaCommand> cmd = createSashaCommand();
  624. cmd->setAction(SCA_LIST);
  625. cmd->setOnline(false);
  626. cmd->setArchived(true);
  627. cmd->setDFU(true);
  628. cmd->setLimit((int) count+1);
  629. cmd->setStart((int)begin);
  630. if(req.getCluster() && *req.getCluster())
  631. cmd->setCluster(req.getCluster());
  632. if(req.getOwner() && *req.getOwner())
  633. cmd->setOwner(req.getOwner());
  634. if(req.getJobname() && *req.getJobname())
  635. cmd->setJobName(req.getJobname());
  636. if(req.getStateReq() && *req.getStateReq())
  637. cmd->setState(req.getStateReq());
  638. cmd->setOutputFormat("owner,jobname,cluster,state,command");//date range/owner/jobname/state*/
  639. if (!cmd->send(sashaserver))
  640. {
  641. StringBuffer msg;
  642. msg.appendf("Cannot connect to archive server at %s",sashaAddress.str());
  643. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_ARCHIVE_SERVER, "%s", msg.str());
  644. }
  645. IArrayOf<IEspDFUWorkunit> results;
  646. __int64 actualCount = cmd->numIds();
  647. StringBuffer s;
  648. for (unsigned j=0;j<actualCount;j++)
  649. {
  650. const char *wuidStr = cmd->queryId(j);
  651. if (!wuidStr)
  652. continue;
  653. StringBuffer strArray[6];
  654. readFromCommaSeparatedString(wuidStr, strArray);
  655. //skip any workunits without access
  656. Owned<IEspDFUWorkunit> resultWU = createDFUWorkunit("", "");
  657. resultWU->setArchived(true);
  658. if (strArray[0].length() > 0)
  659. resultWU->setID(strArray[0].str());
  660. if (strArray[1].length() > 0)
  661. resultWU->setUser(strArray[1].str());
  662. if (strArray[2].length() > 0)
  663. resultWU->setJobName(strArray[2].str());
  664. if (strArray[3].length() > 0)
  665. resultWU->setClusterName(strArray[3].str());
  666. if (strArray[4].length() > 0)
  667. resultWU->setStateMessage(strArray[4].str());
  668. if (strArray[5].length() > 0)
  669. resultWU->setCommand(atoi(strArray[5].str()));
  670. results.append(*resultWU.getLink());
  671. }
  672. resp.setPageStartFrom(begin+1);
  673. resp.setNextPage(-1);
  674. if(count < actualCount)
  675. {
  676. if (results.length() > count)
  677. {
  678. results.pop();
  679. }
  680. resp.setNextPage(begin + count);
  681. resp.setPageEndAt(begin + count);
  682. }
  683. else
  684. {
  685. resp.setPageEndAt(begin + actualCount);
  686. }
  687. if(begin > 0)
  688. {
  689. resp.setFirst(false);
  690. if (begin - count > 0)
  691. resp.setPrevPage(begin - count);
  692. else
  693. resp.setPrevPage(0);
  694. }
  695. resp.setPageSize(count);
  696. resp.setResults(results);
  697. StringBuffer basicQuery;
  698. if (req.getStateReq() && *req.getStateReq())
  699. {
  700. resp.setStateReq(req.getStateReq());
  701. addToQueryString(basicQuery, "StateReq", req.getStateReq());
  702. }
  703. if (req.getCluster() && *req.getCluster())
  704. {
  705. resp.setCluster(req.getCluster());
  706. addToQueryString(basicQuery, "Cluster", req.getCluster());
  707. }
  708. if (req.getOwner() && *req.getOwner())
  709. {
  710. resp.setOwner(req.getOwner());
  711. addToQueryString(basicQuery, "Owner", req.getOwner());
  712. }
  713. if (req.getType() && *req.getType())
  714. {
  715. resp.setType(req.getType());
  716. addToQueryString(basicQuery, "Type", req.getType());
  717. }
  718. resp.setFilters(basicQuery.str());
  719. resp.setBasicQuery(basicQuery.str());
  720. return true;
  721. }
  722. bool CFileSprayEx::onGetDFUWorkunits(IEspContext &context, IEspGetDFUWorkunits &req, IEspGetDFUWorkunitsResponse &resp)
  723. {
  724. try
  725. {
  726. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Read, false))
  727. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to DFU workunit is denied.");
  728. double version = context.getClientVersion();
  729. if (version > 1.02)
  730. {
  731. const char *type = req.getType();
  732. if (type && *type && !stricmp(type, "archived workunits"))
  733. {
  734. return GetArchivedDFUWorkunits(context, req, resp);
  735. }
  736. }
  737. StringBuffer clusterReq;
  738. const char *clusterName = req.getCluster();
  739. if(clusterName && *clusterName)
  740. {
  741. clusterReq.append(clusterName);
  742. }
  743. Owned<IEnvironmentFactory> envFactory = getEnvironmentFactory();
  744. Owned<IConstEnvironment> constEnv = envFactory->openEnvironmentByFile();
  745. Owned<IPropertyTree> root = &constEnv->getPTree();
  746. if (!root)
  747. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment information.");
  748. StringArray targetClusters, clusterProcesses;
  749. Owned<IPropertyTreeIterator> clusters= root->getElements("Software/Topology/Cluster");
  750. if (clusters->first())
  751. {
  752. do {
  753. IPropertyTree &cluster = clusters->query();
  754. const char* name = cluster.queryProp("@name");
  755. if (!name || !*name)
  756. continue;
  757. Owned<IPropertyTreeIterator> thorClusters= cluster.getElements(eqThorCluster);
  758. Owned<IPropertyTreeIterator> roxieClusters= cluster.getElements(eqRoxieCluster);
  759. if (thorClusters->first() || roxieClusters->first())
  760. {
  761. bool bFound = false;
  762. if (thorClusters->first())
  763. {
  764. IPropertyTree &thorCluster = thorClusters->query();
  765. const char* process = thorCluster.queryProp("@process");
  766. if (process && *process)
  767. {
  768. targetClusters.append(name);
  769. clusterProcesses.append(process);
  770. if (clusterName && !stricmp(clusterName, name))
  771. {
  772. clusterReq.clear().append(process);
  773. }
  774. }
  775. }
  776. if (!bFound && roxieClusters->first())
  777. {
  778. IPropertyTree &roxieCluster = roxieClusters->query();
  779. const char* process = roxieCluster.queryProp("@process");
  780. if (process && *process)
  781. {
  782. targetClusters.append(name);
  783. clusterProcesses.append(process);
  784. if (clusterName && !stricmp(clusterName, name))
  785. {
  786. clusterReq.clear().append(process);
  787. }
  788. }
  789. }
  790. }
  791. } while (clusters->next());
  792. }
  793. __int64 pagesize = req.getPageSize();
  794. __int64 pagefrom = req.getPageStartFrom();
  795. __int64 displayFrom = 0;
  796. if (pagesize < 1)
  797. {
  798. pagesize = 100;
  799. }
  800. if (pagefrom > 0)
  801. {
  802. displayFrom = pagefrom;
  803. }
  804. DFUsortfield sortorder[2] = {DFUsf_wuid, DFUsf_term};
  805. sortorder[0] = (DFUsortfield) (DFUsf_wuid + DFUsf_reverse);
  806. if(req.getSortby() && *req.getSortby())
  807. {
  808. const char *sortby = req.getSortby();
  809. if (!stricmp(sortby, "Owner"))
  810. sortorder[0] = DFUsf_user;
  811. else if (!stricmp(sortby, "JobName"))
  812. sortorder[0] = DFUsf_job;
  813. else if (!stricmp(sortby, "Cluster"))
  814. sortorder[0] = DFUsf_cluster;
  815. else if (!stricmp(sortby, "State"))
  816. sortorder[0] = DFUsf_state;
  817. else if (!stricmp(sortby, "Type"))
  818. sortorder[0] = DFUsf_command;
  819. else if (!stricmp(sortby, "Protected"))
  820. sortorder[0] = DFUsf_protected;
  821. else if (!stricmp(sortby, "PCTDone"))
  822. sortorder[0] = (DFUsortfield) (DFUsf_pcdone | DFUsf_numeric);
  823. else
  824. sortorder[0] = DFUsf_wuid;
  825. bool descending = req.getDescending();
  826. if (descending)
  827. sortorder[0] = (DFUsortfield) (sortorder[0] | DFUsf_reverse);
  828. }
  829. DFUsortfield filters[10];
  830. unsigned short filterCount = 0;
  831. MemoryBuffer filterbuf;
  832. if(req.getStateReq() && *req.getStateReq())
  833. {
  834. filters[filterCount] = DFUsf_state;
  835. filterCount++;
  836. if (stricmp(req.getStateReq(), "unknown") != 0)
  837. filterbuf.append(req.getStateReq());
  838. else
  839. filterbuf.append("");
  840. }
  841. if(clusterName && *clusterName)
  842. {
  843. filters[filterCount] = DFUsf_cluster;
  844. filterCount++;
  845. filterbuf.append(clusterReq.str());
  846. }
  847. if(req.getOwner() && *req.getOwner())
  848. {
  849. filters[filterCount] = DFUsortfield (DFUsf_user | DFUsf_nocase);
  850. filterCount++;
  851. filterbuf.append(req.getOwner());
  852. }
  853. if(req.getJobname() && *req.getJobname())
  854. {
  855. filters[filterCount] = DFUsortfield (DFUsf_job | DFUsf_nocase);
  856. filterCount++;
  857. filterbuf.append(req.getJobname());
  858. }
  859. filters[filterCount] = DFUsf_term;
  860. __int64 cacheHint = req.getCacheHint();
  861. if (cacheHint < 0) //Not set yet
  862. cacheHint = 0;
  863. IArrayOf<IEspDFUWorkunit> result;
  864. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  865. unsigned numWUs;
  866. Owned<IConstDFUWorkUnitIterator> itr = factory->getWorkUnitsSorted(sortorder, filters, filterbuf.bufferBase(), (int) displayFrom, (int) pagesize+1, req.getOwner(), &cacheHint, &numWUs);
  867. if (version >= 1.07)
  868. resp.setCacheHint(cacheHint);
  869. //unsigned actualCount = 0;
  870. itr->first();
  871. while(itr->isValid())
  872. {
  873. Owned<IConstDFUWorkUnit> wu = itr->get();
  874. //actualCount++;
  875. Owned<IEspDFUWorkunit> resultWU = createDFUWorkunit("", "");
  876. resultWU->setID(wu->queryId());
  877. StringBuffer jobname, user, cluster;
  878. resultWU->setJobName(wu->getJobName(jobname).str());
  879. resultWU->setCommand(wu->getCommand());
  880. resultWU->setUser(wu->getUser(user).str());
  881. const char* clusterName = wu->getClusterName(cluster).str();
  882. if (clusterName)
  883. {
  884. StringBuffer clusterForDisplay(clusterName);
  885. if (clusterProcesses.ordinality())
  886. {
  887. for (unsigned i = 0; i < clusterProcesses.length(); i++)
  888. {
  889. const char* clusterProcessName = clusterProcesses.item(i);
  890. if (!stricmp(clusterProcessName, clusterName))
  891. {
  892. clusterForDisplay.clear().append(targetClusters.item(i));
  893. break;
  894. }
  895. }
  896. }
  897. resultWU->setClusterName(clusterForDisplay.str());
  898. }
  899. resultWU->setIsProtected(wu->isProtected());
  900. IConstDFUprogress *prog = wu->queryProgress();
  901. if (prog != NULL)
  902. {
  903. DFUstate state = prog->getState();
  904. resultWU->setState(state);
  905. StringBuffer statemsg;
  906. encodeDFUstate(state,statemsg);
  907. resultWU->setStateMessage(statemsg.str());
  908. resultWU->setPercentDone(prog->getPercentDone());
  909. }
  910. result.append(*resultWU.getLink());
  911. itr->next();
  912. }
  913. if (result.length() > pagesize)
  914. result.pop();
  915. resp.setPageSize(pagesize);
  916. resp.setNumWUs(numWUs);
  917. resp.setPageStartFrom(displayFrom + 1);
  918. if(displayFrom + pagesize < numWUs)
  919. {
  920. resp.setNextPage(displayFrom + pagesize);
  921. resp.setPageEndAt(pagefrom + pagesize);
  922. __int64 last = displayFrom + pagesize;
  923. while (last + pagesize < numWUs)
  924. {
  925. last += pagesize;
  926. }
  927. resp.setLastPage(last);
  928. }
  929. else
  930. {
  931. resp.setNextPage(-1);
  932. resp.setPageEndAt(numWUs);
  933. }
  934. if(displayFrom > 0)
  935. {
  936. resp.setFirst(false);
  937. if (displayFrom - pagesize > 0)
  938. resp.setPrevPage(displayFrom - pagesize);
  939. else
  940. resp.setPrevPage(0);
  941. }
  942. StringBuffer basicQuery;
  943. if (req.getStateReq() && *req.getStateReq())
  944. {
  945. resp.setStateReq(req.getStateReq());
  946. addToQueryString(basicQuery, "StateReq", req.getStateReq());
  947. }
  948. if (req.getCluster() && *req.getCluster())
  949. {
  950. resp.setCluster(req.getCluster());
  951. addToQueryString(basicQuery, "Cluster", req.getCluster());
  952. }
  953. if (req.getOwner() && *req.getOwner())
  954. {
  955. resp.setOwner(req.getOwner());
  956. addToQueryString(basicQuery, "Owner", req.getOwner());
  957. }
  958. resp.setFilters(basicQuery.str());
  959. if (req.getSortby() && *req.getSortby())
  960. {
  961. resp.setSortby(req.getSortby());
  962. if (req.getDescending())
  963. resp.setDescending(req.getDescending());
  964. StringBuffer strbuf = req.getSortby();
  965. strbuf.append("=");
  966. String str1(strbuf.str());
  967. String str(basicQuery.str());
  968. if (str.indexOf(str1) < 0)
  969. {
  970. addToQueryString(basicQuery, "Sortby", req.getSortby());
  971. if (req.getDescending())
  972. addToQueryString(basicQuery, "Descending", "1");
  973. }
  974. }
  975. resp.setBasicQuery(basicQuery.str());
  976. resp.setResults(result);
  977. }
  978. catch(IException* e)
  979. {
  980. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  981. }
  982. return true;
  983. }
  984. void CFileSprayEx::addToQueryString(StringBuffer &queryString, const char *name, const char *value)
  985. {
  986. if (queryString.length() > 0)
  987. {
  988. queryString.append("&amp;");
  989. }
  990. queryString.append(name);
  991. queryString.append("=");
  992. queryString.append(value);
  993. }
  994. void CFileSprayEx::getInfoFromSasha(IEspContext &context, const char *sashaServer, const char* wuid, IEspDFUWorkunit *info)
  995. {
  996. Owned<ISashaCommand> cmd = createSashaCommand();
  997. cmd->addId(wuid);
  998. cmd->setAction(SCA_GET);
  999. cmd->setArchived(true);
  1000. cmd->setDFU(true);
  1001. SocketEndpoint ep(sashaServer, DEFAULT_SASHA_PORT);
  1002. Owned<INode> node = createINode(ep);
  1003. if (!cmd->send(node,1*60*1000))
  1004. {
  1005. DBGLOG("Cannot connect to Sasha server at %s",sashaServer);
  1006. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_ARCHIVE_SERVER,"Cannot connect to archive server at %s.",sashaServer);
  1007. }
  1008. if (cmd->numIds()==0)
  1009. {
  1010. DBGLOG("Could not read archived %s",wuid);
  1011. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT,"Cannot read workunit %s.",wuid);
  1012. }
  1013. unsigned num = cmd->numResults();
  1014. if (num < 1)
  1015. return;
  1016. StringBuffer res;
  1017. cmd->getResult(0,res);
  1018. if(res.length() < 1)
  1019. return;
  1020. Owned<IPropertyTree> wu = createPTreeFromXMLString(res.str());
  1021. if (!wu)
  1022. return;
  1023. const char * command = wu->queryProp("@command");
  1024. const char * submitID = wu->queryProp("@submitID");
  1025. const char * cluster = wu->queryProp("@clusterName");
  1026. const char * queue = wu->queryProp("@queue");
  1027. const char * jobName = wu->queryProp("@jobName");
  1028. const char * protectedWU = wu->queryProp("@protected");
  1029. info->setID(wuid);
  1030. info->setArchived(true);
  1031. if (command && *command)
  1032. info->setCommandMessage(command);
  1033. if (cluster && *cluster)
  1034. info->setClusterName(cluster);
  1035. if (submitID && *submitID)
  1036. info->setUser(submitID);
  1037. if (queue && *queue)
  1038. info->setQueue(queue);
  1039. if (jobName && *jobName)
  1040. info->setJobName(jobName);
  1041. if (protectedWU && stricmp(protectedWU, "0"))
  1042. info->setIsProtected(true);
  1043. else
  1044. info->setIsProtected(false);
  1045. IPropertyTree *source = wu->queryPropTree("Source");
  1046. if(source)
  1047. {
  1048. const char * directory = source->queryProp("@directory");
  1049. const char * name = source->queryProp("@name");
  1050. if (directory && *directory)
  1051. info->setSourceDirectory(directory);
  1052. if (name && *name)
  1053. info->setSourceLogicalName(name);
  1054. }
  1055. IPropertyTree *dest = wu->queryPropTree("Destination");
  1056. if(dest)
  1057. {
  1058. const char * directory = dest->queryProp("@directory");
  1059. int numParts = dest->getPropInt("@numparts", -1);
  1060. if (directory && *directory)
  1061. info->setDestDirectory(directory);
  1062. if (numParts > 0)
  1063. info->setDestNumParts(numParts);
  1064. }
  1065. IPropertyTree *progress = wu->queryPropTree("Progress");
  1066. if(progress)
  1067. {
  1068. const char * state = progress->queryProp("@state");
  1069. const char * timeStarted = progress->queryProp("@timestarted");
  1070. const char * timeStopped = progress->queryProp("@timestopped");
  1071. if (state && *state)
  1072. info->setStateMessage(state);
  1073. if (timeStarted && *timeStarted)
  1074. {
  1075. StringBuffer startStr = timeStarted;
  1076. startStr.replace('T', ' ');
  1077. info->setTimeStarted(startStr.str());
  1078. }
  1079. if (timeStopped && *timeStopped)
  1080. {
  1081. StringBuffer stopStr = timeStopped;
  1082. stopStr.replace('T', ' ');
  1083. info->setTimeStopped(stopStr.str());
  1084. }
  1085. }
  1086. return;
  1087. }
  1088. bool CFileSprayEx::getArchivedWUInfo(IEspContext &context, IEspGetDFUWorkunit &req, IEspGetDFUWorkunitResponse &resp)
  1089. {
  1090. const char *wuid = req.getWuid();
  1091. if (wuid && *wuid)
  1092. {
  1093. StringBuffer sashaAddress;
  1094. IArrayOf<IConstTpSashaServer> sashaservers;
  1095. CTpWrapper dummy;
  1096. dummy.getTpSashaServers(sashaservers);
  1097. ForEachItemIn(i, sashaservers)
  1098. {
  1099. IConstTpSashaServer& sashaserver = sashaservers.item(i);
  1100. IArrayOf<IConstTpMachine> &sashaservermachine = sashaserver.getTpMachines();
  1101. sashaAddress.append(sashaservermachine.item(0).getNetaddress());
  1102. }
  1103. if (sashaAddress.length() < 1)
  1104. {
  1105. throw MakeStringException(ECLWATCH_ARCHIVE_SERVER_NOT_FOUND,"Archive server not found.");
  1106. }
  1107. getInfoFromSasha(context, sashaAddress.str(), wuid, &resp.updateResult());
  1108. resp.setAutoRefresh(WUDETAILS_REFRESH_MINS);
  1109. return true;
  1110. }
  1111. return false;
  1112. }
  1113. bool CFileSprayEx::onGetDFUWorkunit(IEspContext &context, IEspGetDFUWorkunit &req, IEspGetDFUWorkunitResponse &resp)
  1114. {
  1115. try
  1116. {
  1117. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Read, false))
  1118. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to DFU workunit is denied.");
  1119. const char* wuid = req.getWuid();
  1120. if (!wuid || !*wuid)
  1121. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Dfu workunit ID not specified.");
  1122. bool found = false;
  1123. double version = context.getClientVersion();
  1124. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1125. Owned<IConstDFUWorkUnit> wu = factory->openWorkUnit(wuid, false);
  1126. if(wu)
  1127. {
  1128. IEspDFUWorkunit &result = resp.updateResult();
  1129. DeepAssign(context, wu, result);
  1130. int n = resp.getResult().getState();
  1131. if (n == DFUstate_scheduled || n == DFUstate_queued || n == DFUstate_started)
  1132. {
  1133. resp.setAutoRefresh(WUDETAILS_REFRESH_MINS);
  1134. }
  1135. found = true;
  1136. }
  1137. else if ((version > 1.02) && getArchivedWUInfo(context, req, resp))
  1138. {
  1139. found = true;
  1140. }
  1141. if (!found)
  1142. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT, "Dfu workunit %s not found.", req.getWuid());
  1143. }
  1144. catch(IException* e)
  1145. {
  1146. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1147. }
  1148. return true;
  1149. }
  1150. bool CFileSprayEx::onGetDFUProgress(IEspContext &context, IEspProgressRequest &req, IEspProgressResponse &resp)
  1151. {
  1152. try
  1153. {
  1154. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Read, false))
  1155. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to DFU workunit is denied.");
  1156. const char* wuid = req.getWuid();
  1157. if(!wuid || !*wuid)
  1158. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Workunit ID not specified.");
  1159. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1160. Owned<IConstDFUWorkUnit> wu = factory->openWorkUnit(req.getWuid(), false);
  1161. if(!wu)
  1162. throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT, "Dfu workunit %s not found.", req.getWuid());
  1163. resp.setWuid(req.getWuid());
  1164. IConstDFUprogress *prog = wu->queryProgress();
  1165. if (prog)
  1166. {
  1167. resp.setPercentDone(prog->getPercentDone());
  1168. resp.setKbPerSec(prog->getKbPerSec());
  1169. resp.setKbPerSecAve(prog->getKbPerSecAve());
  1170. resp.setSecsLeft(prog->getSecsLeft());
  1171. StringBuffer statestr;
  1172. encodeDFUstate(prog->getState(), statestr);
  1173. resp.setState(statestr.str());
  1174. resp.setSlavesDone(prog->getSlavesDone());
  1175. StringBuffer msg;
  1176. prog->formatProgressMessage(msg);
  1177. resp.setProgressMessage(msg.str());
  1178. prog->formatSummaryMessage(msg.clear());
  1179. resp.setSummaryMessage(msg.str());
  1180. prog->getTimeTaken(msg.clear());
  1181. resp.setTimeTaken(msg.str());
  1182. }
  1183. }
  1184. catch(IException* e)
  1185. {
  1186. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1187. }
  1188. return true;
  1189. }
  1190. bool CFileSprayEx::onCreateDFUWorkunit(IEspContext &context, IEspCreateDFUWorkunit &req, IEspCreateDFUWorkunitResponse &resp)
  1191. {
  1192. try
  1193. {
  1194. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1195. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to create DFU workunit. Permission denied.");
  1196. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1197. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  1198. wu->setQueue(m_QueueLabel.str());
  1199. StringBuffer user, passwd;
  1200. wu->setUser(context.getUserID(user).str());
  1201. wu->setPassword(context.getPassword(passwd).str());
  1202. wu->commit();
  1203. const char * d = wu->queryId();
  1204. IEspDFUWorkunit &result = resp.updateResult();
  1205. DeepAssign(context, wu, result);
  1206. result.setOverwrite(false);
  1207. result.setReplicate(true);
  1208. }
  1209. catch(IException* e)
  1210. {
  1211. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1212. }
  1213. return true;
  1214. }
  1215. bool CFileSprayEx::onUpdateDFUWorkunit(IEspContext &context, IEspUpdateDFUWorkunit &req, IEspUpdateDFUWorkunitResponse &resp)
  1216. {
  1217. try
  1218. {
  1219. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1220. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to update DFU workunit. Permission denied.");
  1221. IConstDFUWorkunit & reqWU = req.getWu();
  1222. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1223. Owned<IDFUWorkUnit> wu = factory->updateWorkUnit(reqWU.getID());
  1224. if(!wu)
  1225. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT, "Dfu workunit %s not found.", reqWU.getID());
  1226. IDFUprogress *prog = wu->queryUpdateProgress();
  1227. if (prog && req.getStateOrig() != reqWU.getState())
  1228. {
  1229. if (prog->getState() != req.getStateOrig())
  1230. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot update DFU workunit %s because its state has been changed internally. Please refresh the page and try again.",reqWU.getID());
  1231. prog->setState((enum DFUstate)reqWU.getState());
  1232. }
  1233. const char* clusterOrig = req.getClusterOrig();
  1234. const char* cluster = reqWU.getClusterName();
  1235. if(cluster && (!clusterOrig || stricmp(clusterOrig, cluster)))
  1236. {
  1237. wu->setClusterName(reqWU.getClusterName());
  1238. }
  1239. const char* jobNameOrig = req.getJobNameOrig();
  1240. const char* jobName = reqWU.getJobName();
  1241. if(jobName && (!jobNameOrig || stricmp(jobNameOrig, jobName)))
  1242. {
  1243. wu->setJobName(jobName);
  1244. }
  1245. if (reqWU.getIsProtected() != req.getIsProtectedOrig())
  1246. wu->protect(reqWU.getIsProtected());
  1247. wu->commit();
  1248. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(reqWU.getID()).str());
  1249. }
  1250. catch(IException* e)
  1251. {
  1252. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1253. }
  1254. return true;
  1255. }
  1256. bool markWUFailed(IDFUWorkUnitFactory *f, const char *wuid)
  1257. {
  1258. Owned<IDFUWorkUnit> wu = f->updateWorkUnit(wuid);
  1259. if(!wu)
  1260. throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT, "Dfu workunit %s not found.", wuid);
  1261. IDFUprogress *prog = wu->queryUpdateProgress();
  1262. if(!prog)
  1263. throw MakeStringException(ECLWATCH_PROGRESS_INFO_NOT_FOUND, "progress information not found for workunit %s.", wuid);
  1264. else if(prog->getState() == DFUstate_started)
  1265. throw MakeStringException(ECLWATCH_CANNOT_DELETE_WORKUNIT, "Cannot delete workunit %s because its state is Started.", wuid);
  1266. else
  1267. {
  1268. prog->setState(DFUstate_failed);
  1269. return true;
  1270. }
  1271. return false;
  1272. }
  1273. bool CFileSprayEx::onDFUWorkunitsAction(IEspContext &context, IEspDFUWorkunitsActionRequest &req, IEspDFUWorkunitsActionResponse &resp)
  1274. {
  1275. try
  1276. {
  1277. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1278. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to update DFU workunit. Permission denied.");
  1279. bool bAllSuccess = true;
  1280. IArrayOf<IEspDFUActionResult> results;
  1281. const char* action = req.getType();
  1282. if(!action || !*action || !strcmp(action, "Delete"))
  1283. {
  1284. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1285. StringArray & wuids = req.getWuids();
  1286. for(unsigned i = 0; i < wuids.ordinality(); ++i)
  1287. {
  1288. Owned<IEspDFUActionResult> res = createDFUActionResult("", "");
  1289. res->setID(wuids.item(i));
  1290. res->setAction("Delete");
  1291. res->setResult("Success");
  1292. try
  1293. {
  1294. if (markWUFailed(factory, wuids.item(i)))
  1295. {
  1296. if (!factory->deleteWorkUnit(wuids.item(i)))
  1297. throw MakeStringException(ECLWATCH_CANNOT_DELETE_WORKUNIT, "Failed in deleting workunit %s.", wuids.item(i));
  1298. }
  1299. }
  1300. catch (IException *e)
  1301. {
  1302. bAllSuccess = false;
  1303. StringBuffer eMsg;
  1304. eMsg = e->errorMessage(eMsg);
  1305. e->Release();
  1306. StringBuffer failedMsg = "Failed: ";
  1307. failedMsg.append(eMsg);
  1308. res->setResult(failedMsg.str());
  1309. }
  1310. results.append(*res.getLink());
  1311. }
  1312. }
  1313. else if (!strcmp(action, "Restore"))
  1314. {
  1315. StringBuffer sashaAddress;
  1316. IArrayOf<IConstTpSashaServer> sashaservers;
  1317. CTpWrapper dummy;
  1318. dummy.getTpSashaServers(sashaservers);
  1319. ForEachItemIn(i, sashaservers)
  1320. {
  1321. IConstTpSashaServer& sashaserver = sashaservers.item(i);
  1322. IArrayOf<IConstTpMachine> &sashaservermachine = sashaserver.getTpMachines();
  1323. sashaAddress.append(sashaservermachine.item(0).getNetaddress());
  1324. }
  1325. if (sashaAddress.length() < 1)
  1326. {
  1327. throw MakeStringException(ECLWATCH_ARCHIVE_SERVER_NOT_FOUND,"Archive server not found.");
  1328. }
  1329. SocketEndpoint ep(sashaAddress.str(), DEFAULT_SASHA_PORT);
  1330. Owned<INode> node = createINode(ep);
  1331. Owned<ISashaCommand> cmd = createSashaCommand();
  1332. cmd->setAction(SCA_RESTORE);
  1333. cmd->setDFU(true);
  1334. StringArray & wuids = req.getWuids();
  1335. for(unsigned ii = 0; ii < wuids.ordinality(); ++ii)
  1336. {
  1337. StringBuffer msg;
  1338. const char *wuid = wuids.item(ii);
  1339. cmd->addId(wuid);
  1340. if (!cmd->send(node,1*60*1000))
  1341. {
  1342. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_ARCHIVE_SERVER,"Cannot connect to archive server at %s.",sashaAddress.str());
  1343. }
  1344. if (cmd->numIds()==0)
  1345. {
  1346. bAllSuccess = false;
  1347. msg.appendf("Restore failed for %s", wuid);
  1348. }
  1349. else
  1350. {
  1351. StringBuffer reply;
  1352. cmd->getId(0,reply);
  1353. msg.appendf("Restore: %s, reply: %s", wuid, reply.str());
  1354. }
  1355. Owned<IEspDFUActionResult> res = createDFUActionResult("", "");
  1356. res->setID(wuid);
  1357. res->setAction("Restore");
  1358. res->setResult(msg.str());
  1359. results.append(*res.getLink());
  1360. }
  1361. }
  1362. else if(!strcmp(action, "Protect"))
  1363. {
  1364. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1365. StringArray & wuids = req.getWuids();
  1366. for(unsigned i = 0; i < wuids.ordinality(); ++i)
  1367. {
  1368. Owned<IEspDFUActionResult> res = createDFUActionResult("", "");
  1369. res->setID(wuids.item(i));
  1370. res->setAction("Protect");
  1371. res->setResult("Success");
  1372. try
  1373. {
  1374. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1375. Owned<IDFUWorkUnit> wu = factory->updateWorkUnit(wuids.item(i));
  1376. if(!wu.get())
  1377. continue;
  1378. wu->protect(true);
  1379. wu->commit();
  1380. }
  1381. catch (IException *e)
  1382. {
  1383. bAllSuccess = false;
  1384. StringBuffer eMsg;
  1385. eMsg = e->errorMessage(eMsg);
  1386. e->Release();
  1387. StringBuffer failedMsg = "Failed: ";
  1388. failedMsg.append(eMsg);
  1389. res->setResult(failedMsg.str());
  1390. }
  1391. results.append(*res.getLink());
  1392. }
  1393. }
  1394. else if(!strcmp(action, "Unprotect"))
  1395. {
  1396. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1397. StringArray & wuids = req.getWuids();
  1398. for(unsigned i = 0; i < wuids.ordinality(); ++i)
  1399. {
  1400. Owned<IEspDFUActionResult> res = createDFUActionResult("", "");
  1401. res->setID(wuids.item(i));
  1402. res->setAction("Unprotect");
  1403. res->setResult("Success");
  1404. try
  1405. {
  1406. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1407. Owned<IDFUWorkUnit> wu = factory->updateWorkUnit(wuids.item(i));
  1408. if(!wu.get())
  1409. continue;
  1410. wu->protect(false);
  1411. wu->commit();
  1412. }
  1413. catch (IException *e)
  1414. {
  1415. bAllSuccess = false;
  1416. StringBuffer eMsg;
  1417. eMsg = e->errorMessage(eMsg);
  1418. e->Release();
  1419. StringBuffer failedMsg = "Failed: ";
  1420. failedMsg.append(eMsg);
  1421. res->setResult(failedMsg.str());
  1422. }
  1423. results.append(*res.getLink());
  1424. }
  1425. }
  1426. else if(!strcmp(action, "SetToFailed"))
  1427. {
  1428. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1429. StringArray & wuids = req.getWuids();
  1430. for(unsigned i = 0; i < wuids.ordinality(); ++i)
  1431. {
  1432. Owned<IEspDFUActionResult> res = createDFUActionResult("", "");
  1433. res->setID(wuids.item(i));
  1434. res->setAction("SetToFailed");
  1435. res->setResult("Success");
  1436. try
  1437. {
  1438. Owned<IDFUWorkUnit> wu = factory->updateWorkUnit(wuids.item(i));
  1439. if(wu)
  1440. {
  1441. IDFUprogress *prog = wu->queryUpdateProgress();
  1442. if (prog)
  1443. {
  1444. prog->setState(DFUstate_failed);
  1445. wu->commit();
  1446. }
  1447. }
  1448. }
  1449. catch (IException *e)
  1450. {
  1451. bAllSuccess = false;
  1452. StringBuffer eMsg;
  1453. eMsg = e->errorMessage(eMsg);
  1454. e->Release();
  1455. StringBuffer failedMsg = "Failed: ";
  1456. failedMsg.append(eMsg);
  1457. res->setResult(failedMsg.str());
  1458. }
  1459. results.append(*res.getLink());
  1460. }
  1461. }
  1462. else
  1463. throw MakeStringException(ECLWATCH_INVALID_ACTION, "Unknown action type %s", action);
  1464. if (bAllSuccess && checkRedirect(context) && strcmp(action, "Delete"))
  1465. {
  1466. if (!strcmp(action, "Restore"))
  1467. resp.setRedirectUrl("/FileSpray/GetDFUWorkunits?Type=archived workunits");
  1468. else
  1469. resp.setRedirectUrl("/FileSpray/GetDFUWorkunits");
  1470. }
  1471. else
  1472. {
  1473. resp.setDFUActionResults(results);
  1474. }
  1475. }
  1476. catch(IException* e)
  1477. {
  1478. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1479. }
  1480. return true;
  1481. }
  1482. bool CFileSprayEx::onDeleteDFUWorkunits(IEspContext &context, IEspDeleteDFUWorkunits &req, IEspDeleteDFUWorkunitsResponse &resp)
  1483. {
  1484. try
  1485. {
  1486. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1487. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to delete DFU workunit. Permission denied.");
  1488. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1489. StringArray & wuids = req.getWuids();
  1490. for(unsigned i = 0; i < wuids.ordinality(); ++i)
  1491. {
  1492. if (markWUFailed(factory, wuids.item(i)))
  1493. factory->deleteWorkUnit(wuids.item(i));
  1494. }
  1495. resp.setRedirectUrl("/FileSpray/GetDFUWorkunits");
  1496. }
  1497. catch(IException* e)
  1498. {
  1499. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1500. }
  1501. return true;
  1502. }
  1503. bool CFileSprayEx::onDeleteDFUWorkunit(IEspContext &context, IEspDeleteDFUWorkunit &req, IEspDeleteDFUWorkunitResponse &resp)
  1504. {
  1505. try
  1506. {
  1507. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1508. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to delete DFU workunit. Permission denied.");
  1509. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1510. if (markWUFailed(factory, req.getWuid()))
  1511. resp.setResult(factory->deleteWorkUnit(req.getWuid()));
  1512. else
  1513. resp.setResult(false);
  1514. resp.setRedirectUrl("/FileSpray/GetDFUWorkunits");
  1515. }
  1516. catch(IException* e)
  1517. {
  1518. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1519. }
  1520. return true;
  1521. }
  1522. bool CFileSprayEx::onSubmitDFUWorkunit(IEspContext &context, IEspSubmitDFUWorkunit &req, IEspSubmitDFUWorkunitResponse &resp)
  1523. {
  1524. try
  1525. {
  1526. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1527. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to submit DFU workunit. Permission denied.");
  1528. submitDFUWorkUnit(req.getWuid());
  1529. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(req.getWuid()).str());
  1530. }
  1531. catch(IException* e)
  1532. {
  1533. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1534. }
  1535. return true;
  1536. }
  1537. bool CFileSprayEx::onAbortDFUWorkunit(IEspContext &context, IEspAbortDFUWorkunit &req, IEspAbortDFUWorkunitResponse &resp)
  1538. {
  1539. try
  1540. {
  1541. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Write, false))
  1542. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Failed to abort DFU workunit. Permission denied.");
  1543. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1544. Owned<IDFUWorkUnit> wu = factory->updateWorkUnit(req.getWuid());
  1545. if(!wu)
  1546. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT, "Dfu workunit %s not found.", req.getWuid());
  1547. wu->requestAbort();
  1548. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(req.getWuid()).str());
  1549. }
  1550. catch(IException* e)
  1551. {
  1552. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1553. }
  1554. return true;
  1555. }
  1556. bool CFileSprayEx::onGetDFUExceptions(IEspContext &context, IEspGetDFUExceptions &req, IEspGetDFUExceptionsResponse &resp)
  1557. {
  1558. try
  1559. {
  1560. if (!context.validateFeatureAccess(DFU_EX_URL, SecAccess_Read, false))
  1561. throw MakeStringException(ECLWATCH_DFU_EX_ACCESS_DENIED, "Failed to get DFU Exceptions. Permission denied.");
  1562. IArrayOf<IEspDFUException> result;
  1563. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1564. Owned<IDFUWorkUnit> wu = factory->updateWorkUnit(req.getWuid());
  1565. if(!wu)
  1566. throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT, "Dfu workunit %s not found.", req.getWuid());
  1567. Owned<IExceptionIterator> itr = wu->getExceptionIterator();
  1568. itr->first();
  1569. while(itr->isValid())
  1570. {
  1571. Owned<IEspDFUException> resultE = createDFUException("", "");
  1572. IException &e = itr->query();
  1573. resultE->setCode(e.errorCode());
  1574. StringBuffer msg;
  1575. resultE->setMessage(e.errorMessage(msg).str());
  1576. result.append(*resultE.getLink());
  1577. itr->next();
  1578. }
  1579. resp.setResult(result);
  1580. }
  1581. catch(IException* e)
  1582. {
  1583. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1584. }
  1585. return true;
  1586. }
  1587. bool CFileSprayEx::onSprayFixed(IEspContext &context, IEspSprayFixed &req, IEspSprayFixedResponse &resp)
  1588. {
  1589. try
  1590. {
  1591. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Write, false))
  1592. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do Spray. Permission denied.");
  1593. StringBuffer destFolder, destTitle, defaultFolder, defaultReplicateFolder;
  1594. const char* destCluster = req.getDestGroup();
  1595. if(destCluster == NULL || *destCluster == '\0')
  1596. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination cluster/group not specified.");
  1597. MemoryBuffer& srcxml = (MemoryBuffer&)req.getSrcxml();
  1598. const char* srcip = req.getSourceIP();
  1599. const char* srcfile = req.getSourcePath();
  1600. if(srcxml.length() == 0)
  1601. {
  1602. if(!srcip || !*srcip)
  1603. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source network IP not specified.");
  1604. if(!srcfile || !*srcfile)
  1605. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source file not specified.");
  1606. }
  1607. bool nosplit = req.getNosplit();
  1608. int recordsize = req.getSourceRecordSize();
  1609. if(recordsize == 0 && !nosplit) // -ve record sizes for blocked
  1610. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid record size");
  1611. const char* destname = req.getDestLogicalName();
  1612. if(!destname || !*destname)
  1613. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination file not specified.");
  1614. CDfsLogicalFileName lfn;
  1615. if (!lfn.setValidate(destname))
  1616. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid destination filename");
  1617. destname = lfn.get();
  1618. StringBuffer gName, ipAddr;
  1619. const char *pTr = strchr(destCluster, ' ');
  1620. if (pTr)
  1621. {
  1622. gName.append(pTr - destCluster, destCluster);
  1623. ipAddr.append(pTr+1);
  1624. }
  1625. else
  1626. gName.append(destCluster);
  1627. if (ipAddr.length() > 0)
  1628. ParseLogicalPath(destname, ipAddr.str(), destFolder, destTitle, defaultFolder, defaultReplicateFolder);
  1629. else
  1630. ParseLogicalPath(destname, destCluster, destFolder, destTitle, defaultFolder, defaultReplicateFolder);
  1631. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1632. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  1633. wu->setClusterName(gName.str());
  1634. wu->setJobName(destTitle.str());
  1635. wu->setQueue(m_QueueLabel.str());
  1636. StringBuffer user, passwd;
  1637. wu->setUser(context.getUserID(user).str());
  1638. wu->setPassword(context.getPassword(passwd).str());
  1639. wu->setCommand(DFUcmd_import);
  1640. IDFUfileSpec *source = wu->queryUpdateSource();
  1641. if(srcxml.length() == 0)
  1642. {
  1643. RemoteMultiFilename rmfn;
  1644. SocketEndpoint ep(srcip);
  1645. rmfn.setEp(ep);
  1646. StringBuffer fnamebuf(srcfile);
  1647. fnamebuf.trim();
  1648. rmfn.append(fnamebuf.str()); // handles comma separated files
  1649. source->setMultiFilename(rmfn);
  1650. }
  1651. else
  1652. {
  1653. srcxml.append('\0');
  1654. source->setFromXML((const char*)srcxml.toByteArray());
  1655. }
  1656. IDFUfileSpec *destination = wu->queryUpdateDestination();
  1657. if(recordsize > 0)
  1658. source->setRecordSize(recordsize);
  1659. else if (recordsize == RECFMVB_RECSIZE_ESCAPE) {
  1660. source->setFormat(DFUff_recfmvb);
  1661. destination->setFormat(DFUff_variable);
  1662. }
  1663. else if (recordsize == RECFMV_RECSIZE_ESCAPE) {
  1664. source->setFormat(DFUff_recfmv);
  1665. destination->setFormat(DFUff_variable);
  1666. }
  1667. else if (recordsize == PREFIX_VARIABLE_RECSIZE_ESCAPE) {
  1668. source->setFormat(DFUff_variable);
  1669. destination->setFormat(DFUff_variable);
  1670. }
  1671. else if (recordsize == PREFIX_VARIABLE_BIGENDIAN_RECSIZE_ESCAPE) {
  1672. source->setFormat(DFUff_variablebigendian);
  1673. destination->setFormat(DFUff_variable);
  1674. }
  1675. destination->setLogicalName(destname);
  1676. destination->setDirectory(destFolder.str());
  1677. StringBuffer fileMask;
  1678. constructFileMask(destTitle.str(), fileMask);
  1679. destination->setFileMask(fileMask.str());
  1680. destination->setGroupName(gName.str());
  1681. const char * encryptkey = req.getEncrypt();
  1682. if(req.getCompress()||(encryptkey&&*encryptkey))
  1683. destination->setCompressed(true);
  1684. ClusterPartDiskMapSpec mspec;
  1685. destination->getClusterPartDiskMapSpec(gName.str(), mspec);
  1686. mspec.setDefaultBaseDir(defaultFolder.str());
  1687. mspec.setDefaultReplicateDir(defaultReplicateFolder.str());
  1688. destination->setClusterPartDiskMapSpec(gName.str(), mspec);
  1689. int repo = req.getReplicateOffset();
  1690. bool isNull = req.getReplicateOffset_isNull();
  1691. if (!isNull && (repo!=1))
  1692. destination->setReplicateOffset(repo);
  1693. if (req.getWrap())
  1694. destination->setWrap(true);
  1695. IDFUoptions *options = wu->queryUpdateOptions();
  1696. const char * decryptkey = req.getDecrypt();
  1697. if ((encryptkey&&*encryptkey)||(decryptkey&&*decryptkey))
  1698. options->setEncDec(encryptkey,decryptkey);
  1699. options->setReplicate(req.getReplicate());
  1700. options->setOverwrite(req.getOverwrite()); // needed if target already exists
  1701. const char* prefix = req.getPrefix();
  1702. if(prefix && *prefix)
  1703. options->setLengthPrefix(prefix);
  1704. if(req.getNosplit())
  1705. options->setNoSplit(true);
  1706. if(req.getNorecover())
  1707. options->setNoRecover(true);
  1708. if(req.getMaxConnections() > 0)
  1709. options->setmaxConnections(req.getMaxConnections());
  1710. if(req.getThrottle() > 0)
  1711. options->setThrottle(req.getThrottle());
  1712. if(req.getTransferBufferSize() > 0)
  1713. options->setTransferBufferSize(req.getTransferBufferSize());
  1714. if (req.getPull())
  1715. options->setPull(true);
  1716. if (req.getPush())
  1717. options->setPush(true);
  1718. resp.setWuid(wu->queryId());
  1719. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  1720. submitDFUWorkUnit(wu.getClear());
  1721. }
  1722. catch(IException* e)
  1723. {
  1724. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1725. }
  1726. return true;
  1727. }
  1728. bool CFileSprayEx::onSprayVariable(IEspContext &context, IEspSprayVariable &req, IEspSprayResponse &resp)
  1729. {
  1730. try
  1731. {
  1732. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Write, false))
  1733. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do Spray. Permission denied.");
  1734. StringBuffer destFolder, destTitle, defaultFolder, defaultReplicateFolder;
  1735. const char* destCluster = req.getDestGroup();
  1736. if(destCluster == NULL || *destCluster == '\0')
  1737. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination cluster/group not specified.");
  1738. StringBuffer gName, ipAddr;
  1739. const char *pTr = strchr(destCluster, ' ');
  1740. if (pTr)
  1741. {
  1742. gName.append(pTr - destCluster, destCluster);
  1743. ipAddr.append(pTr+1);
  1744. }
  1745. else
  1746. gName.append(destCluster);
  1747. MemoryBuffer& srcxml = (MemoryBuffer&)req.getSrcxml();
  1748. const char* srcip = req.getSourceIP();
  1749. const char* srcfile = req.getSourcePath();
  1750. if(srcxml.length() == 0)
  1751. {
  1752. if(!srcip || !*srcip)
  1753. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source network IP not specified.");
  1754. if(!srcfile || !*srcfile)
  1755. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source file not specified.");
  1756. }
  1757. const char* destname = req.getDestLogicalName();
  1758. if(!destname || !*destname)
  1759. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination file not specified.");
  1760. CDfsLogicalFileName lfn;
  1761. if (!lfn.setValidate(destname))
  1762. throw MakeStringException(ECLWATCH_INVALID_INPUT, "invalid destination filename");
  1763. destname = lfn.get();
  1764. if (ipAddr.length() > 0)
  1765. ParseLogicalPath(destname, ipAddr.str(), destFolder, destTitle, defaultFolder, defaultReplicateFolder);
  1766. else
  1767. ParseLogicalPath(destname, destCluster, destFolder, destTitle, defaultFolder, defaultReplicateFolder);
  1768. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1769. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  1770. wu->setClusterName(gName.str());
  1771. wu->setJobName(destTitle.str());
  1772. wu->setQueue(m_QueueLabel.str());
  1773. StringBuffer user, passwd;
  1774. wu->setUser(context.getUserID(user).str());
  1775. wu->setPassword(context.getPassword(passwd).str());
  1776. wu->setCommand(DFUcmd_import);
  1777. IDFUfileSpec *source = wu->queryUpdateSource();
  1778. IDFUfileSpec *destination = wu->queryUpdateDestination();
  1779. IDFUoptions *options = wu->queryUpdateOptions();
  1780. if(srcxml.length() == 0)
  1781. {
  1782. RemoteMultiFilename rmfn;
  1783. SocketEndpoint ep(srcip);
  1784. rmfn.setEp(ep);
  1785. StringBuffer fnamebuf(srcfile);
  1786. fnamebuf.trim();
  1787. rmfn.append(fnamebuf.str()); // handles comma separated files
  1788. source->setMultiFilename(rmfn);
  1789. }
  1790. else
  1791. {
  1792. srcxml.append('\0');
  1793. source->setFromXML((const char*)srcxml.toByteArray());
  1794. }
  1795. source->setMaxRecordSize(req.getSourceMaxRecordSize());
  1796. source->setFormat((DFUfileformat)req.getSourceFormat());
  1797. // if rowTag specified, it means it's xml format, otherwise it's csv
  1798. const char* rowtag = req.getSourceRowTag();
  1799. if(rowtag != NULL && *rowtag != '\0')
  1800. {
  1801. source->setRowTag(rowtag);
  1802. options->setKeepHeader(true);
  1803. }
  1804. else
  1805. {
  1806. const char* cs = req.getSourceCsvSeparate();
  1807. if (req.getNoSourceCsvSeparator())
  1808. {
  1809. cs = "";
  1810. }
  1811. else if(cs == NULL || *cs == '\0')
  1812. cs = "\\,";
  1813. const char* ct = req.getSourceCsvTerminate();
  1814. if(ct == NULL || *ct == '\0')
  1815. ct = "\\n,\\r\\n";
  1816. const char* cq = req.getSourceCsvQuote();
  1817. if(cq== NULL)
  1818. cq = "'";
  1819. source->setCsvOptions(cs, ct, cq, req.getSourceCsvEscape());
  1820. }
  1821. destination->setLogicalName(destname);
  1822. destination->setDirectory(destFolder.str());
  1823. StringBuffer fileMask;
  1824. constructFileMask(destTitle.str(), fileMask);
  1825. destination->setFileMask(fileMask.str());
  1826. destination->setGroupName(gName.str());
  1827. ClusterPartDiskMapSpec mspec;
  1828. destination->getClusterPartDiskMapSpec(gName.str(), mspec);
  1829. mspec.setDefaultBaseDir(defaultFolder.str());
  1830. mspec.setDefaultReplicateDir(defaultReplicateFolder.str());
  1831. destination->setClusterPartDiskMapSpec(gName.str(), mspec);
  1832. const char * encryptkey = req.getEncrypt();
  1833. if(req.getCompress()||(encryptkey&&*encryptkey))
  1834. destination->setCompressed(true);
  1835. const char * decryptkey = req.getDecrypt();
  1836. if ((encryptkey&&*encryptkey)||(decryptkey&&*decryptkey))
  1837. options->setEncDec(encryptkey,decryptkey);
  1838. int repo = req.getReplicateOffset();
  1839. bool isNull = req.getReplicateOffset_isNull();
  1840. if (!isNull && (repo!=1))
  1841. destination->setReplicateOffset(repo);
  1842. options->setReplicate(req.getReplicate());
  1843. options->setOverwrite(req.getOverwrite()); // needed if target already exists
  1844. const char* prefix = req.getPrefix();
  1845. if(prefix && *prefix)
  1846. options->setLengthPrefix(prefix);
  1847. if(req.getNosplit())
  1848. options->setNoSplit(true);
  1849. if(req.getNorecover())
  1850. options->setNoRecover(true);
  1851. if(req.getMaxConnections() > 0)
  1852. options->setmaxConnections(req.getMaxConnections());
  1853. if(req.getThrottle() > 0)
  1854. options->setThrottle(req.getThrottle());
  1855. if(req.getTransferBufferSize() > 0)
  1856. options->setTransferBufferSize(req.getTransferBufferSize());
  1857. if (req.getPull())
  1858. options->setPull(true);
  1859. if (req.getPush())
  1860. options->setPush(true);
  1861. resp.setWuid(wu->queryId());
  1862. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  1863. submitDFUWorkUnit(wu.getClear());
  1864. }
  1865. catch(IException* e)
  1866. {
  1867. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1868. }
  1869. return true;
  1870. }
  1871. bool CFileSprayEx::onReplicate(IEspContext &context, IEspReplicate &req, IEspReplicateResponse &resp)
  1872. {
  1873. try
  1874. {
  1875. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Write, false))
  1876. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do Replicate. Permission denied.");
  1877. const char* srcname = req.getSourceLogicalName();
  1878. if(!srcname || !*srcname)
  1879. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source logical file not specified.");
  1880. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1881. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  1882. StringBuffer jobname = "Replicate: ";
  1883. jobname.append(srcname);
  1884. wu->setJobName(jobname.str());
  1885. wu->setQueue(m_QueueLabel.str());
  1886. StringBuffer user, passwd;
  1887. wu->setUser(context.getUserID(user).str());
  1888. wu->setPassword(context.getPassword(passwd).str());
  1889. wu->setCommand(DFUcmd_replicate);
  1890. IDFUfileSpec *source = wu->queryUpdateSource();
  1891. if (source)
  1892. {
  1893. source->setLogicalName(srcname);
  1894. int repo = req.getReplicateOffset();
  1895. if (repo!=1)
  1896. source->setReplicateOffset(repo);
  1897. }
  1898. const char* cluster = req.getCluster();
  1899. if(cluster && *cluster)
  1900. {
  1901. IDFUoptions *opt = wu->queryUpdateOptions();
  1902. opt->setReplicateMode(DFURMmissing,cluster,req.getRepeatLast(),req.getOnlyRepeated());
  1903. }
  1904. resp.setWuid(wu->queryId());
  1905. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  1906. submitDFUWorkUnit(wu.getClear());
  1907. }
  1908. catch(IException* e)
  1909. {
  1910. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1911. }
  1912. return true;
  1913. }
  1914. bool CFileSprayEx::onDespray(IEspContext &context, IEspDespray &req, IEspDesprayResponse &resp)
  1915. {
  1916. try
  1917. {
  1918. if (!context.validateFeatureAccess(FILE_DESPRAY_URL, SecAccess_Write, false))
  1919. throw MakeStringException(ECLWATCH_FILE_DESPRAY_ACCESS_DENIED, "Failed to do Despray. Permission denied.");
  1920. const char* srcname = req.getSourceLogicalName();
  1921. if(!srcname || !*srcname)
  1922. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source logical file not specified.");
  1923. const char* destip = req.getDestIP();
  1924. StringBuffer fnamebuf(req.getDestPath());
  1925. const char* destfile = fnamebuf.trim().str();
  1926. MemoryBuffer& dstxml = (MemoryBuffer&)req.getDstxml();
  1927. if(dstxml.length() == 0)
  1928. {
  1929. if(!destip || !*destip)
  1930. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination network IP not specified.");
  1931. if(!destfile || !*destfile)
  1932. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination file not specified.");
  1933. }
  1934. StringBuffer srcTitle;
  1935. ParseLogicalPath(srcname, srcTitle);
  1936. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  1937. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  1938. wu->setJobName(srcTitle.str());
  1939. wu->setQueue(m_QueueLabel.str());
  1940. StringBuffer user, passwd;
  1941. wu->setUser(context.getUserID(user).str());
  1942. wu->setPassword(context.getPassword(passwd).str());
  1943. wu->setCommand(DFUcmd_export);
  1944. IDFUfileSpec *source = wu->queryUpdateSource();
  1945. IDFUfileSpec *destination = wu->queryUpdateDestination();
  1946. IDFUoptions *options = wu->queryUpdateOptions();
  1947. source->setLogicalName(srcname);
  1948. if(dstxml.length() == 0)
  1949. {
  1950. RemoteFilename rfn;
  1951. SocketEndpoint ep(destip);
  1952. rfn.setPath(ep, destfile);
  1953. destination->setSingleFilename(rfn);
  1954. }
  1955. else
  1956. {
  1957. dstxml.append('\0');
  1958. destination->setFromXML((const char*)dstxml.toByteArray());
  1959. }
  1960. destination->setTitle(srcTitle.str());
  1961. options->setKeepHeader(true);
  1962. options->setOverwrite(req.getOverwrite()); // needed if target already exists
  1963. const char* splitprefix = req.getSplitprefix();
  1964. if(splitprefix && *splitprefix)
  1965. options->setSplitPrefix(splitprefix);
  1966. double version = context.getClientVersion();
  1967. if (version > 1.01)
  1968. {
  1969. if(req.getMaxConnections() > 0)
  1970. options->setmaxConnections(req.getMaxConnections());
  1971. else if(req.getSingleConnection())
  1972. options->setmaxConnections(1);
  1973. }
  1974. else
  1975. {
  1976. if(req.getMaxConnections() > 0)
  1977. options->setmaxConnections(req.getMaxConnections());
  1978. }
  1979. if(req.getThrottle() > 0)
  1980. options->setThrottle(req.getThrottle());
  1981. if(req.getTransferBufferSize() > 0)
  1982. options->setTransferBufferSize(req.getTransferBufferSize());
  1983. if(req.getNorecover())
  1984. options->setNoRecover(true);
  1985. if (req.getWrap()) {
  1986. options->setPush(); // I think needed for a despray
  1987. destination->setWrap(true);
  1988. }
  1989. if (req.getMultiCopy())
  1990. destination->setMultiCopy(true);
  1991. const char * encryptkey = req.getEncrypt();
  1992. if(req.getCompress()||(encryptkey&&*encryptkey))
  1993. destination->setCompressed(true);
  1994. const char * decryptkey = req.getDecrypt();
  1995. if ((encryptkey&&*encryptkey)||(decryptkey&&*decryptkey))
  1996. options->setEncDec(encryptkey,decryptkey);
  1997. resp.setWuid(wu->queryId());
  1998. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  1999. submitDFUWorkUnit(wu.getClear());
  2000. }
  2001. catch(IException* e)
  2002. {
  2003. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2004. }
  2005. return true;
  2006. }
  2007. bool CFileSprayEx::doCopyForRoxie(IEspContext &context, const char * srcName, const char * srcDali, const char * srcUser, const char * srcPassword,
  2008. const char * dstName, const char * destCluster, bool compressed, bool overwrite, bool supercopy,
  2009. DFUclusterPartDiskMapping val, StringBuffer baseDir, StringBuffer fileMask, IEspCopyResponse &resp)
  2010. {
  2011. StringBuffer user, passwd;
  2012. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  2013. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  2014. if (supercopy)
  2015. {
  2016. wu->setJobName(dstName);
  2017. wu->setQueue(m_QueueLabel.str());
  2018. wu->setUser(context.getUserID(user).str());
  2019. wu->setPassword(context.getPassword(passwd).str());
  2020. wu->setClusterName(destCluster);
  2021. IDFUfileSpec *source = wu->queryUpdateSource();
  2022. wu->setCommand(DFUcmd_supercopy); // **** super copy
  2023. source->setLogicalName(srcName);
  2024. if (srcDali) // remote copy
  2025. {
  2026. SocketEndpoint ep(srcDali);
  2027. source->setForeignDali(ep);
  2028. source->setForeignUser(srcUser, srcPassword);
  2029. }
  2030. IDFUfileSpec *destination = wu->queryUpdateDestination();
  2031. destination->setLogicalName(dstName);
  2032. destination->setFileMask(fileMask);
  2033. destination->setClusterPartDiskMapping(val, baseDir, destCluster); // roxie
  2034. if(compressed)
  2035. destination->setCompressed(true);
  2036. destination->setWrap(true); // roxie always wraps
  2037. IDFUoptions *options = wu->queryUpdateOptions();
  2038. options->setOverwrite(overwrite);
  2039. options->setReplicate(val==DFUcpdm_c_replicated_by_d); // roxie
  2040. }
  2041. else
  2042. {
  2043. wu->setJobName(dstName);
  2044. wu->setQueue(m_QueueLabel.str());
  2045. wu->setUser(context.getUserID(user).str());
  2046. wu->setPassword(context.getPassword(passwd).str());
  2047. wu->setClusterName(destCluster);
  2048. wu->setCommand(DFUcmd_copy);
  2049. IDFUfileSpec *source = wu->queryUpdateSource();
  2050. source->setLogicalName(srcName);
  2051. if (srcDali) // remote copy
  2052. {
  2053. SocketEndpoint ep(srcDali);
  2054. source->setForeignDali(ep);
  2055. source->setForeignUser(srcUser, srcPassword);
  2056. }
  2057. IDFUfileSpec *destination = wu->queryUpdateDestination();
  2058. destination->setLogicalName(dstName);
  2059. destination->setFileMask(fileMask);
  2060. destination->setClusterPartDiskMapping(val, baseDir, destCluster, true); // **** repeat last part
  2061. if(compressed)
  2062. destination->setCompressed(true);
  2063. destination->setWrap(true); // roxie always wraps
  2064. IDFUoptions *options = wu->queryUpdateOptions();
  2065. options->setOverwrite(overwrite);
  2066. options->setReplicate(val==DFUcpdm_c_replicated_by_d); // roxie
  2067. options->setSuppressNonKeyRepeats(true); // **** only repeat last part when src kind = key
  2068. }
  2069. resp.setResult(wu->queryId());
  2070. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  2071. submitDFUWorkUnit(wu.getClear());
  2072. return true;
  2073. }
  2074. bool CFileSprayEx::onCopy(IEspContext &context, IEspCopy &req, IEspCopyResponse &resp)
  2075. {
  2076. try
  2077. {
  2078. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Write, false))
  2079. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do Copy. Permission denied.");
  2080. const char* srcname = req.getSourceLogicalName();
  2081. const char* dstname = req.getDestLogicalName();
  2082. if(!srcname || !*srcname)
  2083. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source logical file not specified.");
  2084. if(!dstname || !*dstname)
  2085. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination logical file not specified.");
  2086. StringBuffer destFolder, destTitle, defaultFolder, defaultReplicateFolder;
  2087. StringBuffer srcCluster, destCluster, destClusterName;
  2088. bool bRoxie = false;
  2089. const char* destCluster0 = req.getDestGroup();
  2090. if(destCluster0 == NULL || *destCluster0 == '\0')
  2091. {
  2092. getClusterFromLFN(srcname, srcCluster, context.queryUserId(), context.queryPassword());
  2093. DBGLOG("Destination cluster/group not specified, using source cluster %s", srcCluster.str());
  2094. destCluster = srcCluster.str();
  2095. destClusterName = srcCluster.str();
  2096. }
  2097. else
  2098. {
  2099. destCluster = destCluster0;
  2100. destClusterName = destCluster0;
  2101. const char* destClusterRoxie = req.getDestGroupRoxie();
  2102. if (destClusterRoxie && !stricmp(destClusterRoxie, "Yes"))
  2103. {
  2104. bRoxie = true;
  2105. }
  2106. }
  2107. int offset;
  2108. StringBuffer sbf, baseDir;
  2109. DFUclusterPartDiskMapping val;
  2110. CDfsLogicalFileName lfn;
  2111. if (!bRoxie)
  2112. {
  2113. if (!lfn.setValidate(dstname))
  2114. throw MakeStringException(ECLWATCH_INVALID_INPUT, "invalid destination filename");
  2115. dstname = lfn.get();
  2116. }
  2117. else
  2118. {
  2119. val = readClusterMappingSettings(destCluster.str(), baseDir, offset);
  2120. }
  2121. ParseLogicalPath(dstname, destCluster.str(), destFolder, destTitle, defaultFolder, defaultReplicateFolder);
  2122. StringBuffer fileMask;
  2123. constructFileMask(destTitle.str(), fileMask);
  2124. const char* srcDali = req.getSourceDali();
  2125. bool supercopy = req.getSuperCopy();
  2126. if (supercopy)
  2127. {
  2128. StringBuffer user, passwd;
  2129. context.getUserID(user);
  2130. context.getPassword(passwd);
  2131. StringBuffer u(user);
  2132. StringBuffer p(passwd);
  2133. Owned<INode> foreigndali;
  2134. if (srcDali)
  2135. {
  2136. SocketEndpoint ep(srcDali);
  2137. foreigndali.setown(createINode(ep));
  2138. const char* srcu = req.getSrcusername();
  2139. if(srcu && *srcu)
  2140. {
  2141. u.clear().append(srcu);
  2142. p.clear().append(req.getSrcpassword());
  2143. }
  2144. }
  2145. Owned<IUserDescriptor> udesc=createUserDescriptor();
  2146. udesc->set(u.str(),p.str());
  2147. if (!queryDistributedFileDirectory().isSuperFile(srcname,udesc,foreigndali))
  2148. supercopy = false;
  2149. }
  2150. if (bRoxie)
  2151. {
  2152. bool compressRoxieCopy = false;
  2153. bool overwriteRoxieCopy = false;
  2154. if(req.getCompress())
  2155. compressRoxieCopy = true;
  2156. if(req.getOverwrite())
  2157. overwriteRoxieCopy = true;
  2158. return doCopyForRoxie(context, srcname, req.getSourceDali(), req.getSrcusername(), req.getSrcpassword(),
  2159. dstname, destCluster, req.getCompress(), req.getOverwrite(), supercopy, val, baseDir, fileMask, resp);
  2160. }
  2161. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  2162. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  2163. wu->setJobName(dstname);
  2164. wu->setQueue(m_QueueLabel.str());
  2165. StringBuffer user, passwd;
  2166. wu->setUser(context.getUserID(user).str());
  2167. wu->setPassword(context.getPassword(passwd).str());
  2168. if(destCluster.length() > 0)
  2169. {
  2170. wu->setClusterName(destCluster.str());
  2171. }
  2172. const char* srcDiffKeyName = req.getSourceDiffKeyName();
  2173. const char* destDiffKeyName = req.getDestDiffKeyName();
  2174. IDFUfileSpec *source = wu->queryUpdateSource();
  2175. IDFUfileSpec *destination = wu->queryUpdateDestination();
  2176. IDFUoptions *options = wu->queryUpdateOptions();
  2177. if (supercopy)
  2178. wu->setCommand(DFUcmd_supercopy);
  2179. else
  2180. wu->setCommand(DFUcmd_copy);
  2181. source->setLogicalName(srcname);
  2182. if(srcDali && *srcDali)
  2183. {
  2184. SocketEndpoint ep(srcDali);
  2185. source->setForeignDali(ep);
  2186. const char* srcusername = req.getSrcusername();
  2187. if(srcusername && *srcusername)
  2188. {
  2189. const char* srcpasswd = req.getSrcpassword();
  2190. source->setForeignUser(srcusername, srcpasswd);
  2191. }
  2192. }
  2193. if (bRoxie)
  2194. {
  2195. destination->setClusterPartDiskMapping(val, baseDir.str(), destCluster.str());
  2196. if (val != DFUcpdm_c_replicated_by_d)
  2197. {
  2198. options->setReplicate(false);
  2199. }
  2200. else
  2201. {
  2202. options->setReplicate(true);
  2203. destination->setReplicateOffset(offset);
  2204. }
  2205. }
  2206. if (srcDiffKeyName&&*srcDiffKeyName)
  2207. source->setDiffKey(srcDiffKeyName);
  2208. if (destDiffKeyName&&*destDiffKeyName)
  2209. destination->setDiffKey(destDiffKeyName);
  2210. if (!bRoxie)
  2211. {
  2212. destination->setDirectory(destFolder.str());
  2213. ClusterPartDiskMapSpec mspec;
  2214. destination->getClusterPartDiskMapSpec(destCluster.str(), mspec);
  2215. mspec.setDefaultBaseDir(defaultFolder.str());
  2216. mspec.setDefaultReplicateDir(defaultReplicateFolder.str());
  2217. destination->setClusterPartDiskMapSpec(destCluster.str(), mspec);
  2218. }
  2219. destination->setFileMask(fileMask.str());
  2220. destination->setGroupName(destCluster.str());
  2221. destination->setLogicalName(dstname);
  2222. const char * encryptkey = req.getEncrypt();
  2223. if(req.getCompress()||(encryptkey&&*encryptkey))
  2224. destination->setCompressed(true);
  2225. if (!bRoxie)
  2226. {
  2227. options->setReplicate(req.getReplicate());
  2228. destination->setWrap(req.getWrap());
  2229. }
  2230. else
  2231. {
  2232. destination->setWrap(true);
  2233. }
  2234. const char * decryptkey = req.getDecrypt();
  2235. if ((encryptkey&&*encryptkey)||(decryptkey&&*decryptkey))
  2236. options->setEncDec(encryptkey,decryptkey);
  2237. options->setOverwrite(req.getOverwrite());
  2238. if(req.getNorecover())
  2239. options->setNoRecover(true);
  2240. if(!req.getNosplit_isNull())
  2241. options->setNoSplit(req.getNosplit());
  2242. if(req.getMaxConnections() > 0)
  2243. options->setmaxConnections(req.getMaxConnections());
  2244. if(req.getThrottle() > 0)
  2245. options->setThrottle(req.getThrottle());
  2246. if(req.getTransferBufferSize() > 0)
  2247. options->setTransferBufferSize(req.getTransferBufferSize());
  2248. if (req.getPull())
  2249. options->setPull(true);
  2250. if (req.getPush())
  2251. options->setPush(true);
  2252. if (req.getIfnewer())
  2253. options->setIfNewer(true);
  2254. resp.setResult(wu->queryId());
  2255. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  2256. submitDFUWorkUnit(wu.getClear());
  2257. }
  2258. catch(IException* e)
  2259. {
  2260. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2261. }
  2262. return true;
  2263. }
  2264. bool CFileSprayEx::onRename(IEspContext &context, IEspRename &req, IEspRenameResponse &resp)
  2265. {
  2266. try
  2267. {
  2268. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Write, false))
  2269. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do Rename. Permission denied.");
  2270. const char* srcname = req.getSrcname();
  2271. const char* dstname = req.getDstname();
  2272. if(!srcname || !*srcname)
  2273. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Source logical file not specified.");
  2274. if(!dstname || !*dstname)
  2275. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Destination logical file not specified.");
  2276. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  2277. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  2278. StringBuffer destTitle;
  2279. ParseLogicalPath(req.getDstname(), destTitle);
  2280. wu->setJobName(destTitle.str());
  2281. wu->setQueue(m_QueueLabel.str());
  2282. StringBuffer user, passwd;
  2283. wu->setUser(context.getUserID(user).str());
  2284. wu->setPassword(context.getPassword(passwd).str());
  2285. wu->setCommand(DFUcmd_rename);
  2286. #if 0 // TBD - Handling for multiple clusters? the cluster should be specified by user if needed
  2287. Owned<IUserDescriptor> udesc;
  2288. if(user.length() > 0)
  2289. {
  2290. const char* passwd = context.queryPassword();
  2291. udesc.setown(createUserDescriptor());
  2292. udesc->set(user.str(), passwd);
  2293. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(srcname, udesc);
  2294. if(df)
  2295. {
  2296. StringBuffer cluster0;
  2297. df->getClusterName(0,cluster0); // TBD - Handling for multiple clusters?
  2298. if (cluster0.length()!=0)
  2299. {
  2300. wu->setClusterName(cluster0.str());
  2301. }
  2302. else
  2303. {
  2304. const char *cluster = df->queryAttributes().queryProp("@group");
  2305. if (cluster && *cluster)
  2306. {
  2307. wu->setClusterName(cluster);
  2308. }
  2309. }
  2310. }
  2311. }
  2312. #endif
  2313. IDFUfileSpec *source = wu->queryUpdateSource();
  2314. source->setLogicalName(srcname);
  2315. IDFUfileSpec *destination = wu->queryUpdateDestination();
  2316. destination->setLogicalName(dstname);
  2317. IDFUoptions *options = wu->queryUpdateOptions();
  2318. options->setOverwrite(req.getOverwrite());
  2319. resp.setWuid(wu->queryId());
  2320. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  2321. submitDFUWorkUnit(wu.getClear());
  2322. }
  2323. catch(IException* e)
  2324. {
  2325. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2326. }
  2327. return true;
  2328. }
  2329. bool CFileSprayEx::onDFUWUFile(IEspContext &context, IEspDFUWUFileRequest &req, IEspDFUWUFileResponse &resp)
  2330. {
  2331. try
  2332. {
  2333. if (!context.validateFeatureAccess(DFU_WU_URL, SecAccess_Read, false))
  2334. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to DFU workunit is denied.");
  2335. if (*req.getWuid())
  2336. {
  2337. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  2338. Owned<IConstDFUWorkUnit> wu = factory->openWorkUnit(req.getWuid(), false);
  2339. if(!wu)
  2340. throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT, "Dfu workunit %s not found.", req.getWuid());
  2341. StringBuffer xmlbuf;
  2342. xmlbuf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  2343. const char* plainText = req.getPlainText();
  2344. if (plainText && (!stricmp(plainText, "yes")))
  2345. {
  2346. wu->toXML(xmlbuf);
  2347. resp.setFile(xmlbuf.str());
  2348. resp.setFile_mimetype(HTTP_TYPE_TEXT_PLAIN);
  2349. }
  2350. else
  2351. {
  2352. xmlbuf.append("<?xml-stylesheet href=\"../esp/xslt/xmlformatter.xsl\" type=\"text/xsl\"?>");
  2353. wu->toXML(xmlbuf);
  2354. resp.setFile(xmlbuf.str());
  2355. resp.setFile_mimetype(HTTP_TYPE_APPLICATION_XML);
  2356. }
  2357. }
  2358. }
  2359. catch(IException* e)
  2360. {
  2361. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2362. }
  2363. return true;
  2364. }
  2365. int CFileSprayEx::doFileCheck(const char* mask, const char* netaddr, const char* osStr, const char* path)
  2366. {
  2367. int iRet = 1;
  2368. if (mask && *mask)
  2369. {
  2370. char *str = (char *) mask + strlen(mask) - 4;
  2371. if (!stricmp(str, ".cfg") || !stricmp(str, ".log"))
  2372. iRet = 0;
  2373. }
  2374. else if (netaddr && *netaddr && path && *path)
  2375. {
  2376. iRet = 2;
  2377. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  2378. factory->validateCache();
  2379. Owned<IConstEnvironment> env = factory->openEnvironmentByFile();
  2380. Owned<IPropertyTree> pEnvRoot = &env->getPTree();
  2381. IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree("Software");
  2382. Owned<IPropertyTree> pRoot = createPTreeFromXMLString("<Environment/>");
  2383. IPropertyTree* pSoftware = pRoot->addPropTree("Software", createPTree("Software"));
  2384. if (pEnvSoftware && pSoftware)
  2385. {
  2386. Owned<IPropertyTreeIterator> it = pEnvSoftware->getElements("DropZone");
  2387. ForEach(*it)
  2388. {
  2389. const char* pszComputer = it->query().queryProp("@computer");
  2390. if (!strcmp(pszComputer, "."))
  2391. pszComputer = "localhost";
  2392. StringBuffer xpath, sNetAddr;
  2393. xpath.appendf("Hardware/Computer[@name='%s']/@netAddress", pszComputer);
  2394. const char* pszNetAddr = pEnvRoot->queryProp(xpath.str());
  2395. if (strcmp(pszNetAddr, "."))
  2396. {
  2397. sNetAddr.append(pszNetAddr);
  2398. }
  2399. else
  2400. {
  2401. StringBuffer ipStr;
  2402. IpAddress ipaddr = queryHostIP();
  2403. ipaddr.getIpText(ipStr);
  2404. if (ipStr.length() > 0)
  2405. {
  2406. #ifdef MACHINE_IP
  2407. sNetAddr.append(MACHINE_IP);
  2408. #else
  2409. sNetAddr.append(ipStr.str());
  2410. #endif
  2411. }
  2412. }
  2413. #ifdef MACHINE_IP
  2414. if ((sNetAddr.length() > 0) && !stricmp(sNetAddr.str(), MACHINE_IP))
  2415. #else
  2416. if ((sNetAddr.length() > 0) && !stricmp(sNetAddr.str(), netaddr))
  2417. #endif
  2418. {
  2419. StringBuffer dir;
  2420. IPropertyTree* pDropZone = pSoftware->addPropTree("DropZone", &it->get());
  2421. pDropZone->getProp("@directory", dir);
  2422. if (osStr && *osStr)
  2423. {
  2424. int os = atoi(osStr);
  2425. const char pathSep = (os == OS_WINDOWS) ? '\\' : '/';
  2426. dir.replace(pathSep=='\\'?'/':'\\', pathSep);
  2427. }
  2428. if ((dir.length() > 0) && !strnicmp(path, dir.str(), dir.length()))
  2429. {
  2430. iRet = 0;
  2431. break;
  2432. }
  2433. }
  2434. }
  2435. }
  2436. }
  2437. return iRet;
  2438. }
  2439. bool CFileSprayEx::onFileList(IEspContext &context, IEspFileListRequest &req, IEspFileListResponse &resp)
  2440. {
  2441. try
  2442. {
  2443. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Read, false))
  2444. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do FileList. Permission denied.");
  2445. const char* path = req.getPath();
  2446. if (!path || !*path)
  2447. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Path not specified.");
  2448. const char* netaddr = req.getNetaddr();
  2449. const char* mask = req.getMask();
  2450. bool directoryOnly = req.getDirectoryOnly();
  2451. StringBuffer sPath(path);
  2452. const char* osStr = req.getOS();
  2453. if (osStr && *osStr)
  2454. {
  2455. int os = atoi(osStr);
  2456. const char pathSep = (os == OS_WINDOWS) ? '\\' : '/';
  2457. sPath.replace(pathSep=='\\'?'/':'\\', pathSep);
  2458. if (*(sPath.str() + sPath.length() -1) != pathSep)
  2459. sPath.append( pathSep );
  2460. }
  2461. int checkReturn = doFileCheck(mask, netaddr, osStr, sPath.str());
  2462. if (checkReturn > 1)
  2463. throw MakeStringException(ECLWATCH_DROP_ZONE_NOT_FOUND, "Dropzone is not found in the environment settings.");
  2464. else if (checkReturn > 0)
  2465. throw MakeStringException(ECLWATCH_ACCESS_TO_FILE_DENIED, "Access to the file path denied.");
  2466. RemoteFilename rfn;
  2467. SocketEndpoint ep;
  2468. #ifdef MACHINE_IP
  2469. ep.set(MACHINE_IP);
  2470. #else
  2471. ep.set(netaddr);
  2472. #endif
  2473. rfn.setPath(ep, sPath.str());
  2474. Owned<IFile> f = createIFile(rfn);
  2475. if(!f->isDirectory())
  2476. throw MakeStringException(ECLWATCH_INVALID_DIRECTORY, "%s is not a directory.", path);
  2477. IArrayOf<IEspPhysicalFileStruct> files;
  2478. if (mask && !*mask)
  2479. mask = NULL;
  2480. Owned<IDirectoryIterator> di = f->directoryFiles(NULL, false, true);
  2481. if(di.get() != NULL)
  2482. {
  2483. ForEach(*di)
  2484. {
  2485. StringBuffer fname;
  2486. di->getName(fname);
  2487. if (fname.length() == 0 || (directoryOnly && !di->isDir()) || (!di->isDir() && mask && !WildMatch(fname.str(), mask, true)))
  2488. continue;
  2489. Owned<IEspPhysicalFileStruct> onefile = createPhysicalFileStruct();
  2490. onefile->setName(fname.str());
  2491. onefile->setIsDir(di->isDir());
  2492. onefile->setFilesize(di->getFileSize());
  2493. CDateTime modtime;
  2494. StringBuffer timestr;
  2495. di->getModifiedTime(modtime);
  2496. unsigned y,m,d,h,min,sec,nsec;
  2497. modtime.getDate(y,m,d,true);
  2498. modtime.getTime(h,min,sec,nsec,true);
  2499. timestr.appendf("%04d-%02d-%02d %02d:%02d:%02d", y,m,d,h,min,sec);
  2500. onefile->setModifiedtime(timestr.str());
  2501. files.append(*onefile.getLink());
  2502. }
  2503. }
  2504. sPath.replace('\\', '/');//XSLT cannot handle backslashes
  2505. resp.setPath(sPath);
  2506. resp.setFiles(files);
  2507. resp.setNetaddr(netaddr);
  2508. if (osStr && *osStr)
  2509. {
  2510. int os = atoi(osStr);
  2511. resp.setOS(os);
  2512. }
  2513. if (mask && *mask)
  2514. resp.setMask(mask);
  2515. resp.setDirectoryOnly(directoryOnly);
  2516. }
  2517. catch(IException* e)
  2518. {
  2519. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2520. }
  2521. return true;
  2522. }
  2523. bool CFileSprayEx::onDfuMonitor(IEspContext &context, IEspDfuMonitorRequest &req, IEspDfuMonitorResponse &resp)
  2524. {
  2525. try
  2526. {
  2527. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Read, false))
  2528. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Failed to do DfuMonitor. Permission denied.");
  2529. Owned<IDFUWorkUnitFactory> factory = getDFUWorkUnitFactory();
  2530. Owned<IDFUWorkUnit> wu = factory->createWorkUnit();
  2531. wu->setQueue(m_MonitorQueueLabel.str());
  2532. StringBuffer user, passwd;
  2533. wu->setUser(context.getUserID(user).str());
  2534. wu->setPassword(context.getPassword(passwd).str());
  2535. wu->setCommand(DFUcmd_monitor);
  2536. IDFUmonitor *monitor = wu->queryUpdateMonitor();
  2537. IDFUfileSpec *source = wu->queryUpdateSource();
  2538. const char *eventname = req.getEventName();
  2539. const char *lname = req.getLogicalName();
  2540. if (lname&&*lname)
  2541. source->setLogicalName(lname);
  2542. else {
  2543. const char *ip = req.getIp();
  2544. const char *filename = req.getFilename();
  2545. if (filename&&*filename) {
  2546. RemoteFilename rfn;
  2547. if (ip&&*ip) {
  2548. SocketEndpoint ep;
  2549. ep.set(ip);
  2550. rfn.setPath(ep,filename);
  2551. }
  2552. else
  2553. rfn.setRemotePath(filename);
  2554. source->setSingleFilename(rfn);
  2555. }
  2556. else
  2557. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Neither logical name nor network ip/file specified for monitor.");
  2558. }
  2559. if (eventname)
  2560. monitor->setEventName(eventname);
  2561. monitor->setShotLimit(req.getShotLimit());
  2562. monitor->setSub(req.getSub());
  2563. resp.setWuid(wu->queryId());
  2564. resp.setRedirectUrl(StringBuffer("/FileSpray/GetDFUWorkunit?wuid=").append(wu->queryId()).str());
  2565. submitDFUWorkUnit(wu.getClear());
  2566. }
  2567. catch(IException* e)
  2568. {
  2569. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2570. }
  2571. return true;
  2572. }
  2573. bool CFileSprayEx::onOpenSave(IEspContext &context, IEspOpenSaveRequest &req, IEspOpenSaveResponse &resp)
  2574. {
  2575. try
  2576. {
  2577. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Read, false))
  2578. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Permission denied.");
  2579. const char* location = req.getLocation();
  2580. const char* path = req.getPath();
  2581. const char* name = req.getName();
  2582. const char* type = req.getType();
  2583. const char* dateTime = req.getDateTime();
  2584. if (location && *location)
  2585. resp.setLocation(location);
  2586. if (path && *path)
  2587. resp.setPath(path);
  2588. if (name && *name)
  2589. resp.setName(name);
  2590. if (type && *type)
  2591. resp.setType(type);
  2592. if (dateTime && *dateTime)
  2593. resp.setDateTime(dateTime);
  2594. if (req.getBinaryFile())
  2595. resp.setViewable(false);
  2596. }
  2597. catch(IException* e)
  2598. {
  2599. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2600. }
  2601. return true;
  2602. }
  2603. bool CFileSprayEx::getDropZoneFiles(IEspContext &context, const char* netaddr, const char* osStr, const char* path,
  2604. IEspDropZoneFilesRequest &req, IEspDropZoneFilesResponse &resp)
  2605. {
  2606. bool directoryOnly = req.getDirectoryOnly();
  2607. int checkReturn = doFileCheck(NULL, netaddr, osStr, path);
  2608. if (checkReturn > 1)
  2609. throw MakeStringException(ECLWATCH_DROP_ZONE_NOT_FOUND, "Dropzone is not found in the environment settings.");
  2610. else if (checkReturn > 0)
  2611. throw MakeStringException(ECLWATCH_ACCESS_TO_FILE_DENIED, "Access to the file path denied.");
  2612. RemoteFilename rfn;
  2613. SocketEndpoint ep;
  2614. #ifdef MACHINE_IP
  2615. ep.set(MACHINE_IP);
  2616. #else
  2617. ep.set(netaddr);
  2618. #endif
  2619. rfn.setPath(ep, path);
  2620. Owned<IFile> f = createIFile(rfn);
  2621. if(!f->isDirectory())
  2622. throw MakeStringException(ECLWATCH_INVALID_DIRECTORY, "%s is not a directory.", path);
  2623. IArrayOf<IEspPhysicalFileStruct> files;
  2624. Owned<IDirectoryIterator> di = f->directoryFiles(NULL, false, true);
  2625. if(di.get() != NULL)
  2626. {
  2627. ForEach(*di)
  2628. {
  2629. StringBuffer fname;
  2630. di->getName(fname);
  2631. if (fname.length() == 0 || (directoryOnly && !di->isDir()))
  2632. continue;
  2633. Owned<IEspPhysicalFileStruct> onefile = createPhysicalFileStruct();
  2634. onefile->setName(fname.str());
  2635. onefile->setIsDir(di->isDir());
  2636. onefile->setFilesize(di->getFileSize());
  2637. CDateTime modtime;
  2638. StringBuffer timestr;
  2639. di->getModifiedTime(modtime);
  2640. unsigned y,m,d,h,min,sec,nsec;
  2641. modtime.getDate(y,m,d,true);
  2642. modtime.getTime(h,min,sec,nsec,true);
  2643. timestr.appendf("%04d-%02d-%02d %02d:%02d:%02d", y,m,d,h,min,sec);
  2644. onefile->setModifiedtime(timestr.str());
  2645. files.append(*onefile.getLink());
  2646. }
  2647. }
  2648. resp.setFiles(files);
  2649. return true;
  2650. }
  2651. bool CFileSprayEx::onDropZoneFiles(IEspContext &context, IEspDropZoneFilesRequest &req, IEspDropZoneFilesResponse &resp)
  2652. {
  2653. try
  2654. {
  2655. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Read, false))
  2656. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Permission denied.");
  2657. const char* netAddress = req.getNetAddress();
  2658. const char* directory = req.getPath();
  2659. const char* subfolder = req.getSubfolder();
  2660. StringBuffer netAddressStr, directoryStr, osStr;
  2661. if (netAddress && *netAddress && directory && *directory)
  2662. {
  2663. netAddressStr.append(netAddress);
  2664. directoryStr.append(directory);
  2665. }
  2666. IArrayOf<IEspDropZone> dropZoneList;
  2667. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  2668. Owned<IConstEnvironment> m_constEnv = factory->openEnvironmentByFile();
  2669. Owned<IPropertyTree> pEnvRoot = &m_constEnv->getPTree();
  2670. IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree("Software");
  2671. if (pEnvSoftware)
  2672. {
  2673. Owned<IPropertyTreeIterator> it = pEnvSoftware->getElements("DropZone");
  2674. ForEach(*it)
  2675. {
  2676. IPropertyTree& pDropZone = it->query();
  2677. //get IP Address of the computer associated with this drop zone
  2678. const char* pszName = pDropZone.queryProp("@name");
  2679. const char* pszComputer = pDropZone.queryProp("@computer");
  2680. if (!strcmp(pszComputer, "."))
  2681. pszComputer = "localhost";
  2682. StringBuffer xpath;
  2683. xpath.appendf("Hardware/Computer[@name='%s']/@netAddress", pszComputer);
  2684. StringBuffer sNetAddr;
  2685. const char* pszNetAddr = pEnvRoot->queryProp(xpath.str());
  2686. if (strcmp(pszNetAddr, "."))
  2687. {
  2688. sNetAddr.append(pszNetAddr);
  2689. }
  2690. else
  2691. {
  2692. StringBuffer ipStr;
  2693. IpAddress ipaddr = queryHostIP();
  2694. ipaddr.getIpText(ipStr);
  2695. if (ipStr.length() > 0)
  2696. {
  2697. #ifdef MACHINE_IP
  2698. sNetAddr.append(MACHINE_IP);
  2699. #else
  2700. sNetAddr.append(ipStr.str());
  2701. #endif
  2702. }
  2703. }
  2704. Owned<IConstMachineInfo> machine;
  2705. if (strcmp(pszNetAddr, "."))
  2706. machine.setown(m_constEnv->getMachineByAddress(sNetAddr.str()));
  2707. else
  2708. {
  2709. machine.setown(m_constEnv->getMachineByAddress(pszNetAddr));
  2710. if (!machine)
  2711. machine.setown(m_constEnv->getMachineByAddress(sNetAddr.str()));
  2712. }
  2713. StringBuffer dir;
  2714. pDropZone.getProp("@directory", dir);
  2715. Owned<IEspDropZone> aDropZone= createDropZone("","");
  2716. if (machine)
  2717. {
  2718. if (machine->getOS() == MachineOsLinux || machine->getOS() == MachineOsSolaris)
  2719. {
  2720. dir.replace('\\', '/');//replace all '\\' by '/'
  2721. aDropZone->setLinux("true");
  2722. osStr = "1";
  2723. }
  2724. else
  2725. {
  2726. dir.replace('/', '\\');
  2727. dir.replace('$', ':');
  2728. osStr = "0";
  2729. }
  2730. }
  2731. aDropZone->setComputer(pszComputer);
  2732. aDropZone->setPath(dir.str());
  2733. aDropZone->setName(pszName);
  2734. aDropZone->setNetAddress(sNetAddr.str());
  2735. if (netAddressStr.length() < 1)
  2736. {
  2737. netAddressStr = sNetAddr;
  2738. directoryStr = dir;
  2739. }
  2740. dropZoneList.append(*aDropZone.getClear());
  2741. }
  2742. }
  2743. if (dropZoneList.ordinality())
  2744. resp.setDropZones(dropZoneList);
  2745. char pathSep = '/';
  2746. if (osStr && *osStr)
  2747. {
  2748. int os = atoi(osStr);
  2749. if (os == OS_WINDOWS)
  2750. pathSep = '\\';
  2751. }
  2752. directoryStr.replace(pathSep=='\\'?'/':'\\', pathSep);
  2753. if (subfolder && *subfolder)
  2754. {
  2755. if (*(directoryStr.str() + directoryStr.length() -1) != pathSep)
  2756. directoryStr.append( pathSep );
  2757. directoryStr.append(subfolder);
  2758. }
  2759. if (*(directoryStr.str() + directoryStr.length() -1) != pathSep)
  2760. directoryStr.append( pathSep );
  2761. getDropZoneFiles(context, netAddressStr.str(), osStr.str(), directoryStr.str(), req, resp);
  2762. if (pathSep=='\\')
  2763. directoryStr.replaceString("\\", "\\\\");
  2764. resp.setNetAddress(netAddressStr.str());
  2765. resp.setPath(directoryStr.str());
  2766. resp.setOS(atoi(osStr.str()));
  2767. }
  2768. catch(IException* e)
  2769. {
  2770. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2771. }
  2772. return true;
  2773. }
  2774. bool CFileSprayEx::onDeleteDropZoneFiles(IEspContext &context, IEspDeleteDropZoneFilesRequest &req, IEspDFUWorkunitsActionResponse &resp)
  2775. {
  2776. try
  2777. {
  2778. if (!context.validateFeatureAccess(FILE_SPRAY_URL, SecAccess_Full, false))
  2779. throw MakeStringException(ECLWATCH_FILE_SPRAY_ACCESS_DENIED, "Permission denied.");
  2780. const char* netAddress = req.getNetAddress();
  2781. const char* directory = req.getPath();
  2782. const char* osStr = req.getOS();
  2783. StringArray & files = req.getNames();
  2784. if (!netAddress || !*netAddress || !directory || !*directory)
  2785. throw MakeStringException(ECLWATCH_DROP_ZONE_NOT_FOUND, "Dropzone not specified.");
  2786. if (!files.ordinality())
  2787. throw MakeStringException(ECLWATCH_INVALID_INPUT, "File not specified.");
  2788. char pathSep = '/';
  2789. StringBuffer sPath(directory);
  2790. if (osStr && *osStr)
  2791. {
  2792. int os = atoi(osStr);
  2793. pathSep = (os == OS_WINDOWS) ? '\\' : '/';
  2794. sPath.replace(pathSep=='\\'?'/':'\\', pathSep);
  2795. if (*(sPath.str() + sPath.length() -1) != pathSep)
  2796. sPath.append( pathSep );
  2797. }
  2798. int checkReturn = doFileCheck(NULL, netAddress, osStr, sPath.str());
  2799. if (checkReturn > 1)
  2800. throw MakeStringException(ECLWATCH_DROP_ZONE_NOT_FOUND, "Dropzone is not found in the environment settings.");
  2801. else if (checkReturn > 0)
  2802. throw MakeStringException(ECLWATCH_ACCESS_TO_FILE_DENIED, "Access to the file path denied.");
  2803. RemoteFilename rfn;
  2804. SocketEndpoint ep;
  2805. #ifdef MACHINE_IP
  2806. ep.set(MACHINE_IP);
  2807. #else
  2808. ep.set(netAddress);
  2809. #endif
  2810. rfn.setPath(ep, sPath.str());
  2811. Owned<IFile> f = createIFile(rfn);
  2812. if(!f->isDirectory())
  2813. throw MakeStringException(ECLWATCH_INVALID_DIRECTORY, "%s is not a directory.", directory);
  2814. bool bAllSuccess = true;
  2815. IArrayOf<IEspDFUActionResult> results;
  2816. for(unsigned i = 0; i < files.ordinality(); ++i)
  2817. {
  2818. const char* file = files.item(i);
  2819. if (!file || !*file)
  2820. continue;
  2821. Owned<IEspDFUActionResult> res = createDFUActionResult("", "");
  2822. res->setID(files.item(i));
  2823. res->setAction("Delete");
  2824. res->setResult("Success");
  2825. try
  2826. {
  2827. StringBuffer fileToDelete = sPath;
  2828. if (*(fileToDelete.str() + fileToDelete.length() -1) != pathSep)
  2829. fileToDelete.append( pathSep );
  2830. fileToDelete.append(file);
  2831. rfn.setPath(ep, fileToDelete.str());
  2832. Owned<IFile> rFile = createIFile(rfn);
  2833. if (!rFile->exists())
  2834. res->setResult("Warning: this file does not exist.");
  2835. else
  2836. rFile->remove();
  2837. }
  2838. catch (IException *e)
  2839. {
  2840. bAllSuccess = false;
  2841. StringBuffer eMsg;
  2842. eMsg = e->errorMessage(eMsg);
  2843. e->Release();
  2844. StringBuffer failedMsg = "Failed: ";
  2845. failedMsg.append(eMsg);
  2846. res->setResult(failedMsg.str());
  2847. }
  2848. results.append(*res.getLink());
  2849. }
  2850. resp.setFirstColumn("File");
  2851. resp.setDFUActionResults(results);
  2852. }
  2853. catch(IException* e)
  2854. {
  2855. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2856. }
  2857. return true;
  2858. }