fileservices.cpp 148 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093
  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 : 4297) // function assumed not to throw an exception but does
  15. #include "platform.h"
  16. #include "fileservices.hpp"
  17. #include "workunit.hpp"
  18. #include "jio.hpp"
  19. #include "jmisc.hpp"
  20. #include "daft.hpp"
  21. #include "dasess.hpp"
  22. #include "dautils.hpp"
  23. #include "daaudit.hpp"
  24. #include "dfuwu.hpp"
  25. #include "ws_fs_esp.ipp"
  26. #include "rmtsmtp.hpp"
  27. #include "dfuplus.hpp"
  28. #include "daclient.hpp"
  29. #include "dasds.hpp"
  30. #include "enginecontext.hpp"
  31. #include "environment.hpp"
  32. #define USE_DALIDFS
  33. #define SDS_LOCK_TIMEOUT 10000
  34. #define FILESERVICES_VERSION "FILESERVICES 2.1.4"
  35. static const char * compatibleVersions[] = {
  36. "FILESERVICES 2.1 [a68789cfb01d00ef6dc362e52d5eac0e]", // linux version
  37. "FILESERVICES 2.1.1",
  38. "FILESERVICES 2.1.2",
  39. "FILESERVICES 2.1.3",
  40. "FILESERVICES 2.1.4",
  41. NULL };
  42. static const char * EclDefinition = nullptr;//Definitions specified in lib_fileservices.ecllib
  43. #define WAIT_SECONDS 30
  44. FILESERVICES_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
  45. {
  46. if (pb->size == sizeof(ECLPluginDefinitionBlockEx))
  47. {
  48. ECLPluginDefinitionBlockEx * pbx = (ECLPluginDefinitionBlockEx *) pb;
  49. pbx->compatibleVersions = compatibleVersions;
  50. }
  51. else if (pb->size != sizeof(ECLPluginDefinitionBlock))
  52. return false;
  53. pb->magicVersion = PLUGIN_VERSION;
  54. pb->version = FILESERVICES_VERSION;
  55. pb->moduleName = "lib_fileservices";
  56. pb->ECL = EclDefinition;
  57. pb->flags = PLUGIN_IMPLICIT_MODULE;
  58. pb->description = "FileServices library";
  59. return true;
  60. }
  61. namespace nsFileservices {
  62. IPluginContext * parentCtx = NULL;
  63. static IConstWorkUnit * getWorkunit(ICodeContext * ctx)
  64. {
  65. Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
  66. StringAttr wuid;
  67. wuid.setown(ctx->getWuid());
  68. return factory->openWorkUnit(wuid);
  69. }
  70. static void setWorkunitState(ICodeContext * ctx, WUState state, const char * msg)
  71. {
  72. Owned<IWorkUnit> wu = ctx->updateWorkUnit();
  73. if (wu)
  74. {
  75. wu->setState(state);//resets stateEx
  76. if (msg)
  77. wu->setStateEx(msg);
  78. wu->commit();
  79. }
  80. }
  81. #ifndef _CONTAINERIZED
  82. static IConstEnvironment * openDaliEnvironment()
  83. {
  84. if (daliClientActive())
  85. {
  86. Owned<IEnvironmentFactory> factory = getEnvironmentFactory(true);
  87. return factory->openEnvironment();
  88. }
  89. return NULL;
  90. }
  91. static IPropertyTree *getEnvironmentTree(IConstEnvironment * daliEnv)
  92. {
  93. if (daliEnv)
  94. return &daliEnv->getPTree(); // No need to clone since daliEnv ensures connection stays alive.
  95. return getHPCCEnvironment();
  96. }
  97. #endif
  98. static void setServerAccess(CClientFileSpray &server, IConstWorkUnit * wu)
  99. {
  100. SCMStringBuffer token;
  101. wu->getWorkunitDistributedAccessToken(token);
  102. server.setUsernameToken(wu->queryUser(), token.str(), "");//use workunit token as password
  103. }
  104. static StringArray availableWsFS;
  105. static CriticalSection espURLcrit;
  106. static void addConfiguredWsFSUrl(const char * url)
  107. {
  108. CriticalBlock b(espURLcrit);
  109. availableWsFS.appendUniq(url);
  110. }
  111. static void setContainerLocalCertificate(IEspClientRpcSettings &rpc)
  112. {
  113. #ifdef _CONTAINERIZED
  114. //will only affect HTTPS
  115. rpc.setMtlsSecretName("local");
  116. #endif
  117. }
  118. static bool contactWsFS(const char * espurl, IConstWorkUnit * wu)
  119. {
  120. CClientFileSpray server;
  121. server.addServiceUrl(espurl);
  122. setServerAccess(server, wu);
  123. try
  124. {
  125. Owned<IClientEchoDateTime> req = server.createEchoDateTimeRequest();
  126. setContainerLocalCertificate(req->rpc());
  127. Owned<IClientEchoDateTimeResponse> result = server.EchoDateTime(req);
  128. if (result->getResult())
  129. return true;
  130. }
  131. catch(IException *ie)
  132. {
  133. StringBuffer error;
  134. ie->errorMessage(error);
  135. PROGLOG("Could not contact WsFS: '%s': %s",espurl, error.str());
  136. ie->Release();
  137. }
  138. catch(...)
  139. {
  140. PROGLOG("Could not contact WsFS: '%s'",espurl);
  141. }
  142. return false;
  143. }
  144. static const char * getNextAliveWsFSURL(IConstWorkUnit * wu)
  145. {
  146. CriticalBlock b(espURLcrit);
  147. for (int index = 0; index < availableWsFS.length(); index++)
  148. {
  149. const char * currentUrl = availableWsFS.item(index);
  150. if (contactWsFS(currentUrl, wu))
  151. return currentUrl;
  152. }
  153. return nullptr;
  154. }
  155. static bool isUrlListEmpty()
  156. {
  157. CriticalBlock b(espURLcrit);
  158. return availableWsFS.length() == 0;
  159. }
  160. static const char *getAccessibleEspServerURL(const char *param, IConstWorkUnit * wu)
  161. {
  162. if (param&&*param)
  163. return param;
  164. CriticalBlock b(espURLcrit);
  165. if (isUrlListEmpty())
  166. {
  167. #ifdef _CONTAINERIZED
  168. // Look for 'eclservices' esp service, fallback to 'eclwatch' service.
  169. Owned<IPropertyTree> globalConfig = getGlobalConfig();
  170. Owned<IPropertyTreeIterator> iter = globalConfig->getElements("services");
  171. IPropertyTree * match = nullptr;
  172. ForEach(*iter)
  173. {
  174. IPropertyTree & cur = iter->query();
  175. //Ecl queries should be connecting to the internal service - not the public services.
  176. if (cur.getPropBool("@public"))
  177. continue;
  178. const char *type = cur.queryProp("@type");
  179. if (streq("eclservices", type))
  180. {
  181. match = &cur;
  182. break;
  183. }
  184. else if (streq("eclwatch", type))
  185. match = &cur;
  186. }
  187. if (match)
  188. {
  189. const char * espService = match->queryProp("@name");
  190. const char *protocol = match->getPropBool("@tls") ? "https" : "http";
  191. unsigned port = match->getPropInt("@port", 8010);
  192. VStringBuffer espURL("%s://%s:%u/FileSpray", protocol, espService, port);
  193. addConfiguredWsFSUrl(espURL.str());
  194. }
  195. #else
  196. Owned<IConstEnvironment> daliEnv = openDaliEnvironment();
  197. Owned<IPropertyTree> env = getEnvironmentTree(daliEnv);
  198. if (env.get())
  199. {
  200. StringBuffer wsFSUrl;
  201. StringBuffer espInstanceComputerName;
  202. StringBuffer bindingProtocol;
  203. StringBuffer xpath;
  204. StringBuffer instanceAddress;
  205. StringBuffer espServiceType;
  206. Owned<IPropertyTreeIterator> espProcessIter = env->getElements("Software/EspProcess");
  207. ForEach(*espProcessIter)
  208. {
  209. Owned<IPropertyTreeIterator> espBindingIter = espProcessIter->query().getElements("EspBinding");
  210. ForEach(*espBindingIter)
  211. {
  212. espBindingIter->query().getProp("@service",wsFSUrl.clear());
  213. xpath.setf("Software/EspService[@name=\"%s\"]/Properties/@type", wsFSUrl.str());
  214. if(env->getProp(xpath.str(), espServiceType.clear()))
  215. {
  216. if (!espServiceType.isEmpty() && (strieq(espServiceType.str(),"WsSMC")|| strieq(espServiceType.str(),"FileSpray_Serv")))
  217. {
  218. if (espBindingIter->query().getProp("@protocol",bindingProtocol.clear()))
  219. {
  220. Owned<IPropertyTreeIterator> espInstanceIter = espProcessIter->query().getElements("Instance");
  221. ForEach(*espInstanceIter)
  222. {
  223. if (espInstanceIter->query().getProp("@computer",espInstanceComputerName.clear()))
  224. {
  225. xpath.setf("Hardware/Computer[@name=\"%s\"]/@netAddress",espInstanceComputerName.str());
  226. if (env->getProp(xpath.str(),instanceAddress.clear()))
  227. {
  228. wsFSUrl.setf("%s://%s:%d/FileSpray", bindingProtocol.str(), instanceAddress.str(), espBindingIter->query().getPropInt("@port",8010)); // FileSpray seems to be fixed
  229. addConfiguredWsFSUrl(wsFSUrl.str());
  230. }
  231. }
  232. }
  233. }
  234. }//EclWatch || ws_fs binding
  235. }
  236. }//ESPBinding
  237. }//ESPProcess
  238. }
  239. #endif
  240. if (isUrlListEmpty())
  241. throw MakeStringException(-1,"Could not find any WS FileSpray in the target HPCC configuration.");
  242. }
  243. const char * nextWsFSUrl = getNextAliveWsFSURL(wu);
  244. if (!nextWsFSUrl||!*nextWsFSUrl)
  245. throw MakeStringException(-1,"Could not contact any of the configured WS FileSpray instances, check HPCC configuration and system health.");
  246. PROGLOG("FileServices: Targeting ESP WsFileSpray URL: %s", nextWsFSUrl);
  247. return nextWsFSUrl;
  248. }
  249. StringBuffer & constructLogicalName(IConstWorkUnit * wu, const char * partialLogicalName, StringBuffer & result)
  250. {
  251. if (partialLogicalName == NULL)
  252. throw MakeStringException(0, "Logical Name Cannot be blank");
  253. if (*partialLogicalName == '~')
  254. ++partialLogicalName;
  255. else if (wu)
  256. {
  257. StringBuffer prefix;
  258. wu->getScope(StringBufferAdaptor(prefix));
  259. if (prefix.length())
  260. result.append(prefix).append("::");
  261. }
  262. result.append(partialLogicalName);
  263. if ((result.length()>0)&&(strstr(result.str(),"::")==NULL)&&(result.charAt(0)!='#'))
  264. result.insert(0,".::");
  265. return result;
  266. }
  267. StringBuffer & constructLogicalName(ICodeContext * ctx, const char * partialLogicalName, StringBuffer & result)
  268. {
  269. Owned<IConstWorkUnit> wu;
  270. if (partialLogicalName&&(*partialLogicalName != '~'))
  271. wu.setown(getWorkunit(ctx));
  272. return constructLogicalName(wu, partialLogicalName, result);
  273. }
  274. static void WUmessage(ICodeContext *ctx, ErrorSeverity sev, const char *fn, const char *msg)
  275. {
  276. StringBuffer s("fileservices");
  277. if (fn)
  278. s.append(", ").append(fn);
  279. ctx->addWuExceptionEx(msg, 0, sev, MSGAUD_audit, s.str()); // use plain code context
  280. return;
  281. }
  282. static void AuditMessage(ICodeContext *ctx,
  283. const char *func,
  284. const char *lfn1,
  285. const char *lfn2=NULL)
  286. {
  287. // FileServices,WUID,user,function,LFN1,LFN2
  288. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  289. StringBuffer aln;
  290. StringAttr wuid;
  291. wuid.setown(ctx->getWuid());
  292. aln.append(",FileAccess,FileServices,").append(func).append(',').append(wuid).append(',');
  293. if (udesc)
  294. udesc->getUserName(aln);
  295. if (lfn1&&*lfn1) {
  296. aln.append(',').append(lfn1);
  297. if (lfn2&&*lfn2) {
  298. aln.append(',').append(lfn2);
  299. }
  300. }
  301. LOG(MCauditInfo,"%s",aln.str());
  302. }
  303. }//namespace
  304. using namespace nsFileservices;
  305. FILESERVICES_API void setPluginContext(IPluginContext * _ctx) { parentCtx = _ctx; }
  306. FILESERVICES_API char * FILESERVICES_CALL fsGetBuildInfo(void)
  307. {
  308. return CTXSTRDUP(parentCtx, FILESERVICES_VERSION);
  309. }
  310. //-------------------------------------------------------------------------------------------------------------------------------------------
  311. FILESERVICES_API void FILESERVICES_CALL fsDeleteLogicalFile(ICodeContext *ctx, const char *name,bool ifexists)
  312. {
  313. StringBuffer lfn;
  314. constructLogicalName(ctx, name, lfn);
  315. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  316. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  317. StringBuffer uname;
  318. DBGLOG("Deleting NS logical file %s for user %s", lfn.str(),udesc?udesc->getUserName(uname).str():"");
  319. if (queryDistributedFileDirectory().removeEntry(lfn.str(),udesc,transaction, INFINITE, true))
  320. {
  321. StringBuffer s("DeleteLogicalFile ('");
  322. s.append(lfn);
  323. if (transaction->active())
  324. s.append("') added to transaction");
  325. else
  326. s.append("') done");
  327. WUmessage(ctx,SeverityInformation,NULL,s.str());
  328. AuditMessage(ctx,"DeleteLogicalFile",lfn.str());
  329. }
  330. else if (!ifexists)
  331. {
  332. throw MakeStringException(0, "Could not delete file %s", lfn.str());
  333. }
  334. }
  335. FILESERVICES_API bool FILESERVICES_CALL fsFileExists(ICodeContext *ctx, const char *name, bool physical)
  336. {
  337. StringBuffer lfn;
  338. constructLogicalName(ctx, name, lfn);
  339. if (physical)
  340. return queryDistributedFileDirectory().existsPhysical(lfn.str(),ctx->queryUserDescriptor());
  341. return queryDistributedFileDirectory().exists(lfn.str(),ctx->queryUserDescriptor(),false,false);
  342. }
  343. FILESERVICES_API bool FILESERVICES_CALL fsFileValidate(ICodeContext *ctx, const char *name)
  344. {
  345. StringBuffer lfn;
  346. constructLogicalName(ctx, name, lfn);
  347. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  348. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead, false, false, nullptr, defaultPrivilegedUser);
  349. if (df)
  350. {
  351. Owned<IDistributedFilePartIterator> partIter = df->getIterator();
  352. ForEach(*partIter)
  353. {
  354. IDistributedFilePart & part = partIter->query();
  355. unsigned numCopies = part.numCopies();
  356. bool gotone = false;
  357. offset_t partSize = (offset_t)-1;
  358. for (unsigned copy=0; copy < numCopies; copy++)
  359. {
  360. RemoteFilename remote;
  361. part.getFilename(remote,copy);
  362. OwnedIFile file = createIFile(remote);
  363. if (file->exists())
  364. {
  365. offset_t thisSize = file->size();
  366. if (gotone && (partSize != thisSize))
  367. throw MakeStringException(0, "Inconsistent file sizes for %s", lfn.str());
  368. partSize = thisSize;
  369. gotone = true;
  370. }
  371. }
  372. if (!gotone)
  373. return false;
  374. }
  375. return true;
  376. }
  377. return false;
  378. }
  379. FILESERVICES_API void FILESERVICES_CALL fsSetReadOnly(ICodeContext *ctx, const char *name, bool ro)
  380. {
  381. StringBuffer lfn;
  382. constructLogicalName(ctx, name, lfn);
  383. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  384. Owned<IException> error;
  385. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdWrite, false, false, nullptr, defaultPrivilegedUser);
  386. if (df)
  387. {
  388. LOG(MCauditInfo, "Set ReadOnly: %s", name);
  389. Owned<IDistributedFilePartIterator> partIter = df->getIterator();
  390. ForEach(*partIter)
  391. {
  392. IDistributedFilePart & part = partIter->query();
  393. unsigned numCopies = part.numCopies();
  394. for (unsigned copy=0; copy < numCopies; copy++)
  395. {
  396. RemoteFilename remote;
  397. part.getFilename(remote,copy);
  398. OwnedIFile file = createIFile(remote);
  399. try
  400. {
  401. file->setReadOnly(ro);
  402. }
  403. catch (IException * e)
  404. {
  405. EXCLOG(e);
  406. e->Release();
  407. }
  408. }
  409. }
  410. return;
  411. }
  412. if (!error)
  413. error.setown(MakeStringException(0, "Could not find logical file %s", lfn.str()));
  414. throw error.getClear();
  415. }
  416. FILESERVICES_API void FILESERVICES_CALL implementRenameLogicalFile(ICodeContext *ctx, const char *oldname, const char *newname, const bool overwrite)
  417. {
  418. StringBuffer oldLfn, newLfn;
  419. constructLogicalName(ctx, oldname, oldLfn);
  420. constructLogicalName(ctx, newname, newLfn);
  421. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  422. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  423. IDistributedFileDirectory &distributedDirectory = queryDistributedFileDirectory();
  424. if (!distributedDirectory.exists(oldLfn.str(), udesc, false, false))
  425. throw MakeStringException(0, "Old file %s doesn't exists.", oldLfn.str());
  426. if (overwrite && distributedDirectory.exists(newLfn.str(), udesc, false, false))
  427. fsDeleteLogicalFile(ctx, newname, true);
  428. try {
  429. distributedDirectory.renamePhysical(oldLfn.str(), newLfn.str(), udesc, transaction);
  430. StringBuffer s("RenameLogicalFile ('");
  431. s.append(oldLfn).append(", '").append(newLfn).append("') done");
  432. WUmessage(ctx, SeverityInformation, NULL, s.str());
  433. AuditMessage(ctx, "RenameLogicalFile", oldLfn.str(), newLfn.str());
  434. }
  435. catch (IException *e)
  436. {
  437. StringBuffer s;
  438. e->errorMessage(s);
  439. WUmessage(ctx, SeverityWarning, "RenameLogicalFile", s.str());
  440. throw e;
  441. }
  442. }
  443. FILESERVICES_API void FILESERVICES_CALL fsRenameLogicalFile(ICodeContext *ctx, const char *oldname, const char *newname)
  444. {
  445. implementRenameLogicalFile(ctx, oldname, newname, false);
  446. }
  447. FILESERVICES_API void FILESERVICES_CALL fsRenameLogicalFile_v2(ICodeContext *ctx, const char *oldname, const char *newname, const bool overwrite)
  448. {
  449. implementRenameLogicalFile(ctx, oldname, newname, overwrite);
  450. }
  451. FILESERVICES_API void FILESERVICES_CALL fsSendEmail_v2(ICodeContext * ctx, const char * to, const char * subject, const char * body, const char * mailServer, unsigned port, const char * sender, const char *cc, const char *bcc, bool highPriority)
  452. {
  453. StringArray warnings;
  454. sendEmail( to, cc, bcc, subject, body, mailServer, port, sender, &warnings, highPriority);
  455. ForEachItemIn(i,warnings)
  456. WUmessage(ctx, SeverityWarning, "SendEmail", warnings.item(i));
  457. }
  458. FILESERVICES_API void FILESERVICES_CALL fsSendEmail(ICodeContext * ctx, const char * to, const char * subject, const char * body, const char * mailServer, unsigned port, const char * sender)
  459. {
  460. fsSendEmail_v2(ctx, to, subject, body, mailServer, port, sender, nullptr, nullptr, false);
  461. }
  462. FILESERVICES_API void FILESERVICES_CALL fsSendEmailAttachText_v2(ICodeContext * ctx, const char * to, const char * subject, const char * body, const char * attachment, const char * mimeType, const char * attachmentName, const char * mailServer, unsigned int port, const char * sender, const char *cc, const char *bcc, bool highPriority)
  463. {
  464. StringArray warnings;
  465. sendEmailAttachText(to, cc, bcc, subject, body, attachment, mimeType, attachmentName, mailServer, port, sender, &warnings, highPriority);
  466. ForEachItemIn(i,warnings)
  467. WUmessage(ctx, SeverityWarning, "SendEmailAttachText", warnings.item(i));
  468. }
  469. FILESERVICES_API void FILESERVICES_CALL fsSendEmailAttachText(ICodeContext * ctx, const char * to, const char * subject, const char * body, const char * attachment, const char * mimeType, const char * attachmentName, const char * mailServer, unsigned int port, const char * sender)
  470. {
  471. fsSendEmailAttachText_v2(ctx, to, subject, body, attachment, mimeType, attachmentName, mailServer, port, sender, nullptr, nullptr, false);
  472. }
  473. FILESERVICES_API void FILESERVICES_CALL fsSendEmailAttachData_v2(ICodeContext * ctx, const char * to, const char * subject, const char * body, size32_t lenAttachment, const void * attachment, const char * mimeType, const char * attachmentName, const char * mailServer, unsigned int port, const char * sender, const char *cc, const char *bcc, bool highPriority)
  474. {
  475. StringArray warnings;
  476. sendEmailAttachData(to, cc, bcc, subject, body, lenAttachment, attachment, mimeType, attachmentName, mailServer, port, sender, &warnings, highPriority);
  477. ForEachItemIn(i,warnings)
  478. WUmessage(ctx, SeverityWarning, "SendEmailAttachData", warnings.item(i));
  479. }
  480. FILESERVICES_API void FILESERVICES_CALL fsSendEmailAttachData(ICodeContext * ctx, const char * to, const char * subject, const char * body, size32_t lenAttachment, const void * attachment, const char * mimeType, const char * attachmentName, const char * mailServer, unsigned int port, const char * sender)
  481. {
  482. fsSendEmailAttachData_v2(ctx, to, subject, body, lenAttachment, attachment, mimeType, attachmentName, mailServer, port, sender, nullptr, nullptr, false);
  483. }
  484. FILESERVICES_API char * FILESERVICES_CALL fsCmdProcess(const char *prog, const char *src)
  485. {
  486. throw makeStringException(0, "CmdProcess no longer supported for security reasons");
  487. }
  488. FILESERVICES_API void FILESERVICES_CALL fsCmdProcess2(unsigned & tgtLen, char * & tgt, const char *prog, unsigned srcLen, const char * src)
  489. {
  490. throw makeStringException(0, "CmdProcess no longer supported for security reasons");
  491. }
  492. static void blockUntilComplete(const char * label, IClientFileSpray &server, ICodeContext *ctx, const char * wuid, int timeOut, StringBuffer *stateout=NULL, bool monitoringok=false)
  493. {
  494. if (!wuid || strcmp(wuid, "") == 0)
  495. return;
  496. if (timeOut == 0)
  497. return;
  498. CTimeMon time(timeOut);
  499. unsigned polltime = 1;
  500. VStringBuffer reason("Blocked by fileservice activity: %s",label);
  501. setWorkunitState(ctx, WUStateBlocked, reason.str());
  502. while(true)
  503. {
  504. Owned<IClientGetDFUWorkunit> req = server.createGetDFUWorkunitRequest();
  505. setContainerLocalCertificate(req->rpc());
  506. req->setWuid(wuid);
  507. Owned<IClientGetDFUWorkunitResponse> result = server.GetDFUWorkunit(req);
  508. const IMultiException* excep = &result->getExceptions();
  509. if ((excep != NULL) && (excep->ordinality() > 0))
  510. {
  511. setWorkunitState(ctx, WUStateRunning, NULL);
  512. StringBuffer errmsg;
  513. excep->errorMessage(errmsg);
  514. throw MakeStringExceptionDirect(0, errmsg.str());
  515. }
  516. IConstDFUWorkunit & dfuwu = result->getResult();
  517. bool aborting = false;
  518. Owned<IWorkUnit> wu = ctx->updateWorkUnit(); // may return NULL
  519. if (wu.get()) { // if updatable (e.g. not hthor with no agent context)
  520. aborting = wu->aborting();
  521. StringBuffer wuScope, ElapsedLabel, RemainingLabel;
  522. wuScope.appendf("%s-%s", label, dfuwu.getID());
  523. ElapsedLabel.append(wuScope).append(" (Elapsed) ");
  524. RemainingLabel.append(wuScope).append(" (Remaining) ");
  525. //MORE: I think this are intended to replace the timing information, but will currently combine
  526. updateWorkunitStat(wu, SSTdfuworkunit, wuScope, StTimeElapsed, ElapsedLabel, milliToNano(time.elapsed()));
  527. updateWorkunitStat(wu, SSTdfuworkunit, wuScope, StTimeRemaining, RemainingLabel, milliToNano(dfuwu.getSecsLeft()*1000));
  528. stat_type costFileAccess = money2cost_type(dfuwu.getFileAccessCost());
  529. updateWorkunitStat(wu, SSTdfuworkunit, wuScope, StCostFileAccess, "", costFileAccess);
  530. wu->setApplicationValue(label, dfuwu.getID(), dfuwu.getSummaryMessage(), true);
  531. wu->commit();
  532. wu.clear();
  533. }
  534. DFUstate state = (DFUstate)dfuwu.getState();
  535. if (stateout)
  536. stateout->clear().append(dfuwu.getStateMessage());
  537. switch(state)
  538. {
  539. case DFUstate_unknown:
  540. case DFUstate_scheduled:
  541. case DFUstate_queued:
  542. case DFUstate_started:
  543. case DFUstate_aborting:
  544. break;
  545. case DFUstate_monitoring:
  546. if (monitoringok)
  547. {
  548. setWorkunitState(ctx, WUStateRunning, NULL);
  549. return;
  550. }
  551. break;
  552. case DFUstate_aborted:
  553. case DFUstate_failed:
  554. setWorkunitState(ctx, WUStateRunning, NULL);
  555. throw MakeStringException(0, "DFUServer Error %s", dfuwu.getSummaryMessage());
  556. case DFUstate_finished:
  557. setWorkunitState(ctx, WUStateRunning, NULL);
  558. return;
  559. }
  560. if (aborting)
  561. {
  562. Owned<IClientAbortDFUWorkunit> abortReq = server.createAbortDFUWorkunitRequest();
  563. setContainerLocalCertificate(abortReq->rpc());
  564. abortReq->setWuid(wuid);
  565. Linked<IClientAbortDFUWorkunitResponse> abortResp = server.AbortDFUWorkunit(abortReq);
  566. setWorkunitState(ctx, WUStateRunning, NULL);
  567. // Add warning of DFU Abort Request - should this be information ---
  568. StringBuffer s("DFU Workunit Abort Requested for ");
  569. s.append(wuid);
  570. WUmessage(ctx,SeverityWarning,"blockUntilComplete",s.str());
  571. throw MakeStringException(0, "Workunit abort request received");
  572. }
  573. if (time.timedout()) {
  574. unsigned left = dfuwu.getSecsLeft();
  575. setWorkunitState(ctx, WUStateRunning, NULL);
  576. if (left)
  577. throw MakeStringException(0, "%s timed out, DFU Secs left: %d)", label, left);
  578. throw MakeStringException(0, "%s timed out)", label);
  579. }
  580. Sleep(polltime*1000);
  581. polltime *= 2;
  582. if (polltime>WAIT_SECONDS)
  583. polltime = WAIT_SECONDS;
  584. }
  585. setWorkunitState(ctx, WUStateRunning, NULL);
  586. }
  587. //----------------------------------------------------------------------------------
  588. FILESERVICES_API char * FILESERVICES_CALL implementSprayFixed(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane = nullptr, unsigned destinationNumParts = 0)
  589. {
  590. LOG(MCauditInfo, "Spray: %s", destinationLogicalName);
  591. CClientFileSpray server;
  592. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  593. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort, wu));
  594. setServerAccess(server, wu);
  595. Owned<IClientSprayFixed> req = server.createSprayFixedRequest();
  596. setContainerLocalCertificate(req->rpc());
  597. StringBuffer logicalName;
  598. constructLogicalName(wu, destinationLogicalName, logicalName);
  599. req->setSourceIP(sourceIP);
  600. req->setSourcePath(sourcePath);
  601. req->setSourcePlane(sourcePlane);
  602. req->setSourceRecordSize(recordSize);
  603. req->setDestGroup(destinationGroup);
  604. req->setDestLogicalName(logicalName.str());
  605. req->setOverwrite(overwrite);
  606. req->setReplicate(replicate);
  607. req->setCompress(compress);
  608. if (maxConnections != -1)
  609. req->setMaxConnections(maxConnections);
  610. if (failIfNoSourceFile)
  611. req->setFailIfNoSourceFile(true);
  612. req->setExpireDays(expireDays);
  613. if (!isEmptyString(dfuServerQueue))
  614. req->setDFUServerQueue(dfuServerQueue);
  615. if (noSplit)
  616. req->setNosplit(true);
  617. Owned<IClientSprayFixedResponse> result = server.SprayFixed(req);
  618. StringBuffer wuid(result->getWuid());
  619. if (!wuid.length())
  620. {
  621. const IMultiException* excep = &result->getExceptions();
  622. if ((excep != NULL) && (excep->ordinality() > 0))
  623. {
  624. StringBuffer errmsg;
  625. excep->errorMessage(errmsg);
  626. throw MakeStringExceptionDirect(0, errmsg.str());
  627. }
  628. else
  629. {
  630. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  631. }
  632. }
  633. wu.clear();
  634. blockUntilComplete("Spray", server, ctx, wuid, timeOut);
  635. return wuid.detach();
  636. }
  637. FILESERVICES_API void FILESERVICES_CALL fsSprayFixed(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile)
  638. {
  639. CTXFREE(parentCtx, implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, -1, nullptr, false));
  640. }
  641. FILESERVICES_API void FILESERVICES_CALL fsSprayFixed_v2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays)
  642. {
  643. CTXFREE(parentCtx, implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, nullptr, false));
  644. }
  645. FILESERVICES_API void FILESERVICES_CALL fsSprayFixed_v3(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue)
  646. {
  647. CTXFREE(parentCtx, implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, false));
  648. }
  649. FILESERVICES_API void FILESERVICES_CALL fsSprayFixed_v4(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit)
  650. {
  651. CTXFREE(parentCtx, implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit));
  652. }
  653. FILESERVICES_API void FILESERVICES_CALL fsSprayFixed_v5(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts)
  654. {
  655. CTXFREE(parentCtx, implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, sourcePlane, destinationNumParts));
  656. }
  657. FILESERVICES_API char * FILESERVICES_CALL fsfSprayFixed(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile)
  658. {
  659. return implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, -1, nullptr, false);
  660. }
  661. FILESERVICES_API char * FILESERVICES_CALL fsfSprayFixed_v2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays)
  662. {
  663. return implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, nullptr, false);
  664. }
  665. FILESERVICES_API char * FILESERVICES_CALL fsfSprayFixed_v3(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue)
  666. {
  667. return implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, false);
  668. }
  669. FILESERVICES_API char * FILESERVICES_CALL fsfSprayFixed_v4(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit)
  670. {
  671. return implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit);
  672. }
  673. FILESERVICES_API char * FILESERVICES_CALL fsfSprayFixed_v5(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int recordSize, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts)
  674. {
  675. return implementSprayFixed(ctx, sourceIP, sourcePath, recordSize, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, sourcePlane, destinationNumParts);
  676. }
  677. //----------------------------------------------------------------------------------
  678. static char * implementSprayVariable(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * sourceCsvEscape, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane = nullptr, unsigned destinationNumParts = 0)
  679. {
  680. LOG(MCauditInfo, "Spray: %s", destinationLogicalName);
  681. CClientFileSpray server;
  682. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  683. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  684. setServerAccess(server, wu);
  685. Owned<IClientSprayVariable> req = server.createSprayVariableRequest();
  686. setContainerLocalCertificate(req->rpc());
  687. StringBuffer logicalName;
  688. constructLogicalName(wu, destinationLogicalName, logicalName);
  689. req->setSourceIP(sourceIP);
  690. req->setSourcePath(sourcePath);
  691. req->setSourcePlane(sourcePlane);
  692. req->setSourceMaxRecordSize(sourceMaxRecordSize);
  693. req->setSourceFormat(CDFUfileformat::decode(encoding));
  694. req->setSourceCsvSeparate(sourceCsvSeparate);
  695. if (sourceCsvSeparate && *sourceCsvSeparate == '\0')
  696. req->setNoSourceCsvSeparator(true);
  697. req->setSourceCsvTerminate(sourceCsvTerminate);
  698. req->setSourceCsvQuote(sourceCsvQuote);
  699. if (sourceCsvEscape && *sourceCsvEscape)
  700. req->setSourceCsvEscape(sourceCsvEscape);
  701. req->setDestGroup(destinationGroup);
  702. req->setDestLogicalName(logicalName.str());
  703. req->setOverwrite(overwrite);
  704. req->setReplicate(replicate);
  705. req->setCompress(compress);
  706. if (maxConnections != -1)
  707. req->setMaxConnections(maxConnections);
  708. if (failIfNoSourceFile)
  709. req->setFailIfNoSourceFile(true);
  710. if (recordStructurePresent)
  711. req->setRecordStructurePresent(true);
  712. if (!quotedTerminator)
  713. req->setQuotedTerminator(false);
  714. req->setExpireDays(expireDays);
  715. if (!isEmptyString(dfuServerQueue))
  716. req->setDFUServerQueue(dfuServerQueue);
  717. if (noSplit)
  718. req->setNosplit(true);
  719. Owned<IClientSprayResponse> result = server.SprayVariable(req);
  720. StringBuffer wuid(result->getWuid());
  721. if (!wuid.length())
  722. {
  723. const IMultiException* excep = &result->getExceptions();
  724. if ((excep != NULL) && (excep->ordinality() > 0))
  725. {
  726. StringBuffer errmsg;
  727. excep->errorMessage(errmsg);
  728. throw MakeStringExceptionDirect(0, errmsg.str());
  729. }
  730. else
  731. {
  732. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  733. }
  734. }
  735. wu.clear();
  736. blockUntilComplete("Spray", server, ctx, wuid, timeOut);
  737. return wuid.detach();
  738. }
  739. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile)
  740. {
  741. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, NULL, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, false, true, "ascii", -1, nullptr, false));
  742. }
  743. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile)
  744. {
  745. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, NULL, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, false, true, "ascii", -1, nullptr, false);
  746. }
  747. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile)
  748. {
  749. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, false, true, "ascii", -1, nullptr, false));
  750. }
  751. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile)
  752. {
  753. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, false, true, "ascii", -1, nullptr, false);
  754. }
  755. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v3(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent)
  756. {
  757. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, true, "ascii", -1, nullptr, false));
  758. }
  759. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v3(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent)
  760. {
  761. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, true, "ascii", -1, nullptr, false);
  762. }
  763. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v4(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator)
  764. {
  765. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, "ascii", -1, nullptr, false));
  766. }
  767. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v4(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator)
  768. {
  769. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, "ascii", -1, nullptr, false);
  770. }
  771. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v5(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding)
  772. {
  773. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, -1, nullptr, false));
  774. }
  775. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v5(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding)
  776. {
  777. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, -1, nullptr, false);
  778. }
  779. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v6(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays)
  780. {
  781. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, nullptr, false));
  782. }
  783. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v6(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays)
  784. {
  785. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, nullptr, false);
  786. }
  787. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v7(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue)
  788. {
  789. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, dfuServerQueue, false));
  790. }
  791. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v7(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue)
  792. {
  793. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, dfuServerQueue, false);
  794. }
  795. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v8(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue, bool noSplit)
  796. {
  797. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, dfuServerQueue, noSplit));
  798. }
  799. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v8(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue, bool noSplit)
  800. {
  801. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, dfuServerQueue, noSplit);
  802. }
  803. FILESERVICES_API void FILESERVICES_CALL fsSprayVariable_v9(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts)
  804. {
  805. CTXFREE(parentCtx, implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, dfuServerQueue, noSplit, sourcePlane, destinationNumParts));
  806. }
  807. FILESERVICES_API char * FILESERVICES_CALL fsfSprayVariable_v9(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char * sourceCsvSeparate, const char * sourceCsvTerminate, const char * sourceCsvQuote, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, const char * csvEscape, bool failIfNoSourceFile, bool recordStructurePresent, bool quotedTerminator, const char * encoding, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts)
  808. {
  809. return implementSprayVariable(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceCsvSeparate, sourceCsvTerminate, sourceCsvQuote, csvEscape, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, recordStructurePresent, quotedTerminator, encoding, expireDays, dfuServerQueue, noSplit, sourcePlane, destinationNumParts);
  810. }
  811. //----------------------------------------------------------------------------------
  812. FILESERVICES_API char * FILESERVICES_CALL implementSprayXml(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts=0)
  813. {
  814. LOG(MCauditInfo, "Spray: %s", destinationLogicalName);
  815. CClientFileSpray server;
  816. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  817. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  818. setServerAccess(server, wu);
  819. Owned<IClientSprayVariable> req = server.createSprayVariableRequest();
  820. setContainerLocalCertificate(req->rpc());
  821. StringBuffer logicalName;
  822. constructLogicalName(wu, destinationLogicalName, logicalName);
  823. DFUfileformat dfufmt;
  824. if (sourceEncoding == NULL)
  825. dfufmt = DFUff_utf8;
  826. else
  827. dfufmt = CDFUfileformat::decode(sourceEncoding);
  828. req->setSourceIP(sourceIP);
  829. req->setSourcePath(sourcePath);
  830. req->setSourcePlane(sourcePlane);
  831. req->setSourceMaxRecordSize(sourceMaxRecordSize);
  832. req->setSourceFormat(dfufmt);
  833. req->setSourceRowTag(sourceRowTag);
  834. req->setDestGroup(destinationGroup);
  835. req->setDestLogicalName(logicalName.str());
  836. req->setOverwrite(overwrite);
  837. req->setReplicate(replicate);
  838. req->setCompress(compress);
  839. if (maxConnections != -1)
  840. req->setMaxConnections(maxConnections);
  841. if (failIfNoSourceFile)
  842. req->setFailIfNoSourceFile(true);
  843. req->setExpireDays(expireDays);
  844. if (!isEmptyString(dfuServerQueue))
  845. req->setDFUServerQueue(dfuServerQueue);
  846. if (noSplit)
  847. req->setNosplit(true);
  848. Owned<IClientSprayResponse> result = server.SprayVariable(req);
  849. StringBuffer wuid(result->getWuid());
  850. if (!wuid.length())
  851. {
  852. const IMultiException* excep = &result->getExceptions();
  853. if ((excep != NULL) && (excep->ordinality() > 0))
  854. {
  855. StringBuffer errmsg;
  856. excep->errorMessage(errmsg);
  857. throw MakeStringExceptionDirect(0, errmsg.str());
  858. }
  859. else
  860. {
  861. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  862. }
  863. }
  864. wu.clear();
  865. blockUntilComplete("Spray", server, ctx, wuid, timeOut);
  866. return wuid.detach();
  867. }
  868. FILESERVICES_API void FILESERVICES_CALL fsSprayXml(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile)
  869. {
  870. CTXFREE(parentCtx, implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, -1, nullptr, false, nullptr));
  871. }
  872. FILESERVICES_API void FILESERVICES_CALL fsSprayXml_v2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays)
  873. {
  874. CTXFREE(parentCtx, implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, nullptr, false, nullptr));
  875. }
  876. FILESERVICES_API void FILESERVICES_CALL fsSprayXml_v3(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue)
  877. {
  878. CTXFREE(parentCtx, implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, false, nullptr));
  879. }
  880. FILESERVICES_API void FILESERVICES_CALL fsSprayXml_v4(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit)
  881. {
  882. CTXFREE(parentCtx, implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, nullptr));
  883. }
  884. FILESERVICES_API void FILESERVICES_CALL fsSprayXml_v5(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts)
  885. {
  886. CTXFREE(parentCtx, implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, sourcePlane, destinationNumParts));
  887. }
  888. FILESERVICES_API char * FILESERVICES_CALL fsfSprayXml(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile)
  889. {
  890. return implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, -1, nullptr, false, nullptr);
  891. }
  892. FILESERVICES_API char * FILESERVICES_CALL fsfSprayXml_v2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays)
  893. {
  894. return implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, nullptr, false, nullptr);
  895. }
  896. FILESERVICES_API char * FILESERVICES_CALL fsfSprayXml_v3(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue)
  897. {
  898. return implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, false, nullptr);
  899. }
  900. FILESERVICES_API char * FILESERVICES_CALL fsfSprayXml_v4(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit)
  901. {
  902. return implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, nullptr);
  903. }
  904. FILESERVICES_API char * FILESERVICES_CALL fsfSprayXml_v5(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowTag, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * sourcePlane, unsigned destinationNumParts)
  905. {
  906. return implementSprayXml(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowTag, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, sourcePlane, destinationNumParts);
  907. }
  908. //----------------------------------------------------------------------------------
  909. FILESERVICES_API char * FILESERVICES_CALL implementSprayJson(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowPath, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * username, const char * userPw, const char * sourcePlane, unsigned destinationNumParts=0)
  910. {
  911. LOG(MCauditInfo, "Spray JSON: %s", destinationLogicalName);
  912. CClientFileSpray server;
  913. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  914. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  915. setServerAccess(server, wu);
  916. Owned<IClientSprayVariable> req = server.createSprayVariableRequest();
  917. setContainerLocalCertificate(req->rpc());
  918. StringBuffer logicalName;
  919. constructLogicalName(wu, destinationLogicalName, logicalName);
  920. DFUfileformat dfufmt;
  921. if (sourceEncoding == NULL)
  922. dfufmt = DFUff_utf8;
  923. else
  924. dfufmt = CDFUfileformat::decode(sourceEncoding);
  925. req->setSourceIP(sourceIP);
  926. req->setSourcePath(sourcePath);
  927. req->setSourcePlane(sourcePlane);
  928. req->setSourceMaxRecordSize(sourceMaxRecordSize);
  929. req->setSourceFormat(dfufmt);
  930. req->setSourceRowTag(sourceRowPath);
  931. req->setDestGroup(destinationGroup);
  932. req->setDestLogicalName(logicalName.str());
  933. req->setOverwrite(overwrite);
  934. req->setReplicate(replicate);
  935. req->setCompress(compress);
  936. if (maxConnections != -1)
  937. req->setMaxConnections(maxConnections);
  938. if (failIfNoSourceFile)
  939. req->setFailIfNoSourceFile(true);
  940. req->setIsJSON(true);
  941. req->setExpireDays(expireDays);
  942. if (!isEmptyString(dfuServerQueue))
  943. req->setDFUServerQueue(dfuServerQueue);
  944. if (noSplit)
  945. req->setNosplit(true);
  946. // Store username/psw
  947. if (!isEmptyString(username))
  948. {
  949. req->setSrcUsername(username);
  950. if (!isEmptyString(userPw))
  951. req->setSrcPassword(userPw);
  952. }
  953. Owned<IClientSprayResponse> result = server.SprayVariable(req);
  954. StringBuffer wuid(result->getWuid());
  955. if (!wuid.length())
  956. {
  957. const IMultiException* excep = &result->getExceptions();
  958. if ((excep != NULL) && (excep->ordinality() > 0))
  959. {
  960. StringBuffer errmsg;
  961. excep->errorMessage(errmsg);
  962. throw MakeStringExceptionDirect(0, errmsg.str());
  963. }
  964. else
  965. {
  966. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  967. }
  968. }
  969. wu.clear();
  970. blockUntilComplete("Spray", server, ctx, wuid, timeOut);
  971. return wuid.detach();
  972. }
  973. FILESERVICES_API void FILESERVICES_CALL fsSprayJson(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowPath, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * username, const char * userPw)
  974. {
  975. CTXFREE(parentCtx, implementSprayJson(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowPath, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, username, userPw, nullptr));
  976. }
  977. FILESERVICES_API void FILESERVICES_CALL fsSprayJson_v2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowPath, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * username, const char * userPw, const char * sourcePlane, unsigned destinationNumParts)
  978. {
  979. CTXFREE(parentCtx, implementSprayJson(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowPath, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, username, userPw, sourcePlane, destinationNumParts));
  980. }
  981. FILESERVICES_API char * FILESERVICES_CALL fsfSprayJson(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowPath, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * username, const char * userPw)
  982. {
  983. return implementSprayJson(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowPath, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, username, userPw, nullptr);
  984. }
  985. FILESERVICES_API char * FILESERVICES_CALL fsfSprayJson_v2(ICodeContext *ctx, const char * sourceIP, const char * sourcePath, int sourceMaxRecordSize, const char *sourceRowPath, const char *sourceEncoding, const char * destinationGroup, const char * destinationLogicalName, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool compress, bool failIfNoSourceFile, int expireDays, const char * dfuServerQueue, bool noSplit, const char * username, const char * userPw, const char * sourcePlane, unsigned destinationNumParts)
  986. {
  987. return implementSprayJson(ctx, sourceIP, sourcePath, sourceMaxRecordSize, sourceRowPath, sourceEncoding, destinationGroup, destinationLogicalName, timeOut, espServerIpPort, maxConnections, overwrite, replicate, compress, failIfNoSourceFile, expireDays, dfuServerQueue, noSplit, username, userPw, sourcePlane, destinationNumParts);
  988. }
  989. //----------------------------------------------------------------------------------
  990. static char * implementDespray(ICodeContext *ctx, const char * sourceLogicalName, const char * destinationIP, const char * destinationPath, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, const char * destinationPlane = nullptr)
  991. {
  992. LOG(MCauditInfo, "Despray: %s", sourceLogicalName);
  993. CClientFileSpray server;
  994. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  995. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  996. if (wu)
  997. setServerAccess(server, wu);
  998. Owned<IClientDespray> req = server.createDesprayRequest();
  999. setContainerLocalCertificate(req->rpc());
  1000. StringBuffer logicalName;
  1001. constructLogicalName(wu, sourceLogicalName, logicalName);
  1002. req->setSourceLogicalName(logicalName.str());
  1003. req->setDestIP(destinationIP);
  1004. req->setDestPath(destinationPath);
  1005. req->setDestPlane(destinationPlane);
  1006. req->setOverwrite(overwrite);
  1007. if (maxConnections != -1)
  1008. req->setMaxConnections(maxConnections);
  1009. Owned<IClientDesprayResponse> result = server.Despray(req);
  1010. StringBuffer wuid(result->getWuid());
  1011. if (!wuid.length())
  1012. {
  1013. const IMultiException* excep = &result->getExceptions();
  1014. if ((excep != NULL) && (excep->ordinality() > 0))
  1015. {
  1016. StringBuffer errmsg;
  1017. excep->errorMessage(errmsg);
  1018. throw MakeStringExceptionDirect(0, errmsg.str());
  1019. }
  1020. else
  1021. {
  1022. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  1023. }
  1024. }
  1025. wu.clear();
  1026. blockUntilComplete("Despray", server, ctx, wuid, timeOut);
  1027. return wuid.detach();
  1028. }
  1029. FILESERVICES_API void FILESERVICES_CALL fsDespray(ICodeContext *ctx, const char * sourceLogicalName, const char * destinationIP, const char * destinationPath, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite)
  1030. {
  1031. CTXFREE(parentCtx, implementDespray(ctx, sourceLogicalName, destinationIP, destinationPath, timeOut, espServerIpPort, maxConnections, overwrite));
  1032. }
  1033. FILESERVICES_API char * FILESERVICES_CALL fsfDespray(ICodeContext *ctx, const char * sourceLogicalName, const char * destinationIP, const char * destinationPath, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite)
  1034. {
  1035. return implementDespray(ctx, sourceLogicalName, destinationIP, destinationPath, timeOut, espServerIpPort, maxConnections, overwrite);
  1036. }
  1037. FILESERVICES_API void FILESERVICES_CALL fsDespray2(ICodeContext *ctx, const char * sourceLogicalName, const char * destinationIP, const char * destinationPath, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, const char * destinationPlane)
  1038. {
  1039. CTXFREE(parentCtx, implementDespray(ctx, sourceLogicalName, destinationIP, destinationPath, timeOut, espServerIpPort, maxConnections, overwrite, destinationPlane));
  1040. }
  1041. FILESERVICES_API char * FILESERVICES_CALL fsfDespray2(ICodeContext *ctx, const char * sourceLogicalName, const char * destinationIP, const char * destinationPath, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, const char * destinationPlane)
  1042. {
  1043. return implementDespray(ctx, sourceLogicalName, destinationIP, destinationPath, timeOut, espServerIpPort, maxConnections, overwrite, destinationPlane);
  1044. }
  1045. FILESERVICES_API char * FILESERVICES_CALL implementCopy(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize, bool preserveCompression, bool noSplit, int expireDays)
  1046. {
  1047. LOG(MCauditInfo, "Copy: %s%s", sourceLogicalName,asSuperfile?" as superfile":"");
  1048. CClientFileSpray server;
  1049. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1050. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  1051. setServerAccess(server, wu);
  1052. Owned<IClientCopy> req = server.createCopyRequest();
  1053. setContainerLocalCertificate(req->rpc());
  1054. if (asSuperfile)
  1055. req->setSuperCopy(true);
  1056. StringBuffer _sourceLogicalName, _destinationLogicalName;
  1057. constructLogicalName(wu, sourceLogicalName, _sourceLogicalName);
  1058. constructLogicalName(wu, destinationLogicalName, _destinationLogicalName);
  1059. req->setSourceLogicalName(_sourceLogicalName.str());
  1060. req->setDestLogicalName(_destinationLogicalName.str());
  1061. if ((destinationGroup != NULL) && (*destinationGroup != '\0'))
  1062. req->setDestGroup(destinationGroup);
  1063. if ((sourceDali != NULL) && (*sourceDali != '\0'))
  1064. req->setSourceDali(sourceDali);
  1065. req->setOverwrite(overwrite);
  1066. req->setReplicate(replicate);
  1067. if (compress)
  1068. req->setCompress(true);
  1069. req->setPreserveCompression(preserveCompression);
  1070. if (forcePush)
  1071. req->setPush(true);
  1072. if (transferBufferSize > 0)
  1073. req->setTransferBufferSize(transferBufferSize);
  1074. if (maxConnections != -1)
  1075. req->setMaxConnections(maxConnections);
  1076. if (noSplit)
  1077. req->setNosplit(true);
  1078. req->setExpireDays(expireDays);
  1079. Owned<IClientCopyResponse> result = server.Copy(req);
  1080. StringBuffer wuid(result->getResult());
  1081. if (!wuid.length())
  1082. {
  1083. const IMultiException* excep = &result->getExceptions();
  1084. if ((excep != NULL) && (excep->ordinality() > 0))
  1085. {
  1086. StringBuffer errmsg;
  1087. excep->errorMessage(errmsg);
  1088. throw MakeStringExceptionDirect(0, errmsg.str());
  1089. }
  1090. else
  1091. {
  1092. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  1093. }
  1094. }
  1095. wu.clear();
  1096. blockUntilComplete("Copy", server, ctx, wuid, timeOut);
  1097. return wuid.detach();
  1098. }
  1099. FILESERVICES_API void FILESERVICES_CALL fsCopy(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize)
  1100. {
  1101. CTXFREE(parentCtx, implementCopy(ctx, sourceLogicalName, destinationGroup, destinationLogicalName, sourceDali, timeOut, espServerIpPort, maxConnections, overwrite, replicate, asSuperfile, compress, forcePush, transferBufferSize, true, false, -1));
  1102. }
  1103. FILESERVICES_API void FILESERVICES_CALL fsCopy_v2(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize, bool preserveCompression)
  1104. {
  1105. CTXFREE(parentCtx, implementCopy(ctx, sourceLogicalName, destinationGroup, destinationLogicalName, sourceDali, timeOut, espServerIpPort, maxConnections, overwrite, replicate, asSuperfile, compress, forcePush, transferBufferSize, preserveCompression, false, -1));
  1106. }
  1107. FILESERVICES_API void FILESERVICES_CALL fsCopy_v3(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize, bool preserveCompression, bool noSplit, int expireDays)
  1108. {
  1109. CTXFREE(parentCtx, implementCopy(ctx, sourceLogicalName, destinationGroup, destinationLogicalName, sourceDali, timeOut, espServerIpPort, maxConnections, overwrite, replicate, asSuperfile, compress, forcePush, transferBufferSize, preserveCompression, noSplit, expireDays));
  1110. }
  1111. FILESERVICES_API char * FILESERVICES_CALL fsfCopy(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize)
  1112. {
  1113. return implementCopy(ctx, sourceLogicalName, destinationGroup, destinationLogicalName, sourceDali, timeOut, espServerIpPort, maxConnections, overwrite, replicate, asSuperfile, compress, forcePush, transferBufferSize, true, false, -1);
  1114. }
  1115. FILESERVICES_API char * FILESERVICES_CALL fsfCopy_v2(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize, bool preserveCompression)
  1116. {
  1117. return implementCopy(ctx, sourceLogicalName, destinationGroup, destinationLogicalName, sourceDali, timeOut, espServerIpPort, maxConnections, overwrite, replicate, asSuperfile, compress, forcePush, transferBufferSize, preserveCompression, false,-1);
  1118. }
  1119. FILESERVICES_API char * FILESERVICES_CALL fsfCopy_v3(ICodeContext *ctx, const char * sourceLogicalName, const char *destinationGroup, const char * destinationLogicalName, const char * sourceDali, int timeOut, const char * espServerIpPort, int maxConnections, bool overwrite, bool replicate, bool asSuperfile, bool compress, bool forcePush, int transferBufferSize, bool preserveCompression, bool noSplit, int expireDays)
  1120. {
  1121. return implementCopy(ctx, sourceLogicalName, destinationGroup, destinationLogicalName, sourceDali, timeOut, espServerIpPort, maxConnections, overwrite, replicate, asSuperfile, compress, forcePush, transferBufferSize, preserveCompression, noSplit, expireDays);
  1122. }
  1123. FILESERVICES_API void FILESERVICES_CALL fsReplicate(ICodeContext *ctx, const char * sourceLogicalName,int timeOut, const char * espServerIpPort)
  1124. {
  1125. CTXFREE(parentCtx, fsfReplicate(ctx, sourceLogicalName, timeOut, espServerIpPort));
  1126. }
  1127. FILESERVICES_API char * FILESERVICES_CALL fsfReplicate(ICodeContext *ctx, const char * sourceLogicalName, int timeOut, const char * espServerIpPort)
  1128. {
  1129. LOG(MCauditInfo, "REPLICATE: %s", sourceLogicalName);
  1130. CClientFileSpray server;
  1131. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1132. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  1133. setServerAccess(server, wu);
  1134. Owned<IClientReplicate> req = server.createReplicateRequest();
  1135. setContainerLocalCertificate(req->rpc());
  1136. StringBuffer logicalName;
  1137. constructLogicalName(wu, sourceLogicalName, logicalName);
  1138. req->setSourceLogicalName(logicalName.str());
  1139. Owned<IClientReplicateResponse> result = server.Replicate(req);
  1140. StringBuffer wuid(result->getWuid());
  1141. if (!wuid.length())
  1142. {
  1143. const IMultiException* excep = &result->getExceptions();
  1144. if ((excep != NULL) && (excep->ordinality() > 0))
  1145. {
  1146. StringBuffer errmsg;
  1147. excep->errorMessage(errmsg);
  1148. throw MakeStringExceptionDirect(0, errmsg.str());
  1149. }
  1150. else
  1151. {
  1152. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  1153. }
  1154. }
  1155. wu.clear();
  1156. blockUntilComplete("Replicate", server, ctx, wuid, timeOut);
  1157. return wuid.detach();
  1158. }
  1159. //===========================================================================================
  1160. // SuperFile API
  1161. /*
  1162. CreateSuperFile(const varstring lsuperfn, boolean sequentialparts=false);
  1163. boolean SuperFileExists(const varstring lsuperfn);
  1164. DeleteSuperFile(const varstring lsuperfn,boolean deletesub=false);
  1165. unsigned4 GetSuperFileSubCount(const varstring lsuperfn);
  1166. varstring GetSuperFileSubName(const varstring lsuperfn,unsigned4 filenum);
  1167. unsigned4 FindSuperFileSubName(const varstring lsuperfn,const varstring lfn);
  1168. StartSuperFileTransaction();
  1169. AddSuperFile(const varstring lsuperfn,const varstring lfn,unsigned4 atpos=0);
  1170. RemoveSuperFile(const varstring lsuperfn,const varstring lfn,boolean del=false);
  1171. ClearSuperFile(const varstring lsuperfn,boolean del=false);
  1172. RemoveOwnedSubFiles(const varstring lsuperfn,boolean del=false);
  1173. SwapSuperFile(const varstring lsuperfn1,const varstring lsuperfn2);
  1174. ReplaceSuperFile(const varstring lsuperfn,const varstring lfn,const varstring bylfn);
  1175. FinishSuperFileTransaction(boolean rollback=false);
  1176. */
  1177. class CImplicitSuperTransaction
  1178. {
  1179. IDistributedFileTransaction *transaction;
  1180. public:
  1181. CImplicitSuperTransaction(IDistributedFileTransaction *_transaction)
  1182. {
  1183. if (!_transaction->active()) // then created implicitly
  1184. {
  1185. transaction = _transaction;
  1186. transaction->start();
  1187. }
  1188. else
  1189. transaction = NULL;
  1190. }
  1191. ~CImplicitSuperTransaction() noexcept(false)
  1192. {
  1193. if (transaction)
  1194. transaction->commit();
  1195. }
  1196. };
  1197. static bool lookupSuperFile(ICodeContext *ctx, const char *lsuperfn, Owned<IDistributedSuperFile> &file, bool throwerr, StringBuffer &lsfn, bool allowforeign, bool cacheFiles=false)
  1198. {
  1199. lsfn.clear();
  1200. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1201. assertex(transaction);
  1202. constructLogicalName(ctx, lsuperfn, lsfn);
  1203. if (!allowforeign) {
  1204. CDfsLogicalFileName dlfn;
  1205. dlfn.set(lsfn.str());
  1206. if (dlfn.isForeign())
  1207. throw MakeStringException(0, "Foreign superfile not allowed: %s", lsfn.str());
  1208. }
  1209. file.setown(transaction->lookupSuperFile(lsfn.str()));
  1210. if (file.get())
  1211. return true;
  1212. if (throwerr)
  1213. throw MakeStringException(0, "Could not locate superfile: %s", lsfn.str());
  1214. return false;
  1215. }
  1216. static ISimpleSuperFileEnquiry *getSimpleSuperFileEnquiry(ICodeContext *ctx, const char *lsuperfn)
  1217. {
  1218. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1219. assertex(transaction);
  1220. if (transaction->active())
  1221. return NULL;
  1222. StringBuffer lsfn;
  1223. constructLogicalName(ctx, lsuperfn, lsfn);
  1224. return queryDistributedFileDirectory().getSimpleSuperFileEnquiry(lsfn.str(),"Fileservices",ctx->queryUserDescriptor());
  1225. }
  1226. static void CheckNotInTransaction(ICodeContext *ctx, const char *fn)
  1227. {
  1228. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1229. assertex(transaction);
  1230. if (transaction->active()) {
  1231. StringBuffer s("Operation not part of transaction : ");
  1232. s.append(fn);
  1233. WUmessage(ctx,SeverityWarning,fn,s.str());
  1234. }
  1235. }
  1236. FILESERVICES_API void FILESERVICES_CALL fsCreateSuperFile(ICodeContext *ctx, const char *lsuperfn, bool sequentialparts, bool ifdoesnotexist)
  1237. {
  1238. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1239. assertex(transaction);
  1240. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1241. StringBuffer lsfn;
  1242. constructLogicalName(ctx, lsuperfn, lsfn);
  1243. Owned<IDistributedSuperFile> file = queryDistributedFileDirectory().createSuperFile(lsfn,udesc,!sequentialparts,ifdoesnotexist,transaction);
  1244. StringBuffer s("CreateSuperFile ('");
  1245. s.append(lsfn).append("') done");
  1246. AuditMessage(ctx,"CreateSuperFile",lsfn.str());
  1247. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1248. }
  1249. FILESERVICES_API bool FILESERVICES_CALL fsSuperFileExists(ICodeContext *ctx, const char *lsuperfn)
  1250. {
  1251. StringBuffer lsfn;
  1252. constructLogicalName(ctx, lsuperfn, lsfn);
  1253. return queryDistributedFileDirectory().exists(lsfn,ctx->queryUserDescriptor(),false,true);
  1254. }
  1255. FILESERVICES_API void FILESERVICES_CALL fsDeleteSuperFile(ICodeContext *ctx, const char *lsuperfn,bool deletesub)
  1256. {
  1257. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1258. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1259. Owned<IDistributedSuperFile> file;
  1260. StringBuffer lsfn;
  1261. bool found = lookupSuperFile(ctx, lsuperfn, file, false, lsfn, false);
  1262. file.clear(); // MORE: this should really be exists(file)
  1263. StringBuffer s("DeleteSuperFile ('");
  1264. s.append(lsfn).appendf("')");
  1265. if (found) {
  1266. queryDistributedFileDirectory().removeSuperFile(lsfn.str(), deletesub, udesc, transaction);
  1267. if (transaction->active())
  1268. s.append(" action added to transaction");
  1269. else
  1270. s.append(" done");
  1271. } else {
  1272. s.append(" file not found");
  1273. }
  1274. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1275. if (found)
  1276. AuditMessage(ctx,"DeleteSuperFile",lsfn.str());
  1277. }
  1278. FILESERVICES_API unsigned FILESERVICES_CALL fsGetSuperFileSubCount(ICodeContext *ctx, const char *lsuperfn)
  1279. {
  1280. Owned<ISimpleSuperFileEnquiry> enq = getSimpleSuperFileEnquiry(ctx, lsuperfn);
  1281. if (enq)
  1282. return enq->numSubFiles();
  1283. CImplicitSuperTransaction implicitTransaction(ctx->querySuperFileTransaction());
  1284. Owned<IDistributedSuperFile> file;
  1285. StringBuffer lsfn;
  1286. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, true);
  1287. return file->numSubFiles();
  1288. }
  1289. FILESERVICES_API char * FILESERVICES_CALL fsGetSuperFileSubName(ICodeContext *ctx, const char *lsuperfn,unsigned filenum, bool abspath)
  1290. {
  1291. StringBuffer ret;
  1292. if (abspath)
  1293. ret.append('~');
  1294. Owned<ISimpleSuperFileEnquiry> enq = getSimpleSuperFileEnquiry(ctx, lsuperfn);
  1295. if (enq) {
  1296. if (!filenum||!enq->getSubFileName(filenum-1,ret))
  1297. return CTXSTRDUP(parentCtx, "");
  1298. return ret.detach();
  1299. }
  1300. CImplicitSuperTransaction implicitTransaction(ctx->querySuperFileTransaction());
  1301. Owned<IDistributedSuperFile> file;
  1302. StringBuffer lsfn;
  1303. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, true);
  1304. if (!filenum||filenum>file->numSubFiles())
  1305. return CTXSTRDUP(parentCtx, "");
  1306. ret.append(file->querySubFile(filenum-1).queryLogicalName());
  1307. return ret.detach();
  1308. }
  1309. FILESERVICES_API unsigned FILESERVICES_CALL fsFindSuperFileSubName(ICodeContext *ctx, const char *lsuperfn,const char *_lfn)
  1310. {
  1311. StringBuffer lfn;
  1312. constructLogicalName(ctx, _lfn, lfn);
  1313. Owned<ISimpleSuperFileEnquiry> enq = getSimpleSuperFileEnquiry(ctx, lsuperfn);
  1314. if (enq) {
  1315. unsigned n = enq->findSubName(lfn.str());
  1316. return (n==NotFound)?0:n+1;
  1317. }
  1318. CImplicitSuperTransaction implicitTransaction(ctx->querySuperFileTransaction());
  1319. Owned<IDistributedSuperFile> file;
  1320. StringBuffer lsfn;
  1321. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, true);
  1322. unsigned n = 0;
  1323. // could do with better version of this TBD
  1324. Owned<IDistributedFileIterator> iter = file->getSubFileIterator();
  1325. ForEach(*iter) {
  1326. n++;
  1327. if (stricmp(iter->query().queryLogicalName(),lfn.str())==0)
  1328. return n;
  1329. }
  1330. return 0;
  1331. }
  1332. FILESERVICES_API void FILESERVICES_CALL fsStartSuperFileTransaction(IGlobalCodeContext *gctx)
  1333. {
  1334. fslStartSuperFileTransaction(gctx->queryCodeContext());
  1335. }
  1336. FILESERVICES_API void FILESERVICES_CALL fslStartSuperFileTransaction(ICodeContext *ctx)
  1337. {
  1338. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1339. assertex(transaction);
  1340. transaction->start();
  1341. WUmessage(ctx,SeverityInformation,NULL,"StartSuperFileTransaction");
  1342. }
  1343. FILESERVICES_API void FILESERVICES_CALL fsAddSuperFile(IGlobalCodeContext *gctx, const char *lsuperfn,const char *_lfn,unsigned atpos,bool addcontents, bool strict)
  1344. {
  1345. fslAddSuperFile(gctx->queryCodeContext(),lsuperfn,_lfn,atpos,addcontents,strict);
  1346. }
  1347. FILESERVICES_API void FILESERVICES_CALL fslAddSuperFile(ICodeContext *ctx, const char *lsuperfn,const char *_lfn,unsigned atpos,bool addcontents, bool strict)
  1348. {
  1349. Owned<IDistributedSuperFile> file;
  1350. StringBuffer lsfn;
  1351. // NB: if adding contents, tell lookupSuperFile to cache the subfiles in the transaction
  1352. if (!lookupSuperFile(ctx, lsuperfn, file, strict, lsfn, false, addcontents)) {
  1353. // auto create
  1354. fsCreateSuperFile(ctx,lsuperfn,false,false);
  1355. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, false, addcontents);
  1356. }
  1357. // Never add super file to itself
  1358. StringBuffer lfn;
  1359. constructLogicalName(ctx, _lfn, lfn);
  1360. if (stricmp(file->queryLogicalName(), lfn.str()) == 0) {
  1361. throw MakeStringException(0, "AddSuperFile: Adding super file %s to itself!", file->queryLogicalName());
  1362. }
  1363. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1364. assertex(transaction);
  1365. if (strict||addcontents) {
  1366. Owned<IDistributedSuperFile> subfile;
  1367. subfile.setown(transaction->lookupSuperFile(lfn.str()));
  1368. if (!subfile.get())
  1369. throw MakeStringException(0, "AddSuperFile%s: Could not locate super file %s", addcontents?"(addcontents)":"",lfn.str());
  1370. if (strict&&(subfile->numSubFiles()<1))
  1371. throw MakeStringException(0, "AddSuperFile: Adding empty super file %s", lfn.str());
  1372. }
  1373. StringBuffer other;
  1374. if (atpos>1)
  1375. other.append("#").append(atpos);
  1376. {
  1377. CImplicitSuperTransaction implicitTransaction(transaction);
  1378. file->addSubFile(lfn.str(),atpos>0,(atpos>1)?other.str():NULL,addcontents,transaction);
  1379. file.clear(); // Must clear file before implicit transaction executed in destructor
  1380. }
  1381. StringBuffer s("AddSuperFile ('");
  1382. s.append(lsfn).append("', '");
  1383. s.append(lfn).append('\'');
  1384. if (atpos)
  1385. s.append(", ").append(atpos);
  1386. if (addcontents)
  1387. s.append(", addcontents");
  1388. s.append(") ");
  1389. if (transaction->active())
  1390. s.append("trans");
  1391. else
  1392. s.append("done");
  1393. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1394. AuditMessage(ctx,"AddSuperFile",lsfn.str(),lfn.str());
  1395. }
  1396. FILESERVICES_API void FILESERVICES_CALL fsRemoveSuperFile(IGlobalCodeContext *gctx, const char *lsuperfn,const char *_lfn,bool del,bool remcontents)
  1397. {
  1398. fslRemoveSuperFile(gctx->queryCodeContext(),lsuperfn,_lfn,del,remcontents);
  1399. }
  1400. FILESERVICES_API void FILESERVICES_CALL fslRemoveSuperFile(ICodeContext *ctx, const char *lsuperfn,const char *_lfn,bool del,bool remcontents)
  1401. {
  1402. Owned<IDistributedSuperFile> file;
  1403. StringBuffer lsfn;
  1404. StringBuffer lfn;
  1405. if (_lfn)
  1406. constructLogicalName(ctx, _lfn, lfn);
  1407. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, false, true);
  1408. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1409. assertex(transaction);
  1410. {
  1411. CImplicitSuperTransaction implicitTransaction(transaction);
  1412. file->removeSubFile(_lfn?lfn.str():NULL,del,remcontents,transaction);
  1413. file.clear(); // Must clear file before implicit transaction executed in destructor
  1414. }
  1415. StringBuffer s;
  1416. if (_lfn)
  1417. s.append("RemoveSuperFile ('");
  1418. else
  1419. s.append("ClearSuperFile ('");
  1420. s.append(lsfn).append('\'');
  1421. if (_lfn)
  1422. s.append(", '").append(lfn.str()).append('\'');
  1423. if (del)
  1424. s.append(", del");
  1425. if (remcontents)
  1426. s.append(", remcontents");
  1427. s.append(") ");
  1428. if (transaction->active())
  1429. s.append("trans");
  1430. else
  1431. s.append("done");
  1432. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1433. AuditMessage(ctx,"RemoveSuperFile",lsfn.str(),lfn.str());
  1434. }
  1435. FILESERVICES_API void FILESERVICES_CALL fsClearSuperFile(IGlobalCodeContext *gctx, const char *lsuperfn,bool del)
  1436. {
  1437. fsRemoveSuperFile(gctx,lsuperfn,NULL,del);
  1438. }
  1439. FILESERVICES_API void FILESERVICES_CALL fsDeleteOwnedSubFiles(IGlobalCodeContext *gctx, const char *lsuperfn) // Obsolete
  1440. {
  1441. fslRemoveOwnedSubFiles(gctx->queryCodeContext(), lsuperfn, false);
  1442. }
  1443. FILESERVICES_API void FILESERVICES_CALL fsRemoveOwnedSubFiles(IGlobalCodeContext *gctx, const char *lsuperfn, bool del)
  1444. {
  1445. fslRemoveOwnedSubFiles(gctx->queryCodeContext(), lsuperfn, del);
  1446. }
  1447. FILESERVICES_API void FILESERVICES_CALL fslRemoveOwnedSubFiles(ICodeContext *ctx, const char *lsuperfn, bool del)
  1448. {
  1449. Owned<IDistributedSuperFile> file;
  1450. StringBuffer lsfn;
  1451. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, false, true);
  1452. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1453. assertex(transaction);
  1454. {
  1455. CImplicitSuperTransaction implicitTransaction(transaction);
  1456. file->removeOwnedSubFiles(del,transaction);
  1457. file.clear(); // Must clear file before implicit transaction executed in destructor
  1458. }
  1459. VStringBuffer s("RemoveOwnedSubFiles ('%s'", lsfn.str());
  1460. if (del)
  1461. s.append(", del");
  1462. s.append(") ");
  1463. if (transaction->active())
  1464. s.append("trans");
  1465. else
  1466. s.append("done");
  1467. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1468. AuditMessage(ctx,"RemoveOwnedSubFiles",lsfn.str());
  1469. }
  1470. FILESERVICES_API void FILESERVICES_CALL fslClearSuperFile(ICodeContext *ctx, const char *lsuperfn,bool del)
  1471. {
  1472. fslRemoveSuperFile(ctx,lsuperfn,NULL,del);
  1473. }
  1474. FILESERVICES_API void FILESERVICES_CALL fsSwapSuperFile(IGlobalCodeContext *gctx, const char *lsuperfn1,const char *lsuperfn2)
  1475. {
  1476. fslSwapSuperFile(gctx->queryCodeContext(),lsuperfn1,lsuperfn2);
  1477. }
  1478. FILESERVICES_API void FILESERVICES_CALL fslSwapSuperFile(ICodeContext *ctx, const char *lsuperfn1,const char *lsuperfn2)
  1479. {
  1480. StringBuffer lsfn1;
  1481. StringBuffer lsfn2;
  1482. Owned<IDistributedSuperFile> file1;
  1483. Owned<IDistributedSuperFile> file2;
  1484. lookupSuperFile(ctx, lsuperfn1, file1, true, lsfn1,false);
  1485. lookupSuperFile(ctx, lsuperfn2, file2, true,lsfn2,false);
  1486. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1487. assertex(transaction);
  1488. {
  1489. CImplicitSuperTransaction implicitTransaction(transaction);
  1490. file1->swapSuperFile(file2,transaction);
  1491. // Must clear files before implicit transaction executed in destructor
  1492. file1.clear();
  1493. file2.clear();
  1494. }
  1495. StringBuffer s("SwapSuperFile ('");
  1496. s.append(lsfn1).append("', '");
  1497. s.append(lsfn2).append("') '");
  1498. if (transaction->active())
  1499. s.append("trans");
  1500. else
  1501. s.append("done");
  1502. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1503. AuditMessage(ctx,"SwapSuperFile",lsfn1.str(),lsfn2.str());
  1504. }
  1505. FILESERVICES_API void FILESERVICES_CALL fsReplaceSuperFile(IGlobalCodeContext *gctx, const char *lsuperfn,const char *lfn,const char *bylfn)
  1506. {
  1507. fslReplaceSuperFile(gctx->queryCodeContext(),lsuperfn,lfn,bylfn);
  1508. }
  1509. FILESERVICES_API void FILESERVICES_CALL fslReplaceSuperFile(ICodeContext *ctx, const char *lsuperfn,const char *lfn,const char *bylfn)
  1510. {
  1511. unsigned at = fsFindSuperFileSubName(ctx,lsuperfn,lfn);
  1512. if (!at)
  1513. return;
  1514. fslRemoveSuperFile(ctx,lsuperfn,lfn);
  1515. fslAddSuperFile(ctx,lsuperfn,bylfn,at);
  1516. }
  1517. FILESERVICES_API void FILESERVICES_CALL fsFinishSuperFileTransaction(IGlobalCodeContext *gctx, bool rollback)
  1518. {
  1519. fslFinishSuperFileTransaction(gctx->queryCodeContext(),rollback);
  1520. }
  1521. FILESERVICES_API void FILESERVICES_CALL fslFinishSuperFileTransaction(ICodeContext *ctx, bool rollback)
  1522. {
  1523. IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
  1524. assertex(transaction);
  1525. if (transaction->active()) {
  1526. if (rollback)
  1527. transaction->rollback();
  1528. else
  1529. transaction->commit();
  1530. StringBuffer s("FinishSuperFileTransaction ");
  1531. if (rollback)
  1532. s.append("rollback");
  1533. else
  1534. s.append("commit");
  1535. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1536. }
  1537. else {
  1538. StringBuffer s("Invalid FinishSuperFileTransaction ");
  1539. if (rollback)
  1540. s.append("rollback");
  1541. else
  1542. s.append("done");
  1543. s.append(", transaction not active");
  1544. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1545. }
  1546. }
  1547. static char * implementForeignLogicalFileName(ICodeContext *ctx, const char *_lfn, const char *foreigndali, bool abspath, bool omitClusterPrefix)
  1548. {
  1549. StringBuffer lfns;
  1550. Owned<IConstWorkUnit> wu;
  1551. if (!omitClusterPrefix && _lfn&&(*_lfn != '~'))
  1552. wu.setown(getWorkunit(ctx));
  1553. constructLogicalName(wu, _lfn, lfns);
  1554. CDfsLogicalFileName lfn;
  1555. lfn.set(lfns.str());
  1556. if (foreigndali&&*foreigndali) {
  1557. SocketEndpoint ep(foreigndali);
  1558. lfn.setForeign(ep,false);
  1559. }
  1560. else
  1561. lfn.clearForeign();
  1562. StringBuffer ret;
  1563. if (abspath)
  1564. ret.append('~');
  1565. lfn.get(ret);
  1566. return ret.detach();
  1567. }
  1568. FILESERVICES_API char * FILESERVICES_CALL fsForeignLogicalFileName(ICodeContext *ctx, const char *lfn, const char *foreigndali, bool abspath)
  1569. {
  1570. return implementForeignLogicalFileName(ctx, lfn, foreigndali, abspath, false);
  1571. }
  1572. FILESERVICES_API char * FILESERVICES_CALL fsForeignLogicalFileName_v2(ICodeContext *ctx, const char *lfn, const char *foreigndali, bool abspath, bool omitClusterPrefix)
  1573. {
  1574. return implementForeignLogicalFileName(ctx, lfn, foreigndali, abspath, omitClusterPrefix);
  1575. }
  1576. FILESERVICES_API char * FILESERVICES_CALL fsExternalLogicalFileName(const char *location,const char *path,bool abspath)
  1577. {
  1578. StringBuffer ret;
  1579. if (abspath)
  1580. ret.append('~');
  1581. CDfsLogicalFileName lfn;
  1582. lfn.setExternal(location,path);
  1583. return lfn.get(ret).detach();
  1584. }
  1585. FILESERVICES_API char * FILESERVICES_CALL fsWaitDfuWorkunit(IGlobalCodeContext *gctx, const char *wuid, int timeout, const char * espServerIpPort)
  1586. {
  1587. return fslWaitDfuWorkunit(gctx->queryCodeContext(),wuid,timeout,espServerIpPort);
  1588. }
  1589. FILESERVICES_API char * FILESERVICES_CALL fslWaitDfuWorkunit(ICodeContext *ctx, const char *wuid, int timeout, const char * espServerIpPort)
  1590. {
  1591. CClientFileSpray server;
  1592. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1593. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  1594. setServerAccess(server, wu);
  1595. StringBuffer s("Waiting for DFU Workunit ");
  1596. s.append(wuid);
  1597. WUmessage(ctx,SeverityInformation,"WaitDfuWorkunit",s.str());
  1598. StringBuffer state;
  1599. wu.clear();
  1600. blockUntilComplete("WaitDfuWorkunit", server, ctx, wuid, timeout, &state);
  1601. s.clear().append("Finished waiting for DFU Workunit ").append(wuid).append(" state=").append(state.str());
  1602. WUmessage(ctx,SeverityInformation,"WaitDfuWorkunit",s.str());
  1603. return state.detach();
  1604. }
  1605. FILESERVICES_API void FILESERVICES_CALL fsAbortDfuWorkunit(IGlobalCodeContext *gctx, const char *wuid, const char * espServerIpPort)
  1606. {
  1607. fslAbortDfuWorkunit(gctx->queryCodeContext(),wuid,espServerIpPort);
  1608. }
  1609. FILESERVICES_API void FILESERVICES_CALL fslAbortDfuWorkunit(ICodeContext *ctx, const char *wuid, const char * espServerIpPort)
  1610. {
  1611. CClientFileSpray server;
  1612. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1613. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  1614. setServerAccess(server, wu);
  1615. Owned<IClientAbortDFUWorkunit> abortReq = server.createAbortDFUWorkunitRequest();
  1616. setContainerLocalCertificate(abortReq->rpc());
  1617. abortReq->setWuid(wuid);
  1618. Linked<IClientAbortDFUWorkunitResponse> abortResp = server.AbortDFUWorkunit(abortReq);
  1619. StringBuffer s("DFU Workunit Abort Requested for ");
  1620. s.append(wuid);
  1621. WUmessage(ctx,SeverityInformation,"AbortDfuWorkunit",s.str());
  1622. }
  1623. FILESERVICES_API void FILESERVICES_CALL fsMonitorLogicalFileName(ICodeContext *ctx, const char *eventname, const char *_lfn,int shotcount, const char * espServerIpPort)
  1624. {
  1625. CTXFREE(parentCtx, fsfMonitorLogicalFileName(ctx, eventname, _lfn,shotcount, espServerIpPort));
  1626. }
  1627. FILESERVICES_API char * FILESERVICES_CALL fsfMonitorLogicalFileName(ICodeContext *ctx, const char *eventname, const char *_lfn,int shotcount, const char * espServerIpPort)
  1628. {
  1629. CClientFileSpray server;
  1630. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1631. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  1632. setServerAccess(server, wu);
  1633. StringBuffer lfn;
  1634. constructLogicalName(ctx, _lfn, lfn);
  1635. if (shotcount == 0)
  1636. shotcount = -1;
  1637. Owned<IClientDfuMonitorRequest> req = server.createDfuMonitorRequest();
  1638. setContainerLocalCertificate(req->rpc());
  1639. req->setEventName(eventname);
  1640. req->setLogicalName(lfn);
  1641. req->setShotLimit(shotcount);
  1642. Owned<IClientDfuMonitorResponse> result = server.DfuMonitor(req);
  1643. StringBuffer res(result->getWuid());
  1644. StringBuffer s("MonitorLogicalFileName ('");
  1645. s.append(lfn).append("'): ").append(res);
  1646. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1647. wu.clear();
  1648. if (res.length()!=0)
  1649. blockUntilComplete("MonitorLogicalFileName",server,ctx,res.str(),1000*60*60,NULL,true);
  1650. return res.detach();
  1651. }
  1652. FILESERVICES_API void FILESERVICES_CALL fsMonitorFile(ICodeContext *ctx, const char *eventname,const char *ip, const char *filename, bool sub, int shotcount, const char * espServerIpPort)
  1653. {
  1654. CTXFREE(parentCtx, fsfMonitorFile(ctx, eventname,ip, filename, sub, shotcount, espServerIpPort));
  1655. }
  1656. FILESERVICES_API char * FILESERVICES_CALL fsfMonitorFile(ICodeContext *ctx, const char *eventname,const char *ip, const char *filename, bool sub, int shotcount, const char * espServerIpPort)
  1657. {
  1658. CClientFileSpray server;
  1659. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1660. server.addServiceUrl(getAccessibleEspServerURL(espServerIpPort,wu));
  1661. setServerAccess(server, wu);
  1662. if (shotcount == 0)
  1663. shotcount = -1;
  1664. Owned<IClientDfuMonitorRequest> req = server.createDfuMonitorRequest();
  1665. setContainerLocalCertificate(req->rpc());
  1666. req->setEventName(eventname);
  1667. req->setIp(ip);
  1668. req->setFilename(filename);
  1669. req->setShotLimit(shotcount);
  1670. Owned<IClientDfuMonitorResponse> result = server.DfuMonitor(req);
  1671. StringBuffer res(result->getWuid());
  1672. StringBuffer s("MonitorFile (");
  1673. s.append(ip).append(", '").append(filename).append("'): '").append(res);
  1674. WUmessage(ctx,SeverityInformation,NULL,s.str());
  1675. wu.clear();
  1676. if (res.length()!=0)
  1677. blockUntilComplete("MonitorFile",server,ctx,res.str(),1000*60*60,NULL,true);
  1678. return res.detach();
  1679. }
  1680. FILESERVICES_API void FILESERVICES_CALL fsSetFileDescription(ICodeContext *ctx, const char *logicalfilename, const char *value)
  1681. {
  1682. StringBuffer lfn;
  1683. constructLogicalName(ctx, logicalfilename, lfn);
  1684. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1685. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead, false, false, nullptr, defaultPrivilegedUser);
  1686. if (df) {
  1687. DistributedFilePropertyLock lock(df);
  1688. lock.queryAttributes().setProp("@description",value);
  1689. }
  1690. else
  1691. throw MakeStringException(0, "SetFileDescription: Could not locate file %s", lfn.str());
  1692. }
  1693. FILESERVICES_API char * FILESERVICES_CALL fsGetFileDescription(ICodeContext *ctx, const char *logicalfilename)
  1694. {
  1695. StringBuffer lfn;
  1696. constructLogicalName(ctx, logicalfilename, lfn);
  1697. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1698. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead, false, false, nullptr, defaultPrivilegedUser);
  1699. if (!df)
  1700. throw MakeStringException(0, "GetFileDescription: Could not locate file %s", lfn.str());
  1701. const char * ret = df->queryAttributes().queryProp("@description");
  1702. if (ret)
  1703. return CTXSTRDUP(parentCtx, ret);
  1704. else
  1705. return CTXSTRDUP(parentCtx, "");
  1706. }
  1707. FILESERVICES_API void FILESERVICES_CALL fsRemoteDirectory(size32_t & __lenResult,void * & __result, const char *machine, const char *dir, const char *mask, bool sub)
  1708. {
  1709. MemoryBuffer mb;
  1710. RemoteFilename rfn;
  1711. SocketEndpoint ep(machine);
  1712. if (ep.isNull()){
  1713. if (machine)
  1714. throw MakeStringException(-1, "RemoteDirectory: Could not resolve host '%s'", machine);
  1715. ep.setLocalHost(0);
  1716. }
  1717. rfn.setPath(ep,dir);
  1718. Owned<IFile> f = createIFile(rfn);
  1719. if (f) {
  1720. StringBuffer s;
  1721. StringBuffer ds;
  1722. Owned<IDirectoryIterator> di = f->directoryFiles(mask,sub);
  1723. if (di) {
  1724. ForEach(*di) {
  1725. di->getName(s.clear());
  1726. __int64 fsz = di->getFileSize();
  1727. CDateTime dt;
  1728. di->getModifiedTime(dt);
  1729. size32_t sz = s.length();
  1730. dt.getString(ds.clear());
  1731. ds.padTo(19);
  1732. mb.append(sz).append(sz,s.str()).append(fsz).append(19,ds.str());
  1733. }
  1734. }
  1735. }
  1736. __lenResult = mb.length();
  1737. __result = mb.detach();
  1738. }
  1739. FILESERVICES_API void FILESERVICES_CALL fsLogicalFileList(ICodeContext *ctx, size32_t & __lenResult,void * & __result, const char *mask, bool includenormal, bool includesuper, bool unknownszero, const char *foreigndali)
  1740. {
  1741. IEngineContext *engineCtx = ctx->queryEngineContext();
  1742. if (engineCtx && !engineCtx->allowDaliAccess())
  1743. {
  1744. Owned<IException> e = MakeStringException(-1, "FileServices.LogicalFileList cannot access Dali in this context - this normally means it is being called from a thor slave");
  1745. EXCLOG(e, NULL);
  1746. throw e.getClear();
  1747. }
  1748. MemoryBuffer mb;
  1749. if (!mask||!*mask)
  1750. mask ="*";
  1751. StringBuffer masklower(mask);
  1752. masklower.toLowerCase();
  1753. Owned<IDFAttributesIterator> iter = queryDistributedFileDirectory().getForeignDFAttributesIterator(masklower.str(),ctx->queryUserDescriptor(),true,includesuper,foreigndali);
  1754. if (iter) {
  1755. StringBuffer s;
  1756. ForEach(*iter) {
  1757. IPropertyTree &attr=iter->query();
  1758. const char *name = attr.queryProp("@name");
  1759. if (!name||!*name)
  1760. continue;
  1761. int numsub = attr.getPropInt("@numsubfiles",-1);
  1762. bool issuper = numsub>=0;
  1763. if (issuper) {
  1764. if (!includesuper)
  1765. continue;
  1766. }
  1767. else {
  1768. if (!includenormal)
  1769. continue;
  1770. }
  1771. size32_t sz = strlen(name);
  1772. mb.append(sz).append(sz,name);
  1773. mb.append(issuper);
  1774. __int64 i64;
  1775. __int64 fsz = attr.getPropInt64("@size",-1);
  1776. if ((fsz==-1)&&(unknownszero||(numsub==0)))
  1777. fsz = 0;
  1778. mb.append(fsz);
  1779. i64 = attr.getPropInt64("@recordCount",-1);
  1780. if ((i64==-1)&&(fsz!=-1)) {
  1781. int rsz = attr.getPropInt("@recordSize",0);
  1782. if (rsz>0)
  1783. i64 = fsz/rsz;
  1784. }
  1785. if ((i64==-1)&&(unknownszero||(numsub==0)))
  1786. i64 = 0;
  1787. mb.append(i64);
  1788. attr.getProp("@modified",s.clear());
  1789. s.padTo(19);
  1790. mb.append(19,s.str());
  1791. attr.getProp("@owner",s.clear());
  1792. sz = s.length();
  1793. mb.append(sz).append(sz,s.str());
  1794. attr.getProp("@group",s.clear());
  1795. sz = s.length();
  1796. mb.append(sz).append(sz,s.str());
  1797. }
  1798. }
  1799. __lenResult = mb.length();
  1800. __result = mb.detach();
  1801. }
  1802. FILESERVICES_API void FILESERVICES_CALL fsSuperFileContents(ICodeContext *ctx, size32_t & __lenResult,void * & __result, const char *lsuperfn, bool recurse)
  1803. {
  1804. MemoryBuffer mb;
  1805. Owned<ISimpleSuperFileEnquiry> enq;
  1806. if (!recurse)
  1807. enq.setown(getSimpleSuperFileEnquiry(ctx, lsuperfn));
  1808. if (enq) {
  1809. StringArray subs;
  1810. enq->getContents(subs);
  1811. ForEachItemIn(i,subs) {
  1812. const char *name = subs.item(i);
  1813. size32_t sz = strlen(name);
  1814. if (!sz)
  1815. continue;
  1816. mb.append(sz).append(sz,name);
  1817. }
  1818. }
  1819. else {
  1820. CImplicitSuperTransaction implicitTransaction(ctx->querySuperFileTransaction());
  1821. Owned<IDistributedSuperFile> file;
  1822. StringBuffer lsfn;
  1823. lookupSuperFile(ctx, lsuperfn, file, true, lsfn, true);
  1824. Owned<IDistributedFileIterator> iter = file->getSubFileIterator(recurse);
  1825. StringBuffer name;
  1826. ForEach(*iter) {
  1827. iter->getName(name.clear());
  1828. size32_t sz = name.length();
  1829. if (!sz)
  1830. continue;
  1831. mb.append(sz).append(sz,name.str());
  1832. }
  1833. }
  1834. __lenResult = mb.length();
  1835. __result = mb.detach();
  1836. }
  1837. FILESERVICES_API void FILESERVICES_CALL fsLogicalFileSuperOwners(ICodeContext *ctx,size32_t & __lenResult,void * & __result, const char *logicalfilename)
  1838. {
  1839. MemoryBuffer mb;
  1840. StringBuffer lfn;
  1841. constructLogicalName(ctx, logicalfilename, lfn);
  1842. StringArray owners;
  1843. if (queryDistributedFileDirectory().getFileSuperOwners(lfn.str(),owners)) {
  1844. ForEachItemIn(i,owners) {
  1845. const char *name = owners.item(i);
  1846. size32_t sz = strlen(name);
  1847. if (!sz)
  1848. continue;
  1849. mb.append(sz).append(sz,name);
  1850. }
  1851. }
  1852. else {
  1853. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1854. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc,AccessMode::tbdRead,false,true, nullptr, defaultPrivilegedUser); // lock super-owners
  1855. if (df) {
  1856. Owned<IDistributedSuperFileIterator> iter = df->getOwningSuperFiles();
  1857. ForEach(*iter) {
  1858. const char *name = iter->queryName();
  1859. size32_t sz = strlen(name);
  1860. if (!sz)
  1861. continue;
  1862. mb.append(sz).append(sz,name);
  1863. }
  1864. }
  1865. else
  1866. throw MakeStringException(0, "LogicalFileSuperOwners: Could not locate file %s", lfn.str());
  1867. }
  1868. __lenResult = mb.length();
  1869. __result = mb.detach();
  1870. }
  1871. FILESERVICES_API int FILESERVICES_CALL fsCompareFiles(ICodeContext *ctx,const char *name1, const char *name2,bool logicalonly, bool usecrcs)
  1872. {
  1873. StringBuffer lfn1;
  1874. constructLogicalName(ctx, name1, lfn1);
  1875. StringBuffer lfn2;
  1876. constructLogicalName(ctx, name2, lfn2);
  1877. StringBuffer retstr;
  1878. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1879. int ret = queryDistributedFileDirectory().fileCompare(lfn1.str(),lfn2.str(),usecrcs?DFS_COMPARE_FILES_PHYSICAL_CRCS:(logicalonly?DFS_COMPARE_FILES_LOGICAL:DFS_COMPARE_FILES_PHYSICAL),retstr,udesc);
  1880. if (ret==DFS_COMPARE_RESULT_FAILURE)
  1881. throw MakeStringException(ret,"CompareLogicalFiles: %s",retstr.str());
  1882. return ret;
  1883. }
  1884. FILESERVICES_API char * FILESERVICES_CALL fsVerifyFile(ICodeContext *ctx,const char *name,bool usecrcs)
  1885. {
  1886. StringBuffer lfn;
  1887. constructLogicalName(ctx, name, lfn);
  1888. StringBuffer retstr;
  1889. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  1890. if (queryDistributedFileDirectory().filePhysicalVerify(lfn.str(),udesc,usecrcs,retstr))
  1891. retstr.append("OK");
  1892. return retstr.detach();
  1893. }
  1894. // RemotePull
  1895. /*
  1896. varstring RemotePull(
  1897. const varstring remoteEspFsURL, // remote ESP URL e.g. 'http://10.173.34.60:8010/FileSpray'
  1898. const varstring sourceLogicalName, // local
  1899. const varstring destinationGroup, // remote
  1900. const varstring destinationLogicalName, // remote (NB full name required)
  1901. integer4 timeOut=-1,
  1902. integer4 maxConnections=-1,
  1903. boolean allowoverwrite=false,
  1904. boolean replicate=false,
  1905. boolean asSuperfile=false);
  1906. */
  1907. FILESERVICES_API char * FILESERVICES_CALL fsfRemotePull_impl(ICodeContext *ctx,
  1908. const char * remoteEspFsURL,
  1909. const char * sourceLogicalName,
  1910. const char *destinationGroup,
  1911. const char * destinationLogicalName,
  1912. int timeOut,
  1913. int maxConnections,
  1914. bool overwrite,
  1915. bool replicate,
  1916. bool asSuperfile,
  1917. bool forcePush,
  1918. int transferBufferSize,
  1919. bool wrap,
  1920. bool compress,
  1921. bool noSplit,
  1922. int expireDays,
  1923. const char *username,
  1924. const char *userPw)
  1925. {
  1926. LOG(MCauditInfo, "RemotePull(%s): %s%s", remoteEspFsURL,sourceLogicalName,asSuperfile?" as superfile":"");
  1927. CClientFileSpray server;
  1928. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  1929. server.addServiceUrl(remoteEspFsURL);
  1930. setServerAccess(server, wu);
  1931. Owned<IClientCopy> req = server.createCopyRequest();
  1932. setContainerLocalCertificate(req->rpc());
  1933. if (asSuperfile)
  1934. req->setSuperCopy(true);
  1935. StringBuffer _sourceLogicalName, _destinationLogicalName;
  1936. constructLogicalName(wu, sourceLogicalName, _sourceLogicalName);
  1937. // destination name assumed complete (so just skip ~ *)
  1938. while ((*destinationLogicalName=='~')||isspace(*destinationLogicalName))
  1939. destinationLogicalName++;
  1940. _destinationLogicalName.append(destinationLogicalName);
  1941. if (strstr(_destinationLogicalName.str(),"::")==NULL)
  1942. _destinationLogicalName.insert(0,".::");
  1943. StringBuffer _destGroup;
  1944. _destGroup.append(destinationGroup);
  1945. req->setSourceLogicalName(_sourceLogicalName.str());
  1946. req->setDestLogicalName(_destinationLogicalName.str());
  1947. req->setDestGroup(_destGroup.str());
  1948. if (compress)
  1949. req->setCompress(true);
  1950. if (wrap)
  1951. req->setWrap(true);
  1952. StringBuffer sourceDali;
  1953. queryCoven().queryComm().queryGroup().queryNode(0).endpoint().getUrlStr(sourceDali);
  1954. req->setSourceDali(sourceDali);
  1955. req->setOverwrite(overwrite);
  1956. req->setReplicate(replicate);
  1957. if (forcePush)
  1958. req->setPush(true);
  1959. if (transferBufferSize>0)
  1960. req->setTransferBufferSize(transferBufferSize);
  1961. if (noSplit)
  1962. req->setNosplit(true);
  1963. req->setExpireDays(expireDays);
  1964. // Handle username/psw
  1965. if (!isEmptyString(username))
  1966. {
  1967. server.setUsernameToken(username, userPw, nullptr);
  1968. req->setSrcusername(username);
  1969. if (!isEmptyString(userPw))
  1970. req->setSrcpassword(userPw);
  1971. }
  1972. Owned<IClientCopyResponse> result = server.Copy(req);
  1973. StringBuffer wuid(result->getResult());
  1974. if (!wuid.length())
  1975. {
  1976. const IMultiException* excep = &result->getExceptions();
  1977. if ((excep != NULL) && (excep->ordinality() > 0))
  1978. {
  1979. StringBuffer errmsg;
  1980. excep->errorMessage(errmsg);
  1981. throw MakeStringExceptionDirect(0, errmsg.str());
  1982. }
  1983. else
  1984. {
  1985. throw MakeStringExceptionDirect(0, "Result's dfu WUID is empty");
  1986. }
  1987. }
  1988. wu.clear();
  1989. blockUntilComplete("RemotePull", server, ctx, wuid, timeOut);
  1990. return wuid.detach();
  1991. }
  1992. FILESERVICES_API char * FILESERVICES_CALL fsfRemotePull(ICodeContext *ctx,
  1993. const char * remoteEspFsURL,
  1994. const char * sourceLogicalName,
  1995. const char *destinationGroup,
  1996. const char * destinationLogicalName,
  1997. int timeOut,
  1998. int maxConnections,
  1999. bool overwrite,
  2000. bool replicate,
  2001. bool asSuperfile,
  2002. bool forcePush,
  2003. int transferBufferSize,
  2004. bool wrap,
  2005. bool compress)
  2006. {
  2007. return fsfRemotePull_impl(ctx, remoteEspFsURL, sourceLogicalName, destinationGroup, destinationLogicalName, timeOut, maxConnections, overwrite, replicate, asSuperfile,forcePush,transferBufferSize, wrap, compress, false, -1, nullptr, nullptr);
  2008. }
  2009. FILESERVICES_API void FILESERVICES_CALL fsRemotePull(ICodeContext *ctx,
  2010. const char * remoteEspFsURL,
  2011. const char * sourceLogicalName,
  2012. const char *destinationGroup,
  2013. const char * destinationLogicalName,
  2014. int timeOut,
  2015. int maxConnections,
  2016. bool overwrite,
  2017. bool replicate,
  2018. bool asSuperfile,
  2019. bool forcePush,
  2020. int transferBufferSize,
  2021. bool wrap,
  2022. bool compress)
  2023. {
  2024. CTXFREE(parentCtx, fsfRemotePull_impl(ctx, remoteEspFsURL, sourceLogicalName, destinationGroup, destinationLogicalName, timeOut, maxConnections, overwrite, replicate, asSuperfile,forcePush,transferBufferSize, wrap, compress, false, -1, nullptr, nullptr));
  2025. }
  2026. FILESERVICES_API char * FILESERVICES_CALL fsfRemotePull_v2(ICodeContext *ctx,
  2027. const char * remoteEspFsURL,
  2028. const char * sourceLogicalName,
  2029. const char *destinationGroup,
  2030. const char * destinationLogicalName,
  2031. int timeOut,
  2032. int maxConnections,
  2033. bool overwrite,
  2034. bool replicate,
  2035. bool asSuperfile,
  2036. bool forcePush,
  2037. int transferBufferSize,
  2038. bool wrap,
  2039. bool compress,
  2040. bool noSplit,
  2041. int expireDays)
  2042. {
  2043. return fsfRemotePull_impl(ctx, remoteEspFsURL, sourceLogicalName, destinationGroup, destinationLogicalName, timeOut, maxConnections, overwrite, replicate, asSuperfile,forcePush,transferBufferSize, wrap, compress, noSplit, expireDays, nullptr, nullptr);
  2044. }
  2045. FILESERVICES_API void FILESERVICES_CALL fsRemotePull_v2(ICodeContext *ctx,
  2046. const char * remoteEspFsURL,
  2047. const char * sourceLogicalName,
  2048. const char *destinationGroup,
  2049. const char * destinationLogicalName,
  2050. int timeOut,
  2051. int maxConnections,
  2052. bool overwrite,
  2053. bool replicate,
  2054. bool asSuperfile,
  2055. bool forcePush,
  2056. int transferBufferSize,
  2057. bool wrap,
  2058. bool compress,
  2059. bool noSplit,
  2060. int expireDays)
  2061. {
  2062. CTXFREE(parentCtx, fsfRemotePull_impl(ctx, remoteEspFsURL, sourceLogicalName, destinationGroup, destinationLogicalName, timeOut, maxConnections, overwrite, replicate, asSuperfile,forcePush,transferBufferSize, wrap, compress, noSplit, expireDays, nullptr, nullptr));
  2063. }
  2064. FILESERVICES_API char * FILESERVICES_CALL fsfRemotePull_v3(ICodeContext *ctx,
  2065. const char * remoteEspFsURL,
  2066. const char * sourceLogicalName,
  2067. const char *destinationGroup,
  2068. const char * destinationLogicalName,
  2069. int timeOut,
  2070. int maxConnections,
  2071. bool overwrite,
  2072. bool replicate,
  2073. bool asSuperfile,
  2074. bool forcePush,
  2075. int transferBufferSize,
  2076. bool wrap,
  2077. bool compress,
  2078. bool noSplit,
  2079. int expireDays,
  2080. const char *username,
  2081. const char *userPw)
  2082. {
  2083. return fsfRemotePull_impl(ctx, remoteEspFsURL, sourceLogicalName, destinationGroup, destinationLogicalName, timeOut, maxConnections, overwrite, replicate, asSuperfile,forcePush,transferBufferSize, wrap, compress, noSplit, expireDays, username, userPw);
  2084. }
  2085. FILESERVICES_API void FILESERVICES_CALL fsRemotePull_v3(ICodeContext *ctx,
  2086. const char * remoteEspFsURL,
  2087. const char * sourceLogicalName,
  2088. const char *destinationGroup,
  2089. const char * destinationLogicalName,
  2090. int timeOut,
  2091. int maxConnections,
  2092. bool overwrite,
  2093. bool replicate,
  2094. bool asSuperfile,
  2095. bool forcePush,
  2096. int transferBufferSize,
  2097. bool wrap,
  2098. bool compress,
  2099. bool noSplit,
  2100. int expireDays,
  2101. const char *username,
  2102. const char *userPw)
  2103. {
  2104. CTXFREE(parentCtx, fsfRemotePull_impl(ctx, remoteEspFsURL, sourceLogicalName, destinationGroup, destinationLogicalName, timeOut, maxConnections, overwrite, replicate, asSuperfile,forcePush,transferBufferSize, wrap, compress, noSplit, expireDays, username, userPw));
  2105. }
  2106. FILESERVICES_API void FILESERVICES_CALL fsLogicalFileSuperSubList(ICodeContext *ctx, size32_t & __lenResult,void * & __result)
  2107. {
  2108. MemoryBuffer mb;
  2109. getLogicalFileSuperSubList(mb, ctx->queryUserDescriptor());
  2110. __lenResult = mb.length();
  2111. __result = mb.detach();
  2112. }
  2113. FILESERVICES_API void FILESERVICES_CALL fsPromoteSuperFileList(ICodeContext * ctx,bool isAllLsuperfns,size32_t lenLsuperfns,const void * lsuperfns,const char * addhead,bool deltail,bool createonlyonesuperfile,bool reverse)
  2114. {
  2115. CTXFREE(parentCtx, fsfPromoteSuperFileList(ctx,isAllLsuperfns,lenLsuperfns,lsuperfns,addhead,deltail,createonlyonesuperfile,reverse));
  2116. }
  2117. FILESERVICES_API char * FILESERVICES_CALL fsfPromoteSuperFileList(ICodeContext * ctx,bool isAllLsuperfns,size32_t lenLsuperfns,const void * lsuperfns,const char * addhead,bool deltail,bool createonlyonesuperfile,bool reverse)
  2118. {
  2119. Owned<IConstWorkUnit> wu = getWorkunit(ctx);
  2120. MemoryBuffer mb;
  2121. StringBuffer lfn;
  2122. UnsignedArray lfnofs;
  2123. const char *s = (const char *)lsuperfns;
  2124. // MORE - For now, we need a local transaction
  2125. CheckNotInTransaction(ctx, "PromoteSuperFile");
  2126. while ((size32_t)(s-(const char *)lsuperfns)<lenLsuperfns) {
  2127. constructLogicalName(wu,s,lfn.clear());
  2128. lfnofs.append(mb.length());
  2129. mb.append(lfn);
  2130. s = s+strlen(s)+1;
  2131. }
  2132. PointerArray lfns;
  2133. ForEachItemIn(i,lfnofs) {
  2134. lfns.append((void *)(mb.toByteArray()+lfnofs.item(reverse?(lfnofs.ordinality()-i-1):i)));
  2135. }
  2136. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2137. StringArray toadd;
  2138. toadd.appendListUniq(addhead, ",");
  2139. StringBuffer addlist;
  2140. ForEachItemIn(i1,toadd) {
  2141. if (addlist.length())
  2142. addlist.append(',');
  2143. constructLogicalName(wu,toadd.item(i1),addlist);
  2144. }
  2145. toadd.kill();
  2146. queryDistributedFileDirectory().promoteSuperFiles(lfns.ordinality(),(const char **)lfns.getArray(),addlist.str(),deltail,createonlyonesuperfile,udesc.get(),(unsigned)-1,toadd);
  2147. addlist.clear();
  2148. ForEachItemIn(i2,toadd) {
  2149. if (addlist.length())
  2150. addlist.append(',');
  2151. constructLogicalName(wu,toadd.item(i2),addlist);
  2152. }
  2153. return addlist.detach();
  2154. }
  2155. FILESERVICES_API unsigned __int64 FILESERVICES_CALL fsGetUniqueInteger(ICodeContext * ctx, const char *foreigndali)
  2156. {
  2157. SocketEndpoint ep;
  2158. if (foreigndali&&*foreigndali)
  2159. ep.set(foreigndali);
  2160. IEngineContext *engineContext = ctx->queryEngineContext();
  2161. if (engineContext)
  2162. return engineContext->getGlobalUniqueIds(1,&ep);
  2163. return getGlobalUniqueIds(1,&ep);
  2164. }
  2165. FILESERVICES_API void FILESERVICES_CALL fsAddFileRelationship(ICodeContext * ctx,const char *primary, const char *secondary, const char *primflds, const char *secflds, const char *kind, const char *cardinality, bool payload, const char *description)
  2166. {
  2167. StringBuffer pfn;
  2168. constructLogicalName(ctx, primary, pfn);
  2169. StringBuffer sfn;
  2170. constructLogicalName(ctx, secondary, sfn);
  2171. queryDistributedFileDirectory().addFileRelationship(pfn.str(),sfn.str(),primflds,secflds,kind,cardinality,payload,ctx->queryUserDescriptor(), description);
  2172. StringBuffer s("AddFileRelationship('");
  2173. s.append(pfn.str()).append("','").append(sfn.str()).append("','").append(primflds?primflds:"").append("','").append(secflds?secflds:"").append("','").append(kind?kind:"").append("') done");
  2174. WUmessage(ctx,SeverityInformation,NULL,s.str());
  2175. }
  2176. static inline void addmbstr(MemoryBuffer &mb,const char *s)
  2177. {
  2178. size32_t sz = strlen(s);
  2179. mb.append(sz).append(sz,s);
  2180. }
  2181. FILESERVICES_API void FILESERVICES_CALL fsFileRelationshipList(ICodeContext * ctx,size32_t & __lenResult,void * & __result,const char *primary, const char *secondary, const char *primflds, const char *secflds, const char *kind)
  2182. {
  2183. StringBuffer pfn;
  2184. if (primary&&*primary)
  2185. constructLogicalName(ctx, primary, pfn);
  2186. StringBuffer sfn;
  2187. if (secondary&&*secondary)
  2188. constructLogicalName(ctx, secondary, sfn);
  2189. MemoryBuffer mb;
  2190. Owned<IFileRelationshipIterator> iter = queryDistributedFileDirectory().lookupFileRelationships(pfn.str(),sfn.str(),primflds,secflds,kind);
  2191. if (iter) {
  2192. StringBuffer s;
  2193. ForEach(*iter) {
  2194. IFileRelationship &rel=iter->query();
  2195. addmbstr(mb,rel.queryPrimaryFilename());
  2196. addmbstr(mb,rel.querySecondaryFilename());
  2197. addmbstr(mb,rel.queryPrimaryFields());
  2198. addmbstr(mb,rel.querySecondaryFields());
  2199. addmbstr(mb,rel.queryKind());
  2200. addmbstr(mb,rel.queryCardinality());
  2201. mb.append((byte)(rel.isPayload()?1:0));
  2202. addmbstr(mb,rel.queryDescription());
  2203. }
  2204. }
  2205. __lenResult = mb.length();
  2206. __result = mb.detach();
  2207. }
  2208. FILESERVICES_API void FILESERVICES_CALL fsRemoveFileRelationship(ICodeContext * ctx,const char *primary, const char *secondary, const char *primflds, const char *secflds, const char *kind)
  2209. {
  2210. StringBuffer pfn;
  2211. if (primary&&*primary)
  2212. constructLogicalName(ctx, primary, pfn);
  2213. StringBuffer sfn;
  2214. if (secondary&&*secondary)
  2215. constructLogicalName(ctx, secondary, sfn);
  2216. queryDistributedFileDirectory().removeFileRelationships(pfn.str(),sfn.str(),primflds,secflds,kind);
  2217. }
  2218. FILESERVICES_API void FILESERVICES_CALL fsSetColumnMapping(ICodeContext * ctx,const char *filename, const char *mapping)
  2219. {
  2220. StringBuffer lfn;
  2221. constructLogicalName(ctx, filename, lfn);
  2222. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),ctx->queryUserDescriptor(),AccessMode::tbdWrite,false,false,nullptr,defaultPrivilegedUser);
  2223. if (df)
  2224. df->setColumnMapping(mapping);
  2225. else
  2226. throw MakeStringException(-1, "SetColumnMapping: Could not find logical file %s", lfn.str());
  2227. }
  2228. FILESERVICES_API char * FILESERVICES_CALL fsfGetColumnMapping(ICodeContext * ctx,const char *filename)
  2229. {
  2230. StringBuffer lfn;
  2231. constructLogicalName(ctx, filename, lfn);
  2232. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),ctx->queryUserDescriptor(),AccessMode::tbdWrite,false,false,nullptr,defaultPrivilegedUser);
  2233. if (df) {
  2234. StringBuffer mapping;
  2235. df->getColumnMapping(mapping);
  2236. return mapping.detach();
  2237. }
  2238. throw MakeStringException(-1, "GetColumnMapping: Could not find logical file %s", lfn.str());
  2239. return NULL;
  2240. }
  2241. FILESERVICES_API char * FILESERVICES_CALL fsfRfsQuery(const char *server, const char *query)
  2242. {
  2243. StringBuffer ret;
  2244. ret.append('~');
  2245. CDfsLogicalFileName lfn;
  2246. lfn.setQuery(server,query);
  2247. if (!lfn.isSet())
  2248. throw MakeStringException(-1, "RfsQuery invalid parameter");
  2249. return lfn.get(ret).detach();
  2250. }
  2251. FILESERVICES_API void FILESERVICES_CALL fsRfsAction(const char *server, const char *query)
  2252. {
  2253. CDfsLogicalFileName lfn;
  2254. lfn.setQuery(server,query);
  2255. if (!lfn.isSet())
  2256. throw MakeStringException(-1, "RfsAction invalid parameter");
  2257. RemoteFilename rfn;
  2258. lfn.getExternalFilename(rfn);
  2259. Owned<IFile> file = createIFile(rfn);
  2260. Owned<IFileIO> fileio = file->open(IFOread);
  2261. if (fileio) {
  2262. // lets just try reading a byte to cause action
  2263. byte b;
  2264. fileio->read(0,sizeof(b),&b);
  2265. }
  2266. }
  2267. FILESERVICES_API char * FILESERVICES_CALL fsfGetHostName(const char *ipaddress)
  2268. {
  2269. // not a common routine (no Jlib function!) only support IPv4 initially
  2270. StringBuffer ret;
  2271. if (ipaddress&&*ipaddress) {
  2272. IpAddress ip(ipaddress);
  2273. lookupHostName(ip,ret);
  2274. }
  2275. else
  2276. GetHostName(ret);
  2277. return ret.detach();
  2278. }
  2279. FILESERVICES_API char * FILESERVICES_CALL fsfResolveHostName(const char *hostname)
  2280. {
  2281. StringBuffer ret;
  2282. SocketEndpoint ep(hostname);
  2283. ep.getIpText(ret);
  2284. return ret.detach();
  2285. }
  2286. static void checkExternalFileRights(ICodeContext *ctx, CDfsLogicalFileName &lfn, bool rd,bool wr)
  2287. {
  2288. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2289. unsigned auditflags = 0;
  2290. if (rd)
  2291. auditflags |= (DALI_LDAP_AUDIT_REPORT|DALI_LDAP_READ_WANTED);
  2292. if (wr)
  2293. auditflags |= (DALI_LDAP_AUDIT_REPORT|DALI_LDAP_WRITE_WANTED);
  2294. SecAccessFlags perm = queryDistributedFileDirectory().getFilePermissions(lfn.get(),udesc,auditflags);
  2295. if (wr) {
  2296. if (!HASWRITEPERMISSION(perm)) {
  2297. throw MakeStringException(-1,"Write permission denied for %s", lfn.get());
  2298. }
  2299. }
  2300. if (rd) {
  2301. if (!HASREADPERMISSION(perm)) {
  2302. throw MakeStringException(-1,"Read permission denied for %s", lfn.get());
  2303. }
  2304. }
  2305. }
  2306. FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile(ICodeContext * ctx,const char *location,const char *frompath,const char *topath)
  2307. {
  2308. SocketEndpoint ep(location);
  2309. if (ep.isNull())
  2310. throw MakeStringException(-1,"fsMoveExternalFile: Cannot resolve location %s",location);
  2311. CDfsLogicalFileName from;
  2312. from.setExternal(location,frompath);
  2313. CDfsLogicalFileName to;
  2314. to.setExternal(location,topath);
  2315. checkExternalFileRights(ctx,from,true,true);
  2316. checkExternalFileRights(ctx,to,false,true);
  2317. RemoteFilename fromrfn;
  2318. fromrfn.setPath(ep,frompath);
  2319. RemoteFilename torfn;
  2320. torfn.setPath(ep,topath);
  2321. Owned<IFile> fileto = createIFile(torfn);
  2322. if (fileto->exists())
  2323. throw MakeStringException(-1,"fsMoveExternalFile: Destination %s already exists", topath);
  2324. fileto.clear();
  2325. Owned<IFile> file = createIFile(fromrfn);
  2326. file->move(topath);
  2327. StringBuffer s("MoveExternalFile ('");
  2328. s.append(location).append(',').append(frompath).append(',').append(topath).append(") done");
  2329. WUmessage(ctx,SeverityInformation,NULL,s.str());
  2330. AuditMessage(ctx,"MoveExternalFile",frompath,topath);
  2331. }
  2332. FILESERVICES_API void FILESERVICES_CALL fsDeleteExternalFile(ICodeContext * ctx,const char *location,const char *path)
  2333. {
  2334. SocketEndpoint ep(location);
  2335. if (ep.isNull())
  2336. throw MakeStringException(-1,"fsDeleteExternalFile: Cannot resolve location %s",location);
  2337. CDfsLogicalFileName lfn;
  2338. lfn.setExternal(location,path);
  2339. checkExternalFileRights(ctx,lfn,false,true);
  2340. RemoteFilename rfn;
  2341. rfn.setPath(ep,path);
  2342. Owned<IFile> file = createIFile(rfn);
  2343. file->remove();
  2344. StringBuffer s("DeleteExternalFile ('");
  2345. s.append(location).append(',').append(path).append(") done");
  2346. WUmessage(ctx,SeverityInformation,NULL,s.str());
  2347. AuditMessage(ctx,"DeleteExternalFile",path);
  2348. }
  2349. FILESERVICES_API void FILESERVICES_CALL fsCreateExternalDirectory(ICodeContext * ctx,const char *location,const char *_path)
  2350. {
  2351. SocketEndpoint ep(location);
  2352. if (ep.isNull())
  2353. throw MakeStringException(-1, "fsCreateExternalDirectory: Cannot resolve location %s",location);
  2354. CDfsLogicalFileName lfn;
  2355. StringBuffer path(_path);
  2356. if (0 == path.length())
  2357. throw MakeStringException(-1, "fsCreateExternalDirectory: empty directory");
  2358. // remove trailing path separator if present to make it look like a regular LFN after lfn.setExternal
  2359. if (isPathSepChar(path.charAt(path.length()-1)))
  2360. path.remove(path.length()-1, 1);
  2361. lfn.setExternal(location,path);
  2362. checkExternalFileRights(ctx,lfn,false,true);
  2363. RemoteFilename rfn;
  2364. rfn.setPath(ep,path);
  2365. Owned<IFile> file = createIFile(rfn);
  2366. file->createDirectory();
  2367. StringBuffer s("CreateExternalDirectory ('");
  2368. s.append(location).append(',').append(path).append(") done");
  2369. WUmessage(ctx,SeverityInformation,NULL,s.str());
  2370. AuditMessage(ctx,"CreateExternalDirectory",path);
  2371. }
  2372. FILESERVICES_API char * FILESERVICES_CALL fsfGetLogicalFileAttribute(ICodeContext * ctx,const char *_lfn,const char *attrname)
  2373. {
  2374. StringBuffer lfn;
  2375. constructLogicalName(ctx, _lfn, lfn);
  2376. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2377. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead,false, false, nullptr, defaultPrivilegedUser);
  2378. StringBuffer ret;
  2379. if (df) {
  2380. if (strcmp(attrname,"ECL")==0)
  2381. df->getECL(ret);
  2382. else if (strcmp(attrname,"clusterName")==0)
  2383. df->getClusterName(0,ret);
  2384. else if (strcmp(attrname,"partmask")==0)
  2385. ret.append(df->queryPartMask());
  2386. else if (strcmp(attrname,"directory")==0)
  2387. ret.append(df->queryDefaultDir());
  2388. else if (strcmp(attrname,"numparts")==0)
  2389. ret.append(df->numParts());
  2390. else if (strcmp(attrname,"name")==0)
  2391. ret.append(df->queryLogicalName());
  2392. else if (strcmp(attrname,"modified")==0) {
  2393. CDateTime dt;
  2394. df->getModificationTime(dt);
  2395. dt.getString(ret);
  2396. }
  2397. else if (strcmp(attrname,"protected")==0) {
  2398. IPropertyTree &attr = df->queryAttributes();
  2399. Owned<IPropertyTreeIterator> piter = attr.getElements("Protect");
  2400. ForEach(*piter) {
  2401. const char *name = piter->query().queryProp("@name");
  2402. if (name&&*name) {
  2403. if (ret.length())
  2404. ret.append(',');
  2405. ret.append(name);
  2406. }
  2407. }
  2408. }
  2409. else {
  2410. StringBuffer xpath("@");
  2411. xpath.append(attrname);
  2412. IPropertyTree &attr = df->queryAttributes();
  2413. attr.getProp(xpath.str(),ret);
  2414. }
  2415. }
  2416. else
  2417. throw MakeStringException(0, "GetLogicalFileAttribute: Could not find logical file %s", lfn.str());
  2418. return ret.detach();
  2419. }
  2420. FILESERVICES_API void FILESERVICES_CALL fsProtectLogicalFile(ICodeContext * ctx, const char *_lfn, bool set)
  2421. {
  2422. StringBuffer lfn;
  2423. constructLogicalName(ctx, _lfn, lfn);
  2424. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2425. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(), udesc, AccessMode::tbdRead, false, false, nullptr, defaultPrivilegedUser);
  2426. if (df)
  2427. {
  2428. StringBuffer uname;
  2429. udesc->getUserName(uname);
  2430. df->setProtect(uname, set);
  2431. if (!set)
  2432. {
  2433. // for backward compatibility only (see HPCC-23190)
  2434. uname.clear().append("user:");
  2435. udesc->getUserName(uname);
  2436. df->setProtect(uname, false);
  2437. }
  2438. }
  2439. else if (set)
  2440. throw MakeStringException(0, "ProtectLogicalFile: Could not find logical file %s", lfn.str());
  2441. }
  2442. static bool build_dfuplus_globals(int argc, const char *argv[], IProperties * globals)
  2443. {
  2444. for (int i = 1; i < argc; i++)
  2445. if (strchr(argv[i],'='))
  2446. globals->loadProp(argv[i]);
  2447. StringBuffer tmp;
  2448. if (globals->hasProp("encrypt")) {
  2449. encrypt(tmp.clear(),globals->queryProp("encrypt") ); // basic encryption at this stage
  2450. globals->setProp("encrypt",tmp.str());
  2451. }
  2452. if (globals->hasProp("decrypt")) {
  2453. encrypt(tmp.clear(),globals->queryProp("decrypt") ); // basic encryption at this stage
  2454. globals->setProp("decrypt",tmp.str());
  2455. }
  2456. return true;
  2457. }
  2458. FILESERVICES_API void FILESERVICES_CALL fsDfuPlusExec(ICodeContext * ctx,const char *_cmd)
  2459. {
  2460. if (!_cmd||!*_cmd)
  2461. return;
  2462. MemoryBuffer mb;
  2463. const char **argv;
  2464. StringBuffer cmdline;
  2465. if (strcmp(_cmd,"dfuplus ")!=0)
  2466. cmdline.append("dfuplus ");
  2467. cmdline.append(_cmd);
  2468. int argc = parseCommandLine(cmdline.str(),mb,argv);
  2469. Owned<IProperties> globals = createProperties(true);
  2470. if (!build_dfuplus_globals(argc, argv, globals))
  2471. throw MakeStringException(-1,"DfuPlusExec: invalid command line");
  2472. const char* server = globals->queryProp("server");
  2473. if (!server || !*server)
  2474. throw MakeStringException(-1,"DfuPlusExec: server url not specified");
  2475. const char* action = globals->queryProp("action");
  2476. if (!action || !*action)
  2477. throw MakeStringException(-1,"DfuPlusExec: no action specified");
  2478. if (ctx) {
  2479. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2480. StringBuffer tmp;
  2481. const char* username = globals->queryProp("username");
  2482. if (!username || !*username)
  2483. globals->setProp("username",udesc->getUserName(tmp.clear()).str());;
  2484. const char* passwd = globals->queryProp("password");
  2485. if (!passwd || !*passwd)
  2486. globals->setProp("password",udesc->getPassword(tmp.clear()).str());;
  2487. }
  2488. class cMsg: implements CDfuPlusMessagerIntercept
  2489. {
  2490. ICodeContext * ctx;
  2491. unsigned limit;
  2492. public:
  2493. cMsg(ICodeContext *_ctx)
  2494. {
  2495. limit = 0;
  2496. ctx = _ctx;
  2497. }
  2498. void info(const char *msg)
  2499. {
  2500. if (ctx&&(++limit<100))
  2501. WUmessage(ctx,SeverityInformation,NULL,msg);
  2502. }
  2503. void err(const char *msg)
  2504. {
  2505. throw MakeStringException(-1,"DfuPlusExec: %s",msg);
  2506. }
  2507. } cmsg(ctx);
  2508. try {
  2509. Owned<CDfuPlusHelper> helper = new CDfuPlusHelper(LINK(globals.get()));
  2510. helper->msgintercept = &cmsg;
  2511. helper->doit();
  2512. }
  2513. catch(IException* e) {
  2514. EXCLOG(e,"fsDfuPlusExec");
  2515. throw;
  2516. }
  2517. }
  2518. FILESERVICES_API char * FILESERVICES_CALL fsGetEspURL(const char *username, const char *userPW)
  2519. {
  2520. #ifdef _CONTAINERIZED
  2521. const IPropertyTree *match = nullptr;
  2522. const char *espService = getComponentConfigSP()->queryProp("@defaultEsp");
  2523. Owned<IPropertyTree> globalConfig = getGlobalConfig();
  2524. if (isEmptyString(espService))
  2525. espService = globalConfig->queryProp("@defaultEsp");
  2526. if (!isEmptyString(espService))
  2527. {
  2528. VStringBuffer service("services[@name='%s']", espService);
  2529. match = globalConfig->queryPropTree(service.str());
  2530. }
  2531. if (!match)
  2532. {
  2533. // Look for 'eclservices' esp service, fallback to 'eclwatch' service.
  2534. Owned<IPropertyTreeIterator> iter = globalConfig->getElements("services");
  2535. ForEach(*iter)
  2536. {
  2537. const char *type = iter->query().queryProp("@type");
  2538. if (streq("eclservices", type))
  2539. {
  2540. match = &iter->query();
  2541. break;
  2542. }
  2543. else if (streq("eclwatch", type))
  2544. match = &iter->query();
  2545. }
  2546. }
  2547. if (match) // MORE - if not found, we could generate a warning - it implies something misconfigured!
  2548. {
  2549. if (!espService)
  2550. espService = match->queryProp("@name");
  2551. StringBuffer credentials;
  2552. if (username && username[0] && userPW && userPW[0])
  2553. credentials.setf("%s:%s@", username, userPW);
  2554. else if (username && username[0])
  2555. credentials.setf("%s@", username);
  2556. const char *protocol = match->getPropBool("@tls") ? "https" : "http";
  2557. unsigned port = match->getPropInt("@port", 8010);
  2558. VStringBuffer espURL("mtls:%s://%s%s:%u", protocol, credentials.str(), espService, port);
  2559. return espURL.detach();
  2560. }
  2561. #else
  2562. Owned<IConstEnvironment> daliEnv = openDaliEnvironment();
  2563. Owned<IPropertyTree> env = getEnvironmentTree(daliEnv);
  2564. if (env.get())
  2565. {
  2566. StringBuffer espURL;
  2567. StringBuffer espInstanceComputerName;
  2568. StringBuffer bindingProtocol;
  2569. StringBuffer xpath;
  2570. StringBuffer instanceAddress;
  2571. StringBuffer espServiceType;
  2572. StringBuffer credentials;
  2573. Owned<IPropertyTreeIterator> espProcessIter = env->getElements("Software/EspProcess");
  2574. ForEach(*espProcessIter)
  2575. {
  2576. Owned<IPropertyTreeIterator> espBindingIter = espProcessIter->query().getElements("EspBinding");
  2577. ForEach(*espBindingIter)
  2578. {
  2579. espBindingIter->query().getProp("@service",espURL.clear());
  2580. xpath.setf("Software/EspService[@name=\"%s\"]/Properties/@type", espURL.str());
  2581. if(env->getProp(xpath.str(), espServiceType.clear()))
  2582. {
  2583. if (strieq(espServiceType.str(),"WsSMC"))
  2584. {
  2585. if (espBindingIter->query().getProp("@protocol",bindingProtocol.clear()))
  2586. {
  2587. Owned<IPropertyTreeIterator> espInstanceIter = espProcessIter->query().getElements("Instance");
  2588. ForEach(*espInstanceIter)
  2589. {
  2590. if (espInstanceIter->query().getProp("@computer",espInstanceComputerName.clear()))
  2591. {
  2592. xpath.setf("Hardware/Computer[@name=\"%s\"]/@netAddress",espInstanceComputerName.str());
  2593. if (env->getProp(xpath.str(),instanceAddress.clear()))
  2594. {
  2595. if (username && username[0] && userPW && userPW[0])
  2596. credentials.setf("%s:%s@", username, userPW);
  2597. else if (username && username[0])
  2598. credentials.setf("%s@", username);
  2599. if (streq(instanceAddress.str(),"."))
  2600. {
  2601. SocketEndpoint ep(instanceAddress.str());
  2602. ep.getIpText(instanceAddress.clear());
  2603. }
  2604. espURL.setf("%s://%s%s:%d", bindingProtocol.str(), credentials.str(), instanceAddress.str(), espBindingIter->query().getPropInt("@port",8010));
  2605. return espURL.detach();
  2606. }
  2607. }
  2608. }
  2609. }
  2610. }
  2611. }
  2612. }
  2613. }
  2614. }
  2615. #endif
  2616. return strdup("");
  2617. }
  2618. FILESERVICES_API char * FILESERVICES_CALL fsGetDefaultDropZone()
  2619. {
  2620. StringBuffer dropZonePath;
  2621. Owned<IPropertyTreeIterator> dropZones = getGlobalConfigSP()->getElements("storage/planes[@category='lz']");
  2622. if (dropZones->first())
  2623. dropZones->query().getProp("@prefix", dropZonePath); // Why the directory? seems a very stange choice
  2624. return strdup(dropZonePath.str());
  2625. }
  2626. FILESERVICES_API void FILESERVICES_CALL fsGetDropZones(ICodeContext *ctx, size32_t & __lenResult, void * & __result)
  2627. {
  2628. MemoryBuffer mb;
  2629. Owned<IPropertyTreeIterator> dropZones = getGlobalConfigSP()->getElements("storage/planes[@category='lz']");
  2630. ForEach(*dropZones)
  2631. {
  2632. const char * directory = dropZones->query().queryProp("@prefix");
  2633. size32_t sz = strlen(directory);
  2634. mb.append(sz).append(sz,directory);
  2635. }
  2636. __lenResult = mb.length();
  2637. __result = mb.detach();
  2638. }
  2639. FILESERVICES_API void FILESERVICES_CALL fsGetLandingZones(ICodeContext *ctx, size32_t & __lenResult, void * & __result)
  2640. {
  2641. MemoryBuffer mb;
  2642. size32_t sz;
  2643. Owned<IPropertyTree> global = getGlobalConfig();
  2644. Owned<IPropertyTreeIterator> dropZones = global->getElements("storage/planes[labels='lz']");
  2645. ForEach(*dropZones)
  2646. {
  2647. const IPropertyTree &dropZone = dropZones->query();
  2648. const char * name = dropZone.queryProp("@name");
  2649. const char * directory = dropZone.queryProp("@prefix");
  2650. const char * hostGroup = dropZone.queryProp("@hostGroup");
  2651. // field "name"
  2652. sz = strlen(name);
  2653. mb.append(sz).append(sz,name);
  2654. // field "prefix"
  2655. sz = strlen(directory);
  2656. mb.append(sz).append(sz,directory);
  2657. // field "host"
  2658. const char * host = nullptr;
  2659. if (hostGroup)
  2660. {
  2661. VStringBuffer xpath("storage/hostGroups[@name='%s']", name);
  2662. IPropertyTree * match = global->queryPropTree(xpath);
  2663. if (match)
  2664. host = match->queryProp("hosts[1]");
  2665. }
  2666. sz = host ? strlen(host) : 0;
  2667. mb.append(sz).append(sz, host);
  2668. }
  2669. __lenResult = mb.length();
  2670. __result = mb.detach();
  2671. }
  2672. FILESERVICES_API int FILESERVICES_CALL fsGetExpireDays(ICodeContext * ctx, const char *_lfn)
  2673. {
  2674. StringBuffer lfn;
  2675. constructLogicalName(ctx, _lfn, lfn);
  2676. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2677. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead,false, false, nullptr, defaultPrivilegedUser);
  2678. if (df)
  2679. return df->getExpire();
  2680. else
  2681. throw makeStringExceptionV(0, "GetExpireDays: Could not find logical file %s", lfn.str());
  2682. }
  2683. FILESERVICES_API void FILESERVICES_CALL fsSetExpireDays(ICodeContext * ctx, const char *_lfn, int expireDays)
  2684. {
  2685. if (expireDays < 0)
  2686. throw makeStringExceptionV(0, "SetExpireDays: expireDays parameter value should be >= 0 (%d)", expireDays);
  2687. StringBuffer lfn;
  2688. constructLogicalName(ctx, _lfn, lfn);
  2689. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2690. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead,false, false, nullptr, defaultPrivilegedUser);
  2691. if (df)
  2692. df->setExpire(expireDays);
  2693. else
  2694. throw makeStringExceptionV(0, "SetExpireDays: Could not find logical file %s", lfn.str());
  2695. }
  2696. FILESERVICES_API void FILESERVICES_CALL fsClearExpireDays(ICodeContext * ctx, const char *_lfn)
  2697. {
  2698. StringBuffer lfn;
  2699. constructLogicalName(ctx, _lfn, lfn);
  2700. Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
  2701. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(lfn.str(),udesc, AccessMode::tbdRead,false, false, nullptr, defaultPrivilegedUser);
  2702. if (df)
  2703. df->setExpire(-1);
  2704. else
  2705. throw makeStringExceptionV(0, "ClearExpireDays: Could not find logical file %s", lfn.str());
  2706. }