ws_dfuService.cpp 212 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907
  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. #include <math.h>
  15. #include "daclient.hpp"
  16. #include "daft.hpp"
  17. #include "daftcfg.hpp"
  18. #include "fterror.hpp"
  19. #include "fverror.hpp"
  20. #include "daftprogress.hpp"
  21. #include "mpbase.hpp"
  22. #include "daclient.hpp"
  23. #include "dadfs.hpp"
  24. #include "dafdesc.hpp"
  25. #include "dasds.hpp"
  26. #include "danqs.hpp"
  27. #include "dalienv.hpp"
  28. #include "dautils.hpp"
  29. #include "jfile.hpp"
  30. #include "wshelpers.hpp"
  31. #include "LogicFileWrapper.hpp"
  32. #include "rmtfile.hpp"
  33. #include "dfuutil.hpp"
  34. #include "TpWrapper.hpp"
  35. #include "WUWrapper.hpp"
  36. #include "portlist.h"
  37. #include "roxiecommlib.hpp"
  38. #include "dfuwu.hpp"
  39. #include "fverror.hpp"
  40. #include "nbcd.hpp"
  41. #include "jstring.hpp"
  42. #include "exception_util.hpp"
  43. #include "ws_dfuService.hpp"
  44. #include "hqlerror.hpp"
  45. #include "hqlexpr.hpp"
  46. #include "hqlutil.hpp"
  47. #include "eclrtl.hpp"
  48. #include "package.h"
  49. #include "daaudit.hpp"
  50. #define Action_Delete "Delete"
  51. #define Action_AddtoSuperfile "Add To Superfile"
  52. static const char* FEATURE_URL="DfuAccess";
  53. #define FILE_NEWEST 1
  54. #define FILE_OLDEST 2
  55. #define FILE_LARGEST 3
  56. #define FILE_SMALLEST 4
  57. #define COUNTBY_SCOPE "Scope"
  58. #define COUNTBY_OWNER "Owner"
  59. #define COUNTBY_DATE "Date"
  60. #define COUNTBY_YEAR "Year"
  61. #define COUNTBY_QUARTER "Quarter"
  62. #define COUNTBY_MONTH "Month"
  63. #define COUNTBY_DAY "Day"
  64. #define REMOVE_FILE_SDS_CONNECT_TIMEOUT (1000*15) // 15 seconds
  65. const unsigned NODE_GROUP_CACHE_DEFAULT_TIMEOUT = 30*60*1000; //30 minutes
  66. const unsigned MAX_VIEWKEYFILE_ROWS = 1000;
  67. const unsigned MAX_KEY_ROWS = 20;
  68. short days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  69. CThorNodeGroup* CThorNodeGroupCache::readNodeGroup(const char* _groupName)
  70. {
  71. Owned<IEnvironmentFactory> factory = getEnvironmentFactory(true);
  72. Owned<IConstEnvironment> env = factory->openEnvironment();
  73. Owned<IPropertyTree> root = &env->getPTree();
  74. Owned<IPropertyTreeIterator> it= root->getElements("Software/ThorCluster");
  75. ForEach(*it)
  76. {
  77. IPropertyTree& cluster = it->query();
  78. StringBuffer groupName;
  79. getClusterGroupName(cluster, groupName);
  80. if (groupName.length() && strieq(groupName.str(), _groupName))
  81. return new CThorNodeGroup(_groupName, cluster.getCount("ThorSlaveProcess"), cluster.getPropBool("@replicateOutputs", false));
  82. }
  83. return NULL;
  84. }
  85. CThorNodeGroup* CThorNodeGroupCache::lookup(const char* groupName, unsigned timeout)
  86. {
  87. CriticalBlock block(sect);
  88. CThorNodeGroup* item=SuperHashTableOf<CThorNodeGroup, const char>::find(groupName);
  89. if (item && !item->checkTimeout(timeout))
  90. return LINK(item);
  91. Owned<CThorNodeGroup> e = readNodeGroup(groupName);
  92. if (e)
  93. replace(*e.getLink()); //if not exists, will be added.
  94. return e.getClear();
  95. }
  96. void CWsDfuEx::init(IPropertyTree *cfg, const char *process, const char *service)
  97. {
  98. StringBuffer xpath;
  99. DBGLOG("Initializing %s service [process = %s]", service, process);
  100. espProcess.set(process);
  101. xpath.appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/DefaultScope", process, service);
  102. cfg->getProp(xpath.str(), defaultScope_);
  103. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/User", process, service);
  104. cfg->getProp(xpath.str(), user_);
  105. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/Password", process, service);
  106. cfg->getProp(xpath.str(), password_);
  107. StringBuffer disableUppercaseTranslation;
  108. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/DisableUppercaseTranslation", process, service);
  109. cfg->getProp(xpath.str(), disableUppercaseTranslation);
  110. m_clusterName.clear();
  111. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/ClusterName", process, service);
  112. cfg->getProp(xpath.str(), m_clusterName);
  113. Linked<IPropertyTree> globals;
  114. globals.set(cfg->queryPropTree(StringBuffer("Software/EspProcess[@name=\"").append(process).append("\"]/EspService[@name=\"").append(service).append("\"]").str()));
  115. const char * plugins = globals->queryProp("Plugins/@path");
  116. if (plugins)
  117. queryTransformerRegistry().addPlugins(plugins);
  118. m_disableUppercaseTranslation = false;
  119. if (streq(disableUppercaseTranslation.str(), "true"))
  120. m_disableUppercaseTranslation = true;
  121. xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
  122. if (cfg->hasProp(xpath.str()))
  123. setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
  124. xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
  125. if (cfg->hasProp(xpath.str()))
  126. setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
  127. xpath.setf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/NodeGroupCacheMinutes", process, service);
  128. int timeout = cfg->getPropInt(xpath.str(), -1);
  129. if (timeout > -1)
  130. nodeGroupCacheTimeout = (unsigned) timeout*60*1000;
  131. else
  132. nodeGroupCacheTimeout = NODE_GROUP_CACHE_DEFAULT_TIMEOUT;
  133. thorNodeGroupCache.setown(new CThorNodeGroupCache());
  134. if (!daliClientActive())
  135. throw MakeStringException(-1, "No Dali Connection Active. Please Specify a Dali to connect to in you configuration file");
  136. setDaliServixSocketCaching(true);
  137. }
  138. bool CWsDfuEx::onDFUSearch(IEspContext &context, IEspDFUSearchRequest & req, IEspDFUSearchResponse & resp)
  139. {
  140. try
  141. {
  142. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  143. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to Search Logical Files. Permission denied.");
  144. StringBuffer username;
  145. context.getUserID(username);
  146. Owned<IUserDescriptor> userdesc;
  147. if(username.length() > 0)
  148. {
  149. userdesc.setown(createUserDescriptor());
  150. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  151. }
  152. CTpWrapper dummy;
  153. IArrayOf<IEspTpCluster> clusters;
  154. dummy.getClusterProcessList(eqThorCluster, clusters);
  155. dummy.getHthorClusterList(clusters);
  156. StringArray dfuclusters;
  157. ForEachItemIn(k, clusters)
  158. {
  159. IEspTpCluster& cluster = clusters.item(k);
  160. dfuclusters.append(cluster.getName());
  161. }
  162. IArrayOf<IEspTpCluster> clusters1;
  163. dummy.getClusterProcessList(eqRoxieCluster, clusters1);
  164. ForEachItemIn(k1, clusters1)
  165. {
  166. IEspTpCluster& cluster = clusters1.item(k1);
  167. StringBuffer slaveName = cluster.getName();
  168. dfuclusters.append(slaveName.str());
  169. }
  170. StringArray ftarray;
  171. ftarray.append("Logical Files and Superfiles");
  172. ftarray.append("Logical Files Only");
  173. ftarray.append("Superfiles Only");
  174. ftarray.append("Not in Superfiles");
  175. if (req.getShowExample() && *req.getShowExample())
  176. resp.setShowExample(req.getShowExample());
  177. resp.setClusterNames(dfuclusters);
  178. resp.setFileTypes(ftarray);
  179. }
  180. catch(IException* e)
  181. {
  182. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  183. }
  184. return true;
  185. }
  186. void addToQueryString(StringBuffer &queryString, const char *name, const char *value)
  187. {
  188. if (queryString.length() > 0)
  189. {
  190. queryString.append("&");
  191. }
  192. queryString.append(name);
  193. queryString.append("=");
  194. queryString.append(value);
  195. }
  196. void addToQueryStringFromInt(StringBuffer &queryString, const char *name, __int64 value)
  197. {
  198. if (queryString.length() > 0)
  199. {
  200. queryString.append("&");
  201. }
  202. queryString.append(name);
  203. queryString.append("=");
  204. queryString.append(value);
  205. }
  206. void parseTwoStringArrays(const char *input, StringArray& strarray1, StringArray& strarray2)
  207. {
  208. if (!input || strlen(input) <= 2)
  209. return;
  210. char c0[2], c1[2];
  211. c0[0] = input[0], c0[1] = 0;
  212. c1[0] = input[1], c1[1] = 0;
  213. //the first string usually is a name; the second is a value
  214. unsigned int name_len = atoi(c0);
  215. unsigned int value_len = atoi(c1);
  216. if (name_len > 0 && value_len > 0)
  217. {
  218. char * inputText = (char *) input;
  219. inputText += 2; //skip 2 chars
  220. for (;;)
  221. {
  222. if (!inputText || strlen(inputText) < name_len + value_len)
  223. break;
  224. StringBuffer columnNameLenStr, columnValueLenStr;
  225. for (unsigned i_name = 0; i_name < name_len; i_name++)
  226. {
  227. columnNameLenStr.append(inputText[0]);
  228. inputText++;
  229. }
  230. for (unsigned i_value = 0; i_value < value_len; i_value++)
  231. {
  232. columnValueLenStr.append(inputText[0]);
  233. inputText++;
  234. }
  235. unsigned columnNameLen = atoi(columnNameLenStr.str());
  236. unsigned columnValueLen = atoi(columnValueLenStr.str());
  237. if (!inputText || strlen(inputText) < columnNameLen + columnValueLen)
  238. break;
  239. char * colon = inputText + columnNameLen;
  240. if (!colon)
  241. break;
  242. StringAttr tmp;
  243. tmp.set(inputText, columnNameLen);
  244. strarray1.append(tmp.get());
  245. tmp.set(colon, columnValueLen);
  246. //tmp.toUpperCase();
  247. strarray2.append(tmp.get());
  248. inputText = colon + columnValueLen;
  249. }
  250. }
  251. return;
  252. }
  253. bool CWsDfuEx::onDFUQuery(IEspContext &context, IEspDFUQueryRequest & req, IEspDFUQueryResponse & resp)
  254. {
  255. try
  256. {
  257. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  258. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to Browse Logical Files. Permission denied.");
  259. StringBuffer username;
  260. context.getUserID(username);
  261. Owned<IUserDescriptor> userdesc;
  262. if(username.length() > 0)
  263. {
  264. userdesc.setown(createUserDescriptor());
  265. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  266. }
  267. doLogicalFileSearch(context, userdesc.get(), req, resp);
  268. }
  269. catch(IException* e)
  270. {
  271. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  272. }
  273. return true;
  274. }
  275. bool CWsDfuEx::onDFUInfo(IEspContext &context, IEspDFUInfoRequest &req, IEspDFUInfoResponse &resp)
  276. {
  277. try
  278. {
  279. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  280. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to access DFUInfo. Permission denied.");
  281. StringBuffer username;
  282. context.getUserID(username);
  283. Owned<IUserDescriptor> userdesc;
  284. if(username.length() > 0)
  285. {
  286. userdesc.setown(createUserDescriptor());
  287. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  288. }
  289. if (req.getUpdateDescription())
  290. {
  291. double version = context.getClientVersion();
  292. if (version < 1.38)
  293. doGetFileDetails(context, userdesc.get(), req.getFileName(), req.getCluster(), req.getQuerySet(), req.getQuery(), req.getFileDesc(),
  294. req.getIncludeJsonTypeInfo(), req.getIncludeBinTypeInfo(), resp.updateFileDetail());
  295. else
  296. doGetFileDetails(context, userdesc.get(), req.getName(), req.getCluster(), req.getQuerySet(), req.getQuery(), req.getFileDesc(),
  297. req.getIncludeJsonTypeInfo(), req.getIncludeBinTypeInfo(), resp.updateFileDetail());
  298. }
  299. else
  300. {
  301. doGetFileDetails(context, userdesc.get(), req.getName(), req.getCluster(), req.getQuerySet(), req.getQuery(), NULL,
  302. req.getIncludeJsonTypeInfo(), req.getIncludeBinTypeInfo(), resp.updateFileDetail());
  303. }
  304. }
  305. catch(IException* e)
  306. {
  307. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  308. }
  309. return true;
  310. }
  311. bool CWsDfuEx::onDFUSpace(IEspContext &context, IEspDFUSpaceRequest & req, IEspDFUSpaceResponse & resp)
  312. {
  313. try
  314. {
  315. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  316. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to Browse Space Usage. Permission denied.");
  317. StringBuffer username;
  318. context.getUserID(username);
  319. Owned<IUserDescriptor> userdesc;
  320. if(username.length() > 0)
  321. {
  322. userdesc.setown(createUserDescriptor());
  323. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  324. }
  325. const char *countby = req.getCountBy();
  326. if (!countby || strlen(countby) < 1)
  327. return true;
  328. char *scopeName = NULL;
  329. StringBuffer filter;
  330. if(req.getScopeUnder() && *req.getScopeUnder())
  331. {
  332. scopeName = (char *) req.getScopeUnder();
  333. filter.appendf("%s::*", scopeName);
  334. resp.setScopeUnder(req.getScopeUnder());
  335. }
  336. else
  337. {
  338. filter.append("*");
  339. }
  340. PROGLOG("DFUSpace: filter %s ", filter.str());
  341. Owned<IDFAttributesIterator> fi = queryDistributedFileDirectory().getDFAttributesIterator(filter, userdesc.get(), true, false, NULL);
  342. if(!fi)
  343. throw MakeStringException(ECLWATCH_CANNOT_GET_FILE_ITERATOR,"Cannot get information from file system.");
  344. const char *ownerUnder = NULL;
  345. if(req.getOwnerUnder() && *req.getOwnerUnder())
  346. {
  347. ownerUnder = req.getOwnerUnder();
  348. resp.setOwnerUnder(ownerUnder);
  349. }
  350. StringBuffer wuFrom, wuTo, interval;
  351. unsigned yearFrom = 0, monthFrom, dayFrom, yearTo = 0, monthTo, dayTo, hour, minute, second, nano;
  352. if(req.getStartDate() && *req.getStartDate())
  353. {
  354. CDateTime wuTime;
  355. wuTime.setString(req.getStartDate(),NULL,true);
  356. wuTime.getDate(yearFrom, monthFrom, dayFrom, true);
  357. wuTime.getTime(hour, minute, second, nano, true);
  358. wuFrom.appendf("%4d-%02d-%02d %02d:%02d:%02d",yearFrom,monthFrom,dayFrom,hour,minute,second);
  359. StringBuffer startDate;
  360. startDate.appendf("%02d/%02d/%04d", monthFrom, dayFrom, yearFrom);
  361. resp.setStartDate(startDate.str());
  362. }
  363. if(req.getEndDate() && *req.getEndDate())
  364. {
  365. CDateTime wuTime;
  366. wuTime.setString(req.getEndDate(),NULL,true);
  367. wuTime.getDate(yearTo, monthTo, dayTo, true);
  368. wuTime.getTime(hour, minute, second, nano, true);
  369. wuTo.appendf("%4d-%02d-%02d %02d:%02d:%02d",yearTo,monthTo,dayTo,hour,minute,second);
  370. StringBuffer endDate;
  371. endDate.appendf("%02d/%02d/%04d", monthTo, dayTo, yearTo);
  372. resp.setEndDate(endDate.str());
  373. }
  374. unsigned i = 0;
  375. IArrayOf<IEspSpaceItem> SpaceItems64;
  376. if (!stricmp(countby, COUNTBY_DATE))
  377. {
  378. if (yearFrom < 1 || yearTo < 1)
  379. {
  380. StringBuffer wuFrom, wuTo;
  381. bool bFirst = true;
  382. ForEach(*fi)
  383. {
  384. IPropertyTree &attr=fi->query();
  385. StringBuffer modf(attr.queryProp("@modified"));
  386. //char* t=strchr(modf.str(),'T');
  387. //if(t) *t=' ';
  388. if (bFirst)
  389. {
  390. bFirst = false;
  391. wuFrom = modf.str();
  392. wuTo = modf.str();
  393. continue;
  394. }
  395. if (strcmp(modf.str(),wuFrom.str())<0)
  396. wuFrom = modf.str();
  397. if (strcmp(modf.str(),wuTo.str())>0)
  398. wuTo = modf.str();
  399. }
  400. if (yearFrom < 1)
  401. {
  402. CDateTime wuTime;
  403. wuTime.setString(wuFrom.str(),NULL,true);
  404. wuTime.getDate(yearFrom, monthFrom, dayFrom, true);
  405. }
  406. if (yearTo < 1)
  407. {
  408. CDateTime wuTime;
  409. wuTime.setString(wuTo.str(),NULL,true);
  410. wuTime.getDate(yearTo, monthTo, dayTo, true);
  411. }
  412. }
  413. interval = req.getInterval();
  414. resp.setInterval(interval);
  415. createSpaceItemsByDate(SpaceItems64, interval, yearFrom, monthFrom, dayFrom, yearTo, monthTo, dayTo);
  416. }
  417. else
  418. {
  419. Owned<IEspSpaceItem> item64 = createSpaceItem();
  420. if (stricmp(countby, COUNTBY_OWNER))
  421. {
  422. if (scopeName)
  423. item64->setName(scopeName);
  424. else
  425. item64->setName("(root)");
  426. }
  427. else
  428. {
  429. item64->setName("(empty)");
  430. }
  431. item64->setNumOfFilesInt(0);
  432. item64->setNumOfFilesIntUnknown(0);
  433. item64->setTotalSizeInt(0);
  434. item64->setLargestSizeInt(0);
  435. item64->setSmallestSizeInt(0);
  436. item64->setLargestFile("");
  437. item64->setSmallestFile("");
  438. SpaceItems64.append(*item64.getClear());
  439. }
  440. ForEach(*fi)
  441. {
  442. IPropertyTree &attr=fi->query();
  443. if (attr.hasProp("@numsubfiles"))
  444. continue; //exclude superfiles
  445. if (ownerUnder)
  446. {
  447. const char* owner=attr.queryProp("@owner");
  448. if (owner && stricmp(owner, ownerUnder))
  449. continue;
  450. }
  451. StringBuffer modf(attr.queryProp("@modified"));
  452. char* t= (char *) strchr(modf.str(),'T');
  453. if(t) *t=' ';
  454. if (wuFrom.length() && strcmp(modf.str(),wuFrom.str())<0)
  455. continue;
  456. if (wuTo.length() && strcmp(modf.str(),wuTo.str())>0)
  457. continue;
  458. if (!stricmp(countby, COUNTBY_DATE))
  459. {
  460. setSpaceItemByDate(SpaceItems64, interval, attr.queryProp("@modified"), attr.queryProp("@name"), attr.getPropInt64("@size",-1));
  461. }
  462. else if (!stricmp(countby, COUNTBY_OWNER))
  463. {
  464. setSpaceItemByOwner(SpaceItems64, attr.queryProp("@owner"), attr.queryProp("@name"), attr.getPropInt64("@size",-1));
  465. }
  466. else
  467. {
  468. setSpaceItemByScope(SpaceItems64, scopeName, attr.queryProp("@name"), attr.getPropInt64("@size",-1));
  469. }
  470. }
  471. i = 0;
  472. IEspSpaceItem& item0 = SpaceItems64.item(0);
  473. if (item0.getNumOfFilesInt() < 1)
  474. {
  475. i++;
  476. }
  477. double version = context.getClientVersion();
  478. IArrayOf<IEspDFUSpaceItem> SpaceItems;
  479. for(; i < SpaceItems64.length();i++)
  480. {
  481. IEspSpaceItem& item64 = SpaceItems64.item(i);
  482. if (item64.getNumOfFilesInt() < 1)
  483. continue;
  484. StringBuffer buf;
  485. Owned<IEspDFUSpaceItem> item1 = createDFUSpaceItem("","");
  486. __int64 numOfFiles = item64.getNumOfFilesInt();
  487. __int64 numOfFilesIntUnknown = item64.getNumOfFilesIntUnknown();
  488. __int64 totalSize = item64.getTotalSizeInt();
  489. __int64 largestSize = item64.getLargestSizeInt();
  490. __int64 smallestSize = item64.getSmallestSizeInt();
  491. if (version >= 1.38)
  492. {
  493. item1->setNumOfFilesInt64(numOfFiles);
  494. item1->setNumOfFilesUnknownInt64(numOfFilesIntUnknown);
  495. item1->setTotalSizeInt64(totalSize);
  496. item1->setLargestSizeInt64(largestSize);
  497. item1->setSmallestSizeInt64(smallestSize);
  498. }
  499. item1->setName(item64.getName());
  500. buf << comma(numOfFiles);
  501. item1->setNumOfFiles(buf.str());
  502. buf.clear();
  503. buf << comma(numOfFilesIntUnknown);
  504. item1->setNumOfFilesUnknown(buf.str());
  505. buf.clear();
  506. buf << comma(totalSize);
  507. item1->setTotalSize(buf.str());
  508. buf.clear();
  509. buf << comma(largestSize);
  510. item1->setLargestSize(buf.str());
  511. buf.clear();
  512. buf << comma(smallestSize);
  513. item1->setSmallestSize(buf.str());
  514. item1->setLargestFile(item64.getLargestFile());
  515. item1->setSmallestFile(item64.getSmallestFile());
  516. SpaceItems.append(*item1.getClear());
  517. }
  518. resp.setDFUSpaceItems(SpaceItems);
  519. resp.setCountBy(req.getCountBy());
  520. }
  521. catch(IException* e)
  522. {
  523. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  524. }
  525. return true;
  526. }
  527. bool CWsDfuEx::setSpaceItemByScope(IArrayOf<IEspSpaceItem>& SpaceItems64, const char*scopeName, const char*logicalName, __int64 size)
  528. {
  529. char scope[1024];
  530. scope[0] = 0;
  531. const char* pName = NULL;
  532. if (!scopeName)
  533. {
  534. pName = strstr(logicalName, "::");
  535. if (!pName)
  536. return false;
  537. strncpy(scope, logicalName, pName - logicalName);
  538. scope[pName - logicalName] = 0;
  539. }
  540. else
  541. {
  542. if (strlen(logicalName) <= strlen(scopeName)+2)
  543. return false;
  544. char* ppName = (char*) logicalName + strlen(scopeName) + 2;
  545. pName = strstr(ppName, "::");
  546. if (pName)
  547. {
  548. strncpy(scope, logicalName, pName - logicalName);
  549. scope[pName - logicalName] = 0;
  550. }
  551. }
  552. if (strlen(scope) > 0)
  553. {
  554. IEspSpaceItem *item0 = NULL;
  555. for(unsigned i = 0; i < SpaceItems64.length();i++)
  556. {
  557. IEspSpaceItem& item1 = SpaceItems64.item(i);
  558. if (!stricmp(item1.getName(), scope))
  559. {
  560. item0 = &item1;
  561. break;
  562. }
  563. }
  564. if (!item0)
  565. {
  566. Owned<IEspSpaceItem> item1 = createSpaceItem();
  567. item1->setName(scope);
  568. item1->setNumOfFilesInt(1);
  569. if (size < 0)
  570. {
  571. item1->setNumOfFilesIntUnknown(1);
  572. item1->setTotalSizeInt(0);
  573. item1->setLargestSizeInt(0);
  574. item1->setSmallestSizeInt(0);
  575. item1->setLargestFile("");
  576. item1->setSmallestFile("");
  577. }
  578. else
  579. {
  580. item1->setNumOfFilesIntUnknown(0);
  581. item1->setTotalSizeInt(size);
  582. item1->setLargestSizeInt(size);
  583. item1->setSmallestSizeInt(size);
  584. item1->setLargestFile(logicalName);
  585. item1->setSmallestFile(logicalName);
  586. }
  587. SpaceItems64.append(*item1.getClear());
  588. }
  589. else if (size < 0)
  590. {
  591. item0->setNumOfFilesIntUnknown(item0->getNumOfFilesIntUnknown() + 1);
  592. item0->setNumOfFilesInt(item0->getNumOfFilesInt() + 1);
  593. }
  594. else
  595. {
  596. if (item0->getNumOfFilesInt() == item0->getNumOfFilesIntUnknown() || size > item0->getLargestSizeInt())
  597. {
  598. item0->setLargestSizeInt(size);
  599. item0->setLargestFile(logicalName);
  600. }
  601. if (item0->getNumOfFilesInt() == item0->getNumOfFilesIntUnknown() || size < item0->getSmallestSizeInt())
  602. {
  603. item0->setSmallestSizeInt(size);
  604. item0->setSmallestFile(logicalName);
  605. }
  606. item0->setNumOfFilesInt(item0->getNumOfFilesInt() + 1);
  607. item0->setTotalSizeInt(item0->getTotalSizeInt() + size);
  608. }
  609. }
  610. else
  611. {
  612. IEspSpaceItem& item0 = SpaceItems64.item(0);
  613. if (size < 0)
  614. {
  615. item0.setNumOfFilesInt(item0.getNumOfFilesInt() + 1);
  616. item0.setNumOfFilesIntUnknown(item0.getNumOfFilesIntUnknown() + 1);
  617. }
  618. else
  619. {
  620. if ((item0.getNumOfFilesInt() == item0.getNumOfFilesIntUnknown()) || (size > item0.getLargestSizeInt()))
  621. {
  622. item0.setLargestSizeInt(size);
  623. item0.setLargestFile(logicalName);
  624. }
  625. if ((item0.getNumOfFilesInt() == item0.getNumOfFilesIntUnknown()) || (size < item0.getSmallestSizeInt()))
  626. {
  627. item0.setSmallestSizeInt(size);
  628. item0.setSmallestFile(logicalName);
  629. }
  630. item0.setNumOfFilesInt(item0.getNumOfFilesInt() + 1);
  631. item0.setTotalSizeInt(item0.getTotalSizeInt() + size);
  632. }
  633. }
  634. return true;
  635. }
  636. bool CWsDfuEx::setSpaceItemByOwner(IArrayOf<IEspSpaceItem>& SpaceItems64, const char *owner, const char *logicalName, __int64 size)
  637. {
  638. if (owner && *owner)
  639. {
  640. IEspSpaceItem *item0 = NULL;
  641. for(unsigned i = 0; i < SpaceItems64.length();i++)
  642. {
  643. IEspSpaceItem& item1 = SpaceItems64.item(i);
  644. if (!stricmp(item1.getName(), owner))
  645. {
  646. item0 = &item1;
  647. break;
  648. }
  649. }
  650. if (!item0)
  651. {
  652. Owned<IEspSpaceItem> item1 = createSpaceItem();
  653. item1->setName(owner);
  654. item1->setNumOfFilesInt(1);
  655. if (size < 0)
  656. {
  657. item1->setNumOfFilesIntUnknown(1);
  658. item1->setTotalSizeInt(0);
  659. item1->setLargestSizeInt(0);
  660. item1->setSmallestSizeInt(0);
  661. item1->setLargestFile("");
  662. item1->setSmallestFile("");
  663. }
  664. else
  665. {
  666. item1->setNumOfFilesIntUnknown(0);
  667. item1->setTotalSizeInt(size);
  668. item1->setLargestSizeInt(size);
  669. item1->setSmallestSizeInt(size);
  670. item1->setLargestFile(logicalName);
  671. item1->setSmallestFile(logicalName);
  672. }
  673. SpaceItems64.append(*item1.getClear());
  674. }
  675. else if (size < 0)
  676. {
  677. item0->setNumOfFilesIntUnknown(item0->getNumOfFilesIntUnknown() + 1);
  678. item0->setNumOfFilesInt(item0->getNumOfFilesInt() + 1);
  679. }
  680. else
  681. {
  682. if (item0->getNumOfFilesInt() == item0->getNumOfFilesIntUnknown() || size > item0->getLargestSizeInt())
  683. {
  684. item0->setLargestSizeInt(size);
  685. item0->setLargestFile(logicalName);
  686. }
  687. if (item0->getNumOfFilesInt() == item0->getNumOfFilesIntUnknown() || size < item0->getSmallestSizeInt())
  688. {
  689. item0->setSmallestSizeInt(size);
  690. item0->setSmallestFile(logicalName);
  691. }
  692. item0->setNumOfFilesInt(item0->getNumOfFilesInt() + 1);
  693. item0->setTotalSizeInt(item0->getTotalSizeInt() + size);
  694. }
  695. }
  696. else
  697. {
  698. IEspSpaceItem& item0 = SpaceItems64.item(0);
  699. if (size < 0)
  700. {
  701. item0.setNumOfFilesInt(item0.getNumOfFilesInt() + 1);
  702. item0.setNumOfFilesIntUnknown(item0.getNumOfFilesIntUnknown() + 1);
  703. }
  704. else
  705. {
  706. if ((item0.getNumOfFilesInt() == item0.getNumOfFilesIntUnknown()) || (size > item0.getLargestSizeInt()))
  707. {
  708. item0.setLargestSizeInt(size);
  709. item0.setLargestFile(logicalName);
  710. }
  711. if ((item0.getNumOfFilesInt() == item0.getNumOfFilesIntUnknown()) || (size < item0.getSmallestSizeInt()))
  712. {
  713. item0.setSmallestSizeInt(size);
  714. item0.setSmallestFile(logicalName);
  715. }
  716. item0.setNumOfFilesInt(item0.getNumOfFilesInt() + 1);
  717. item0.setTotalSizeInt(item0.getTotalSizeInt() + size);
  718. }
  719. }
  720. return true;
  721. }
  722. bool CWsDfuEx::createSpaceItemsByDate(IArrayOf<IEspSpaceItem>& SpaceItems, StringBuffer interval, unsigned& yearFrom,
  723. unsigned& monthFrom, unsigned& dayFrom, unsigned& yearTo, unsigned& monthTo, unsigned& dayTo)
  724. {
  725. if (!stricmp(interval, COUNTBY_YEAR))
  726. {
  727. for (unsigned i = yearFrom; i <= yearTo; i++)
  728. {
  729. Owned<IEspSpaceItem> item64 = createSpaceItem();
  730. StringBuffer name;
  731. name.appendf("%04d", i);
  732. item64->setName(name.str());
  733. item64->setNumOfFilesInt(0);
  734. item64->setNumOfFilesIntUnknown(0);
  735. item64->setTotalSizeInt(0);
  736. item64->setLargestSizeInt(0);
  737. item64->setSmallestSizeInt(0);
  738. item64->setLargestFile("");
  739. item64->setSmallestFile("");
  740. SpaceItems.append(*item64.getClear());
  741. }
  742. }
  743. else if (!stricmp(interval, COUNTBY_QUARTER))
  744. {
  745. for (unsigned i = yearFrom; i <= yearTo; i++)
  746. {
  747. int quartStart = 1;
  748. int quartEnd = 4;
  749. if (i == yearFrom)
  750. {
  751. if (monthFrom > 9)
  752. {
  753. quartStart = 4;
  754. }
  755. else if (monthFrom > 6)
  756. {
  757. quartStart = 3;
  758. }
  759. else if (monthFrom > 3)
  760. {
  761. quartStart = 2;
  762. }
  763. }
  764. if (i == yearTo)
  765. {
  766. if (monthTo > 9)
  767. {
  768. quartEnd = 4;
  769. }
  770. else if (monthTo > 6)
  771. {
  772. quartEnd = 3;
  773. }
  774. else if (monthTo > 3)
  775. {
  776. quartEnd = 2;
  777. }
  778. }
  779. for (int j = quartStart; j <= quartEnd; j++)
  780. {
  781. Owned<IEspSpaceItem> item64 = createSpaceItem();
  782. StringBuffer name;
  783. name.appendf("%04d quarter: %d", i, j);
  784. item64->setName(name.str());
  785. item64->setNumOfFilesInt(0);
  786. item64->setNumOfFilesIntUnknown(0);
  787. item64->setTotalSizeInt(0);
  788. item64->setLargestSizeInt(0);
  789. item64->setSmallestSizeInt(0);
  790. item64->setLargestFile("");
  791. item64->setSmallestFile("");
  792. SpaceItems.append(*item64.getClear());
  793. }
  794. }
  795. }
  796. else if (!stricmp(interval, COUNTBY_MONTH))
  797. {
  798. for (unsigned i = yearFrom; i <= yearTo; i++)
  799. {
  800. int jFrom = (i != yearFrom) ? 1 : monthFrom;
  801. int jTo = (i != yearTo) ? 12 : monthTo;
  802. for (int j = jFrom; j <= jTo; j++)
  803. {
  804. Owned<IEspSpaceItem> item64 = createSpaceItem();
  805. StringBuffer name;
  806. name.appendf("%04d-%02d", i, j);
  807. item64->setName(name.str());
  808. item64->setNumOfFilesInt(0);
  809. item64->setNumOfFilesIntUnknown(0);
  810. item64->setTotalSizeInt(0);
  811. item64->setLargestSizeInt(0);
  812. item64->setSmallestSizeInt(0);
  813. item64->setLargestFile("");
  814. item64->setSmallestFile("");
  815. SpaceItems.append(*item64.getClear());
  816. }
  817. }
  818. }
  819. else
  820. {
  821. for (unsigned i = yearFrom; i <= yearTo; i++)
  822. {
  823. int jFrom = (i != yearFrom) ? 1 : monthFrom;
  824. int jTo = (i != yearTo) ? 12 : monthTo;
  825. for (int j = jFrom; j <= jTo; j++)
  826. {
  827. int dayStart = 1;
  828. int dayEnd = days[j-1];
  829. if (i == yearFrom && j == monthFrom)
  830. {
  831. dayStart = dayFrom;
  832. }
  833. else if (i == yearTo && j == monthTo)
  834. {
  835. dayEnd = dayTo;
  836. }
  837. for (int k = dayStart; k <= dayEnd; k++)
  838. {
  839. Owned<IEspSpaceItem> item64 = createSpaceItem();
  840. StringBuffer name;
  841. name.appendf("%04d-%02d-%02d", i, j, k);
  842. item64->setName(name.str());
  843. item64->setNumOfFilesInt(0);
  844. item64->setNumOfFilesIntUnknown(0);
  845. item64->setTotalSizeInt(0);
  846. item64->setLargestSizeInt(0);
  847. item64->setSmallestSizeInt(0);
  848. item64->setLargestFile("");
  849. item64->setSmallestFile("");
  850. SpaceItems.append(*item64.getClear());
  851. }
  852. }
  853. }
  854. }
  855. return true;
  856. }
  857. bool CWsDfuEx::setSpaceItemByDate(IArrayOf<IEspSpaceItem>& SpaceItems, StringBuffer interval, StringBuffer mod, const char*logicalName, __int64 size)
  858. {
  859. unsigned year, month, day;
  860. CDateTime wuTime;
  861. wuTime.setString(mod.str(),NULL,true);
  862. wuTime.getDate(year, month, day, true);
  863. StringBuffer name;
  864. if (!stricmp(interval, COUNTBY_YEAR))
  865. {
  866. name.appendf("%04d", year);
  867. }
  868. else if (!stricmp(interval, COUNTBY_QUARTER))
  869. {
  870. int quart = 1;
  871. if (month > 9)
  872. {
  873. quart = 4;
  874. }
  875. else if (month > 6)
  876. {
  877. quart = 3;
  878. }
  879. else if (month > 3)
  880. {
  881. quart = 2;
  882. }
  883. name.appendf("%04d quarter: %d", year, quart);
  884. }
  885. else if (!stricmp(interval, COUNTBY_MONTH))
  886. {
  887. name.appendf("%04d-%02d", year, month);
  888. }
  889. else
  890. {
  891. name.appendf("%04d-%02d-%02d", year, month, day);
  892. }
  893. for (unsigned i = 0; i < SpaceItems.length(); i++)
  894. {
  895. IEspSpaceItem& item0 = SpaceItems.item(i);
  896. if (!stricmp(item0.getName(), name))
  897. {
  898. if (size < 0)
  899. {
  900. item0.setNumOfFilesIntUnknown(item0.getNumOfFilesIntUnknown() + 1);
  901. }
  902. else
  903. {
  904. if ((item0.getNumOfFilesInt() == item0.getNumOfFilesIntUnknown()) || (size > item0.getLargestSizeInt()))
  905. {
  906. item0.setLargestSizeInt(size);
  907. item0.setLargestFile(logicalName);
  908. }
  909. if ((item0.getNumOfFilesInt() == item0.getNumOfFilesIntUnknown()) || (size < item0.getSmallestSizeInt()))
  910. {
  911. item0.setSmallestSizeInt(size);
  912. item0.setSmallestFile(logicalName);
  913. }
  914. item0.setTotalSizeInt(item0.getTotalSizeInt() + size);
  915. }
  916. item0.setNumOfFilesInt(item0.getNumOfFilesInt() + 1);
  917. break;
  918. }
  919. }
  920. return true;
  921. }
  922. void CWsDfuEx::parseStringArray(const char *input, StringArray& strarray)
  923. {
  924. if (!input || !*input)
  925. return;
  926. const char *ptr = input;
  927. const char *pptr = ptr;
  928. while (pptr[0])
  929. {
  930. if (pptr[0] == ',')
  931. {
  932. StringAttr tmp;
  933. tmp.set(ptr, pptr-ptr);
  934. strarray.append(tmp.get());
  935. ptr = pptr + 1;
  936. }
  937. pptr++;
  938. }
  939. if (pptr > ptr)
  940. {
  941. StringAttr tmp;
  942. tmp.set(ptr, pptr-ptr);
  943. strarray.append(tmp.get());
  944. }
  945. }
  946. int CWsDfuEx::superfileAction(IEspContext &context, const char* action, const char* superfile, StringArray& subfiles,
  947. const char* beforeSubFile, bool existingSuperfile, bool autocreatesuper, bool deleteFile, bool removeSuperfile)
  948. {
  949. if (!action || !*action)
  950. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Superfile action not specified");
  951. if(!strieq(action, "add") && !strieq(action, "remove"))
  952. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Only Add or Remove is allowed.");
  953. if (!superfile || !*superfile)
  954. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Superfile name not specified");
  955. StringBuffer username;
  956. context.getUserID(username);
  957. Owned<IUserDescriptor> userdesc;
  958. if(username.length() > 0)
  959. {
  960. userdesc.setown(createUserDescriptor());
  961. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  962. }
  963. if (!autocreatesuper)
  964. {//a file lock created by the lookup() will be released after '}'
  965. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(superfile, userdesc.get(), true);
  966. if (existingSuperfile)
  967. {
  968. if (!df)
  969. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Cannot find file %s.",superfile);
  970. if(!df->querySuperFile())
  971. throw MakeStringException(ECLWATCH_NOT_SUPERFILE,"%s is not a superfile.",superfile);
  972. }
  973. else if (df)
  974. throw MakeStringException(ECLWATCH_FILE_ALREADY_EXISTS,"The file %s already exists.",superfile);
  975. }
  976. PointerArrayOf<char> subfileArray;
  977. unsigned num = subfiles.length();
  978. if (num > 0)
  979. {
  980. StringBuffer msgHead;
  981. if(username.length() > 0)
  982. msgHead.appendf("%s: Superfile:%s, Subfile(s): ", action, superfile);
  983. else
  984. msgHead.appendf("%s: Superfile:%s, Subfile(s): ", action, superfile);
  985. unsigned filesInMsgBuf = 0;
  986. StringBuffer msgBuf = msgHead;
  987. for(unsigned i = 0; i < num; i++)
  988. {
  989. subfileArray.append((char*) subfiles.item(i));
  990. msgBuf.appendf("%s, ", subfiles.item(i));
  991. filesInMsgBuf++;
  992. if (filesInMsgBuf > 9)
  993. {
  994. PROGLOG("%s",msgBuf.str());
  995. msgBuf = msgHead;
  996. filesInMsgBuf = 0;
  997. }
  998. }
  999. if (filesInMsgBuf > 0)
  1000. PROGLOG("%s", msgBuf.str());
  1001. }
  1002. else
  1003. PROGLOG("%s: %s", action, superfile);
  1004. Owned<IDFUhelper> dfuhelper = createIDFUhelper();
  1005. synchronized block(m_superfilemutex);
  1006. if(strieq(action, "add"))
  1007. dfuhelper->addSuper(superfile, userdesc.get(), num, (const char**) subfileArray.getArray(), beforeSubFile, true);
  1008. else
  1009. dfuhelper->removeSuper(superfile, userdesc.get(), num, (const char**) subfileArray.getArray(), deleteFile, removeSuperfile);
  1010. PROGLOG("%s done", action);
  1011. return num;
  1012. }
  1013. bool CWsDfuEx::onAddtoSuperfile(IEspContext &context, IEspAddtoSuperfileRequest &req, IEspAddtoSuperfileResponse &resp)
  1014. {
  1015. try
  1016. {
  1017. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Write, false))
  1018. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to AddtoSuperfile. Permission denied.");
  1019. double version = context.getClientVersion();
  1020. if (version > 1.17)
  1021. {
  1022. const char* backTo = req.getBackToPage();
  1023. if (backTo && *backTo)
  1024. resp.setBackToPage(backTo);
  1025. }
  1026. resp.setSubfiles(req.getSubfiles());
  1027. const char* superfile = req.getSuperfile();
  1028. if (!superfile || !*superfile)
  1029. {
  1030. if (version > 1.15)
  1031. {//Display the subfiles inside a table
  1032. const char* files = req.getSubfiles();
  1033. if (files && *files)
  1034. {
  1035. StringArray subfileNames;
  1036. parseStringArray(files, subfileNames);
  1037. if (subfileNames.length() > 0)
  1038. resp.setSubfileNames(subfileNames);
  1039. }
  1040. }
  1041. return true;//Display a form for user to specify superfile
  1042. }
  1043. if (version > 1.15)
  1044. {
  1045. superfileAction(context, "add", superfile, req.getNames(), NULL, req.getExistingFile(), false, false);
  1046. }
  1047. else
  1048. {
  1049. StringArray subfileNames;
  1050. const char *subfilesStr = req.getSubfiles();
  1051. if (subfilesStr && *subfilesStr)
  1052. parseStringArray(subfilesStr, subfileNames);
  1053. superfileAction(context, "add", superfile, subfileNames, NULL, req.getExistingFile(), false, false);
  1054. }
  1055. resp.setRedirectUrl(StringBuffer("/WsDFU/DFUInfo?Name=").append(superfile));
  1056. }
  1057. catch(IException* e)
  1058. {
  1059. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1060. }
  1061. return true;
  1062. }
  1063. void setDeleteFileResults(const char* fileName, const char* nodeGroup, bool failed, const char *start, const char* text, StringBuffer& resultString,
  1064. IArrayOf<IEspDFUActionInfo>& actionResults)
  1065. {
  1066. if (!fileName || !*fileName)
  1067. return;
  1068. Owned<IEspDFUActionInfo> resultObj = createDFUActionInfo("", "");
  1069. resultObj->setFileName(fileName);
  1070. resultObj->setFailed(failed);
  1071. if (nodeGroup && *nodeGroup)
  1072. resultObj->setNodeGroup(nodeGroup);
  1073. StringBuffer message;
  1074. if (start)
  1075. message.append(start).append(' ');
  1076. message.append(fileName);
  1077. if (nodeGroup && *nodeGroup)
  1078. message.append(" on ").append(nodeGroup);
  1079. if (text && *text)
  1080. message.append(failed ? ": " : " ").append(text);
  1081. resultObj->setActionResult(message);
  1082. resultString.appendf("<Message><Value>%s</Value></Message>", message.str());
  1083. actionResults.append(*resultObj.getClear());
  1084. }
  1085. typedef enum {
  1086. DeleteActionSuccess,
  1087. DeleteActionFailure,
  1088. DeleteActionSkip
  1089. } DeleteActionResult;
  1090. DeleteActionResult doDeleteFile(const char *fn, IUserDescriptor *userdesc, StringArray &superFiles, StringArray &failedFiles,
  1091. const char *auditStr, StringBuffer& returnStr, IArrayOf<IEspDFUActionInfo>& actionResults, bool superFilesOnly, bool removeFromSuperfiles, bool deleteRecursively);
  1092. bool doRemoveFileFromSuperfiles(const char *lfn, IUserDescriptor *userdesc, StringArray &superFiles, StringArray &failedFiles, bool deleteRecursively,
  1093. const char *auditStr, StringBuffer& returnStr, IArrayOf<IEspDFUActionInfo>& actionResults)
  1094. {
  1095. StringArray emptySuperFiles;
  1096. IDistributedFileDirectory &fdir = queryDistributedFileDirectory();
  1097. {
  1098. Owned<IDistributedFile> df = fdir.lookup(lfn, userdesc, true);
  1099. if(!df)
  1100. return false;
  1101. Owned<IDistributedSuperFileIterator> supers = df->getOwningSuperFiles();
  1102. ForEach(*supers)
  1103. {
  1104. IDistributedSuperFile &super = supers->query();
  1105. try
  1106. {
  1107. super.removeSubFile(lfn, false, false, NULL);
  1108. VStringBuffer text("from superfile %s", super.queryLogicalName());
  1109. setDeleteFileResults(lfn, NULL, false, "Removed subfile", text, returnStr, actionResults);
  1110. }
  1111. catch(IException* e)
  1112. {
  1113. StringBuffer emsg;
  1114. VStringBuffer text("from superfile %s: %s", super.queryLogicalName(), e->errorMessage(emsg).str());
  1115. setDeleteFileResults(lfn, NULL, true, "Could not remove subfile ", text, returnStr, actionResults);
  1116. e->Release();
  1117. return false;
  1118. }
  1119. catch(...)
  1120. {
  1121. VStringBuffer text("from superfile %s", super.queryLogicalName());
  1122. setDeleteFileResults(lfn, NULL, true, "Could not remove subfile ", text, returnStr, actionResults);
  1123. return false;
  1124. }
  1125. if (deleteRecursively && super.numSubFiles(false)==0)
  1126. emptySuperFiles.appendUniq(super.queryLogicalName());
  1127. }
  1128. }
  1129. ForEachItemIn(i, emptySuperFiles)
  1130. doDeleteFile(emptySuperFiles.item(i), userdesc, superFiles, failedFiles, auditStr, returnStr, actionResults, false, true, deleteRecursively);
  1131. return true;
  1132. }
  1133. DeleteActionResult doDeleteFile(const char *fn, IUserDescriptor *userdesc, StringArray &superFiles, StringArray &failedFiles,
  1134. const char *auditStr, StringBuffer& returnStr, IArrayOf<IEspDFUActionInfo>& actionResults,
  1135. bool superFilesOnly, bool removeFromSuperfiles, bool deleteRecursively)
  1136. {
  1137. StringArray parsed;
  1138. parsed.appendListUniq(fn, "@");
  1139. const char *lfn = parsed.item(0);
  1140. const char *group = NULL;
  1141. if (parsed.length() > 1)
  1142. {
  1143. group = parsed.item(1);
  1144. if (group && (!*group || strieq(group, "null"))) //null is used by new ECLWatch for a superfile
  1145. group = NULL;
  1146. }
  1147. bool isSuper = false;
  1148. if (superFiles.contains(fn) || failedFiles.contains(fn))
  1149. return DeleteActionSkip;
  1150. try
  1151. {
  1152. IDistributedFileDirectory &fdir = queryDistributedFileDirectory();
  1153. {
  1154. Owned<IDistributedFile> df = fdir.lookup(lfn, userdesc, true);
  1155. if(!df)
  1156. {
  1157. PROGLOG("CWsDfuEx::DFUDeleteFiles: %s not found", lfn);
  1158. setDeleteFileResults(lfn, group, true, "File not found", NULL, returnStr, actionResults);
  1159. return DeleteActionFailure;
  1160. }
  1161. isSuper = df->querySuperFile()!=NULL;
  1162. if (superFilesOnly) // skip non-super files on 1st pass
  1163. {
  1164. if(!isSuper)
  1165. return DeleteActionSkip;
  1166. superFiles.append(fn);
  1167. }
  1168. }
  1169. fdir.removeEntry(fn, userdesc, NULL, REMOVE_FILE_SDS_CONNECT_TIMEOUT, true);
  1170. LOG(daliAuditLogCat, "%s,%s", auditStr, fn);
  1171. setDeleteFileResults(lfn, group, false, isSuper ? "Deleted Superfile" : "Deleted File", NULL, returnStr, actionResults);
  1172. }
  1173. catch(IException* e)
  1174. {
  1175. StringBuffer emsg;
  1176. e->errorMessage(emsg);
  1177. if (removeFromSuperfiles && strstr(emsg, "owned by"))
  1178. {
  1179. if (!doRemoveFileFromSuperfiles(lfn, userdesc, superFiles, failedFiles, deleteRecursively, auditStr, returnStr, actionResults))
  1180. return DeleteActionFailure;
  1181. return doDeleteFile(fn, userdesc, superFiles, failedFiles, auditStr, returnStr, actionResults, superFilesOnly, false, false);
  1182. }
  1183. if (e->errorCode() == DFSERR_CreateAccessDenied)
  1184. emsg.replaceString("Create ", "Delete ");
  1185. setDeleteFileResults(lfn, group, true, "Could not delete", emsg.str(), returnStr, actionResults);
  1186. e->Release();
  1187. return DeleteActionFailure;
  1188. }
  1189. catch(...)
  1190. {
  1191. setDeleteFileResults(lfn, group, true, "Could not delete", "unknown exception", returnStr, actionResults);
  1192. return DeleteActionFailure;
  1193. }
  1194. return DeleteActionSuccess;
  1195. }
  1196. void doDeleteFiles(StringArray &files, IUserDescriptor *userdesc, StringArray &superFiles, StringArray &failedFiles,
  1197. const char *auditStr, StringBuffer &returnStr, IArrayOf<IEspDFUActionInfo> &actionResults,
  1198. bool superFilesOnly, bool removeFromSuperfiles, bool deleteRecursively)
  1199. {
  1200. ForEachItemIn(i, files)
  1201. {
  1202. const char* fn = files.item(i);
  1203. if(!fn || !*fn)
  1204. continue;
  1205. PROGLOG("Deleting %s", fn);
  1206. if (DeleteActionFailure==doDeleteFile(fn, userdesc, superFiles, failedFiles, auditStr, returnStr, actionResults, superFilesOnly, removeFromSuperfiles, deleteRecursively))
  1207. {
  1208. failedFiles.appendUniq(fn);
  1209. PROGLOG("Delete %s failed", fn);
  1210. }
  1211. else
  1212. PROGLOG("Delete %s done", fn);
  1213. }
  1214. }
  1215. inline void doDeleteSuperFiles(StringArray &files, IUserDescriptor *userdesc, StringArray &superFiles,
  1216. StringArray &failedFiles, const char *auditStr, StringBuffer &returnStr, IArrayOf<IEspDFUActionInfo> &actionResults,
  1217. bool removeFromSuperfiles, bool deleteRecursively)
  1218. {
  1219. doDeleteFiles(files, userdesc, superFiles, failedFiles, auditStr, returnStr, actionResults, true, removeFromSuperfiles, deleteRecursively);
  1220. }
  1221. inline void doDeleteSubFiles(StringArray &files, IUserDescriptor *userdesc, StringArray &superFiles,
  1222. StringArray &failedFiles, const char *auditStr, StringBuffer &returnStr, IArrayOf<IEspDFUActionInfo> &actionResults,
  1223. bool removeFromSuperfiles, bool deleteRecursively)
  1224. {
  1225. doDeleteFiles(files, userdesc, superFiles, failedFiles, auditStr, returnStr, actionResults, false, removeFromSuperfiles, deleteRecursively);
  1226. }
  1227. bool CWsDfuEx::DFUDeleteFiles(IEspContext &context, IEspDFUArrayActionRequest &req, IEspDFUArrayActionResponse &resp)
  1228. {
  1229. if (isDetachedFromDali())
  1230. throw MakeStringException(ECLWATCH_INVALID_INPUT, "ESP server is detached from Dali. Please try later.");
  1231. double version = context.getClientVersion();
  1232. Owned<IUserDescriptor> userdesc;
  1233. const char *username = context.queryUserId();
  1234. if(username && *username)
  1235. {
  1236. userdesc.setown(createUserDescriptor());
  1237. userdesc->set(username, context.queryPassword(), context.querySignature());
  1238. }
  1239. StringBuffer returnStr, auditStr = (",FileAccess,WsDfu,DELETED,");
  1240. IArrayOf<IEspDFUActionInfo> actionResults;
  1241. StringArray superFiles, failedFiles;
  1242. auditStr.append(espProcess.get());
  1243. auditStr.append(',');
  1244. if (!isEmptyString(username))
  1245. auditStr.append(username).append('@');
  1246. context.getPeer(auditStr);
  1247. doDeleteSuperFiles(req.getLogicalFiles(), userdesc, superFiles, failedFiles, auditStr.str(),
  1248. returnStr, actionResults, req.getRemoveFromSuperfiles(), req.getRemoveRecursively());
  1249. doDeleteSubFiles(req.getLogicalFiles(), userdesc, superFiles, failedFiles, auditStr.str(),
  1250. returnStr, actionResults, req.getRemoveFromSuperfiles(), req.getRemoveRecursively());
  1251. if (version >= 1.27)
  1252. resp.setActionResults(actionResults);
  1253. if (version < 1.33)
  1254. resp.setDFUArrayActionResult(returnStr.str());
  1255. return true;
  1256. }
  1257. bool CWsDfuEx::onDFUArrayAction(IEspContext &context, IEspDFUArrayActionRequest &req, IEspDFUArrayActionResponse &resp)
  1258. {
  1259. try
  1260. {
  1261. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Write, false))
  1262. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to update Logical Files. Permission denied.");
  1263. CDFUArrayActions action = req.getType();
  1264. if (action == DFUArrayActions_Undefined)
  1265. throw MakeStringException(ECLWATCH_INVALID_INPUT,"Action not defined.");
  1266. double version = context.getClientVersion();
  1267. if (version > 1.03)
  1268. {
  1269. StringBuffer backToPage = req.getBackToPage();
  1270. if (backToPage.length() > 0)
  1271. {
  1272. const char* oldStr = "&";
  1273. const char* newStr = "&amp;";
  1274. backToPage.replaceString(oldStr, newStr);
  1275. resp.setBackToPage(backToPage.str());
  1276. }
  1277. }
  1278. if (action == CDFUArrayActions_Delete)
  1279. return DFUDeleteFiles(context, req, resp);
  1280. //the code below is only for legacy ECLWatch. Other application should use AddtoSuperfile.
  1281. StringBuffer username;
  1282. context.getUserID(username);
  1283. Owned<IUserDescriptor> userdesc;
  1284. if(username.length() > 0)
  1285. {
  1286. userdesc.setown(createUserDescriptor());
  1287. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  1288. }
  1289. IArrayOf<IEspDFUActionInfo> actionResults;
  1290. StringBuffer errorStr, subfiles;
  1291. for(unsigned i = 0; i < req.getLogicalFiles().length();i++)
  1292. {
  1293. const char* file = req.getLogicalFiles().item(i);
  1294. if(!file || !*file)
  1295. continue;
  1296. unsigned len = strlen(file);
  1297. char* curfile = new char[len+1];
  1298. const char* cluster = NULL;
  1299. const char *pCh = strchr(file, '@');
  1300. if (pCh)
  1301. {
  1302. len = pCh - file;
  1303. if (len+1 < strlen(file))
  1304. cluster = pCh + 1;
  1305. }
  1306. strncpy(curfile, file, len);
  1307. curfile[len] = 0;
  1308. try
  1309. {
  1310. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(curfile, userdesc.get(), true);
  1311. if (df)
  1312. {
  1313. if (subfiles.length() > 0)
  1314. subfiles.append(",");
  1315. subfiles.append(curfile);
  1316. }
  1317. else
  1318. setDeleteFileResults(file, NULL, true, NULL, "not found", errorStr, actionResults);
  1319. }
  1320. catch(IException* e)
  1321. {
  1322. StringBuffer emsg;
  1323. e->errorMessage(emsg);
  1324. if (e->errorCode() == DFSERR_CreateAccessDenied)
  1325. emsg.replaceString("Create ", "AddtoSuperfile ");
  1326. setDeleteFileResults(file, NULL, true, NULL, emsg.str(), errorStr, actionResults);
  1327. e->Release();
  1328. }
  1329. catch(...)
  1330. {
  1331. setDeleteFileResults(file, NULL, true, NULL, "unknown exception", errorStr, actionResults);
  1332. }
  1333. delete [] curfile;
  1334. }
  1335. if (version >= 1.27)
  1336. resp.setActionResults(actionResults);
  1337. if (errorStr.length())
  1338. {
  1339. if (version < 1.33)
  1340. resp.setDFUArrayActionResult(errorStr.str());
  1341. return false;
  1342. }
  1343. if (version < 1.18)
  1344. resp.setRedirectUrl(StringBuffer("/WsDFU/AddtoSuperfile?Subfiles=").append(subfiles.str()));
  1345. else
  1346. resp.setRedirectTo(subfiles.str());
  1347. }
  1348. catch(IException* e)
  1349. {
  1350. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1351. }
  1352. return true;
  1353. }
  1354. bool CWsDfuEx::onDFUDefFile(IEspContext &context,IEspDFUDefFileRequest &req, IEspDFUDefFileResponse &resp)
  1355. {
  1356. try
  1357. {
  1358. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1359. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to access DFUDefFile. Permission denied.");
  1360. CDFUDefFileFormat format = req.getFormat();
  1361. if (format == DFUDefFileFormat_Undefined)
  1362. throw MakeStringException(ECLWATCH_INVALID_INPUT,"Invalid format");
  1363. const char* fileName = req.getName();
  1364. if (!fileName || !*fileName)
  1365. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "File name required");
  1366. PROGLOG("DFUDefFile: %s", fileName);
  1367. StringBuffer username;
  1368. context.getUserID(username);
  1369. StringBuffer rawStr,returnStr;
  1370. Owned<IUserDescriptor> userdesc;
  1371. if(username.length() > 0)
  1372. {
  1373. userdesc.setown(createUserDescriptor());
  1374. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  1375. }
  1376. getDefFile(userdesc.get(), req.getName(),rawStr);
  1377. StringBuffer xsltFile;
  1378. xsltFile.append(getCFD()).append("smc_xslt/").append(req.getFormatAsString()).append("_def_file.xslt");
  1379. xsltTransformer(xsltFile.str(),rawStr,returnStr);
  1380. //set the file
  1381. MemoryBuffer buff;
  1382. buff.setBuffer(returnStr.length(), (void*)returnStr.str());
  1383. resp.setDefFile(buff);
  1384. //set the type
  1385. StringBuffer type = "text/";
  1386. if (format == CDFUDefFileFormat_xml)
  1387. type.append("xml");
  1388. else
  1389. type.append("plain");
  1390. resp.setDefFile_mimetype(type.str());
  1391. }
  1392. catch(IException* e)
  1393. {
  1394. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1395. }
  1396. return true;
  1397. }
  1398. IHqlExpression * getEclRecordDefinition(const char * ecl)
  1399. {
  1400. MultiErrorReceiver errs;
  1401. OwnedHqlExpr record = parseQuery(ecl, &errs);
  1402. if (errs.errCount())
  1403. {
  1404. StringBuffer errtext;
  1405. IError *first = errs.firstError();
  1406. first->toString(errtext);
  1407. throw MakeStringException(ECLWATCH_CANNOT_PARSE_ECL_QUERY, "Failed in parsing ECL record definition: %s @ %d:%d.", errtext.str(), first->getColumn(), first->getLine());
  1408. }
  1409. if(!record)
  1410. throw MakeStringException(ECLWATCH_CANNOT_PARSE_ECL_QUERY, "Failed in parsing ECL record definition.");
  1411. return record.getClear();
  1412. }
  1413. IHqlExpression * getEclRecordDefinition(IUserDescriptor* udesc, const char* FileName)
  1414. {
  1415. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(FileName, udesc);
  1416. if(!df)
  1417. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Cannot find file %s.",FileName);
  1418. if(!df->queryAttributes().hasProp("ECL"))
  1419. throw MakeStringException(ECLWATCH_MISSING_PARAMS,"No record definition for file %s.",FileName);
  1420. return getEclRecordDefinition(df->queryAttributes().queryProp("ECL"));
  1421. }
  1422. bool CWsDfuEx::onDFURecordTypeInfo(IEspContext &context, IEspDFURecordTypeInfoRequest &req, IEspDFURecordTypeInfoResponse &resp)
  1423. {
  1424. try
  1425. {
  1426. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1427. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to access DFURecordTypeInfo. Permission denied.");
  1428. const char* fileName = req.getName();
  1429. if (!fileName || !*fileName)
  1430. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "File name required");
  1431. PROGLOG("DFURecordTypeInfo file: %s", fileName);
  1432. const char* userId = context.queryUserId();
  1433. Owned<IUserDescriptor> userdesc;
  1434. if(userId && *userId)
  1435. {
  1436. userdesc.setown(createUserDescriptor());
  1437. userdesc->set(userId, context.queryPassword(), context.querySignature());
  1438. }
  1439. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(fileName, userdesc);
  1440. if(!df)
  1441. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Cannot find file %s.",fileName);
  1442. if (df->queryAttributes().hasProp("_rtlType"))
  1443. {
  1444. MemoryBuffer layoutBin;
  1445. df->queryAttributes().getPropBin("_rtlType", layoutBin);
  1446. if (req.getIncludeJsonTypeInfo())
  1447. {
  1448. Owned<IRtlFieldTypeDeserializer> deserializer(createRtlFieldTypeDeserializer());
  1449. const RtlTypeInfo *typeInfo = deserializer->deserialize(layoutBin);
  1450. StringBuffer jsonFormat;
  1451. dumpTypeInfo(jsonFormat, typeInfo);
  1452. resp.setJsonInfo(jsonFormat);
  1453. layoutBin.reset(0);
  1454. }
  1455. if (req.getIncludeBinTypeInfo())
  1456. resp.setBinInfo(layoutBin);
  1457. }
  1458. else if (df->queryAttributes().hasProp("ECL"))
  1459. {
  1460. const char * kind = df->queryAttributes().queryProp("@kind");
  1461. bool isIndex = (kind && streq(kind, "key"));
  1462. OwnedHqlExpr record = getEclRecordDefinition(userdesc, fileName);
  1463. if (df->queryAttributes().hasProp("_record_layout"))
  1464. {
  1465. MemoryBuffer mb;
  1466. df->queryAttributes().getPropBin("_record_layout", mb);
  1467. record.setown(patchEclRecordDefinitionFromRecordLayout(record, mb));
  1468. }
  1469. if (req.getIncludeJsonTypeInfo())
  1470. {
  1471. StringBuffer jsonFormat;
  1472. exportJsonType(jsonFormat, record, isIndex);
  1473. resp.setJsonInfo(jsonFormat);
  1474. }
  1475. if (req.getIncludeBinTypeInfo())
  1476. {
  1477. MemoryBuffer binFormat;
  1478. exportBinaryType(binFormat, record, isIndex);
  1479. resp.setBinInfo(binFormat);
  1480. }
  1481. }
  1482. }
  1483. catch(IException* e)
  1484. {
  1485. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1486. }
  1487. return true;
  1488. }
  1489. bool CWsDfuEx::onEclRecordTypeInfo(IEspContext &context, IEspEclRecordTypeInfoRequest &req, IEspEclRecordTypeInfoResponse &resp)
  1490. {
  1491. try
  1492. {
  1493. OwnedHqlExpr record = getEclRecordDefinition(req.getEcl());
  1494. if (req.getIncludeJsonTypeInfo())
  1495. {
  1496. StringBuffer jsonFormat;
  1497. exportJsonType(jsonFormat, record, false); // MORE - could allow isIndex to be passed in?
  1498. resp.setJsonInfo(jsonFormat);
  1499. }
  1500. if (req.getIncludeBinTypeInfo())
  1501. {
  1502. MemoryBuffer binFormat;
  1503. exportBinaryType(binFormat, record, false);
  1504. resp.setBinInfo(binFormat);
  1505. }
  1506. }
  1507. catch(IException* e)
  1508. {
  1509. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1510. }
  1511. return true;
  1512. }
  1513. void CWsDfuEx::xsltTransformer(const char* xsltPath,StringBuffer& source,StringBuffer& returnStr)
  1514. {
  1515. if (m_xsl.get() == 0)
  1516. {
  1517. m_xsl.setown(getXslProcessor());
  1518. }
  1519. Owned<IXslTransform> xform = m_xsl->createXslTransform();
  1520. xform->loadXslFromFile(xsltPath);
  1521. xform->setXmlSource(source.str(), source.length()+1);
  1522. xform->transform(returnStr.clear());
  1523. }
  1524. void CWsDfuEx::getDefFile(IUserDescriptor* udesc, const char* FileName,StringBuffer& returnStr)
  1525. {
  1526. OwnedHqlExpr record = getEclRecordDefinition(udesc, FileName);
  1527. Owned<IPropertyTree> data = createPTree("Table", ipt_caseInsensitive);
  1528. exportData(data, record);
  1529. const char* fname=strrchr(FileName,':');
  1530. data->setProp("filename",fname ? fname+1 : FileName);
  1531. toXML(data, returnStr, 0, 0);
  1532. }
  1533. bool CWsDfuEx::checkFileContent(IEspContext &context, IUserDescriptor* udesc, const char * logicalName, const char * cluster)
  1534. {
  1535. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(logicalName, udesc);
  1536. if (!df)
  1537. return false;
  1538. if (!cluster || !stricmp(cluster, ""))
  1539. {
  1540. StringAttr eclCluster;
  1541. const char* wuid = df->queryAttributes().queryProp("@workunit");
  1542. if (wuid && *wuid)
  1543. {
  1544. try
  1545. {
  1546. Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
  1547. if (factory)
  1548. {
  1549. IConstWorkUnit* wu = factory->openWorkUnit(wuid, context.querySecManager(), context.queryUser());
  1550. if (wu)
  1551. eclCluster.set(wu->queryClusterName());
  1552. }
  1553. }
  1554. catch(...)
  1555. {
  1556. return false;
  1557. }
  1558. }
  1559. if (!eclCluster.length())
  1560. return false;
  1561. }
  1562. bool blocked;
  1563. if (df->isCompressed(&blocked) && !blocked)
  1564. return false;
  1565. IPropertyTree & properties = df->queryAttributes();
  1566. const char * format = properties.queryProp("@format");
  1567. if (format && (stricmp(format,"csv")==0 || memicmp(format, "utf", 3) == 0))
  1568. {
  1569. return true;
  1570. }
  1571. const char * recordEcl = properties.queryProp("ECL");
  1572. if (!recordEcl)
  1573. return false;
  1574. MultiErrorReceiver errs;
  1575. Owned< IHqlExpression> ret = ::parseQuery(recordEcl, &errs);
  1576. return errs.errCount() == 0;
  1577. }
  1578. bool FindInStringArray(StringArray& clusters, const char *cluster)
  1579. {
  1580. bool bFound = false;
  1581. if(cluster && *cluster)
  1582. {
  1583. if (clusters.ordinality())
  1584. {
  1585. ForEachItemIn(i, clusters)
  1586. {
  1587. const char* cluster0 = clusters.item(i);
  1588. if(cluster0 && *cluster0 && !stricmp(cluster, cluster0))
  1589. return true;
  1590. }
  1591. }
  1592. }
  1593. else
  1594. {
  1595. #if 0 //Comment out since clusters are not set for some old files
  1596. if (!clusters.ordinality())
  1597. return true;
  1598. ForEachItemIn(i, clusters)
  1599. {
  1600. const char* cluster0 = clusters.item(i);
  1601. if(cluster0 && !*cluster0)
  1602. {
  1603. return true;
  1604. }
  1605. }
  1606. #else
  1607. return true;
  1608. #endif
  1609. }
  1610. return bFound;
  1611. }
  1612. static void getFilePermission(CDfsLogicalFileName &dlfn, ISecUser & user, IUserDescriptor* udesc, ISecManager* secmgr, SecAccessFlags& permission)
  1613. {
  1614. if (dlfn.isMulti())
  1615. {
  1616. if (!dlfn.isExpanded())
  1617. dlfn.expand(udesc);
  1618. unsigned i = dlfn.multiOrdinality();
  1619. while (i--)
  1620. {
  1621. getFilePermission((CDfsLogicalFileName &)dlfn.multiItem(i), user, udesc, secmgr, permission);
  1622. }
  1623. }
  1624. else
  1625. {
  1626. SecAccessFlags permissionTemp;
  1627. if (dlfn.isForeign())
  1628. {
  1629. permissionTemp = queryDistributedFileDirectory().getFilePermissions(dlfn.get(), udesc);
  1630. }
  1631. else
  1632. {
  1633. StringBuffer scopes;
  1634. dlfn.getScopes(scopes);
  1635. permissionTemp = secmgr->authorizeFileScope(user, scopes.str());
  1636. }
  1637. //Descrease the permission whenever a component has a lower permission.
  1638. if (permissionTemp < permission)
  1639. permission = permissionTemp;
  1640. }
  1641. return;
  1642. }
  1643. bool CWsDfuEx::getUserFilePermission(IEspContext &context, IUserDescriptor* udesc, const char* logicalName, SecAccessFlags& permission)
  1644. {
  1645. ISecManager* secmgr = context.querySecManager();
  1646. if (!secmgr)
  1647. {
  1648. return false;
  1649. }
  1650. StringBuffer username;
  1651. StringBuffer password;
  1652. udesc->getUserName(username);
  1653. if (username.length() < 1)
  1654. {
  1655. DBGLOG("User Name not defined\n");
  1656. return false;
  1657. }
  1658. udesc->getPassword(password);
  1659. Owned<ISecUser> user = secmgr->createUser(username);
  1660. if (!user)
  1661. {
  1662. DBGLOG("User %s not found\n", username.str());
  1663. return false;
  1664. }
  1665. if (password.length() > 0)
  1666. user->credentials().setPassword(password);
  1667. CDfsLogicalFileName dlfn;
  1668. dlfn.set(logicalName);
  1669. //Start from the SecAccess_Full. Decrease the permission whenever a component has a lower permission.
  1670. permission = SecAccess_Full;
  1671. getFilePermission(dlfn, *user, udesc, secmgr, permission);
  1672. return true;
  1673. }
  1674. void CWsDfuEx::getFilePartsOnClusters(IEspContext &context, const char* clusterReq, StringArray& clusters, IDistributedFile* df, IEspDFUFileDetail& FileDetails,
  1675. offset_t& mn, offset_t& mx, offset_t& sum, offset_t& count)
  1676. {
  1677. double version = context.getClientVersion();
  1678. IArrayOf<IConstDFUFilePartsOnCluster>& partsOnClusters = FileDetails.getDFUFilePartsOnClusters();
  1679. ForEachItemIn(i, clusters)
  1680. {
  1681. const char* clusterName = clusters.item(i);
  1682. if (!clusterName || !*clusterName || (clusterReq && *clusterReq && !strieq(clusterReq, clusterName)))
  1683. continue;
  1684. Owned<IEspDFUFilePartsOnCluster> partsOnCluster = createDFUFilePartsOnCluster("","");
  1685. partsOnCluster->setCluster(clusterName);
  1686. IArrayOf<IConstDFUPart>& filePartList = partsOnCluster->getDFUFileParts();
  1687. Owned<IFileDescriptor> fdesc = df->getFileDescriptor(clusterName);
  1688. Owned<IPartDescriptorIterator> pi = fdesc->getIterator();
  1689. ForEach(*pi)
  1690. {
  1691. IPartDescriptor& part = pi->query();
  1692. unsigned partIndex = part.queryPartIndex();
  1693. __int64 size = -1;
  1694. StringBuffer partSizeStr;
  1695. IPropertyTree* partPropertyTree = &part.queryProperties();
  1696. if (!partPropertyTree)
  1697. partSizeStr.set("<N/A>");
  1698. else
  1699. {
  1700. size = partPropertyTree->getPropInt64("@size", -1);
  1701. comma c4(size);
  1702. partSizeStr<<c4;
  1703. count++;
  1704. sum+=size;
  1705. if(size>mx) mx=size;
  1706. if(size<mn) mn=size;
  1707. }
  1708. for (unsigned int i=0; i<part.numCopies(); i++)
  1709. {
  1710. StringBuffer b;
  1711. part.queryNode(i)->endpoint().getUrlStr(b);
  1712. Owned<IEspDFUPart> FilePart = createDFUPart("","");
  1713. FilePart->setId(partIndex+1);
  1714. FilePart->setPartsize(partSizeStr.str());
  1715. if (version >= 1.38)
  1716. FilePart->setPartSizeInt64(size);
  1717. FilePart->setIp(b.str());
  1718. FilePart->setCopy(i+1);
  1719. filePartList.append(*FilePart.getClear());
  1720. }
  1721. }
  1722. if (version >= 1.31)
  1723. {
  1724. IClusterInfo* clusterInfo = fdesc->queryCluster(clusterName);
  1725. if (clusterInfo) //Should be valid. But, check it just in case.
  1726. {
  1727. partsOnCluster->setReplicate(clusterInfo->queryPartDiskMapping().isReplicated());
  1728. Owned<CThorNodeGroup> nodeGroup = thorNodeGroupCache->lookup(clusterName, nodeGroupCacheTimeout);
  1729. if (nodeGroup)
  1730. partsOnCluster->setCanReplicate(nodeGroup->queryCanReplicate());
  1731. const char* defaultDir = fdesc->queryDefaultDir();
  1732. if (defaultDir && *defaultDir)
  1733. {
  1734. DFD_OS os = SepCharBaseOs(getPathSepChar(defaultDir));
  1735. StringBuffer baseDir, repDir;
  1736. clusterInfo->getBaseDir(baseDir, os);
  1737. clusterInfo->getReplicateDir(repDir, os);
  1738. partsOnCluster->setBaseDir(baseDir.str());
  1739. partsOnCluster->setReplicateDir(baseDir.str());
  1740. }
  1741. }
  1742. }
  1743. partsOnClusters.append(*partsOnCluster.getClear());
  1744. }
  1745. }
  1746. void CWsDfuEx::parseFieldMask(unsigned __int64 fieldMask, unsigned &fieldCount, IntArray &fieldIndexArray)
  1747. {
  1748. while (fieldMask > 0)
  1749. {
  1750. if (fieldMask & 1)
  1751. fieldIndexArray.append(fieldCount); //index from 0
  1752. fieldMask >>= 1;
  1753. fieldCount++;
  1754. }
  1755. }
  1756. void CWsDfuEx::queryFieldNames(IEspContext &context, const char *fileName, const char *cluster,
  1757. unsigned __int64 fieldMask, StringArray &fieldNames)
  1758. {
  1759. if (!fileName || !*fileName)
  1760. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "File name required");
  1761. Owned<IResultSetFactory> resultSetFactory = getSecResultSetFactory(context.querySecManager(), context.queryUser(), context.queryUserId(), context.queryPassword());
  1762. Owned<INewResultSet> result = resultSetFactory->createNewFileResultSet(fileName, cluster);
  1763. if (!result)
  1764. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Failed to access FileResultSet for %s.", fileName);
  1765. unsigned fieldCount = 0;
  1766. IntArray fieldIndexArray;
  1767. parseFieldMask(fieldMask, fieldCount, fieldIndexArray);
  1768. const IResultSetMetaData& metaData = result->getMetaData();
  1769. unsigned totalColumns = (unsigned) metaData.getColumnCount();
  1770. if (fieldCount > totalColumns)
  1771. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid FieldMask %" I64F "u: total fields %u, ask for %u.",
  1772. fieldMask, totalColumns, fieldCount);
  1773. ForEachItemIn(i, fieldIndexArray)
  1774. {
  1775. int fieldIndex = fieldIndexArray.item(i);
  1776. SCMStringBuffer columnLabel;
  1777. if (metaData.hasSetTranslation(fieldIndex))
  1778. metaData.getNaturalColumnLabel(columnLabel, fieldIndex);
  1779. if (columnLabel.length() < 1)
  1780. metaData.getColumnLabel(columnLabel, fieldIndex);
  1781. fieldNames.append(columnLabel.str());
  1782. }
  1783. }
  1784. void CWsDfuEx::doGetFileDetails(IEspContext &context, IUserDescriptor *udesc, const char *name, const char *cluster,
  1785. const char *querySet, const char *query, const char *description, bool includeJsonTypeInfo, bool includeBinTypeInfo, IEspDFUFileDetail &FileDetails)
  1786. {
  1787. if (!name || !*name)
  1788. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "File name required");
  1789. PROGLOG("doGetFileDetails: %s", name);
  1790. double version = context.getClientVersion();
  1791. if ((version >= 1.38) && !isEmptyString(querySet) && !isEmptyString(query))
  1792. {
  1793. if (getQueryFile(name, querySet, query, FileDetails))
  1794. return;
  1795. }
  1796. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(name, udesc, false, false, true); // lock super-owners
  1797. if(!df)
  1798. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Cannot find file %s.",name);
  1799. StringArray clusters;
  1800. df->getClusterNames(clusters);
  1801. if (cluster && *cluster && !FindInStringArray(clusters, cluster))
  1802. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Cannot find file %s on %s.", name, cluster);
  1803. offset_t size=queryDistributedFileSystem().getSize(df), recordSize=df->queryAttributes().getPropInt64("@recordSize",0);
  1804. CDateTime dt;
  1805. df->getModificationTime(dt);
  1806. const char* lname=df->queryLogicalName(), *fname=strrchr(lname,':');
  1807. FileDetails.setName(lname);
  1808. FileDetails.setFilename(fname ? fname+1 : lname);
  1809. FileDetails.setDir(df->queryDefaultDir());
  1810. FileDetails.setPathMask(df->queryPartMask());
  1811. if (version >= 1.28)
  1812. {
  1813. StringBuffer buf;
  1814. FileDetails.setPrefix(getPrefixFromLogicalName(lname, buf));
  1815. if (cluster && *cluster)
  1816. FileDetails.setNodeGroup(cluster);
  1817. else if (clusters.length() == 1)
  1818. FileDetails.setNodeGroup(clusters.item(0));
  1819. IArrayOf<IEspDFUFileProtect> protectList;
  1820. Owned<IPropertyTreeIterator> itr= df->queryAttributes().getElements("Protect");
  1821. ForEach(*itr)
  1822. {
  1823. IPropertyTree &tree = itr->query();
  1824. const char *owner = tree.queryProp("@name");
  1825. const char *modified = tree.queryProp("@modified");
  1826. int count = tree.getPropInt("@count", 0);
  1827. Owned<IEspDFUFileProtect> protect= createDFUFileProtect();
  1828. if(owner && *owner)
  1829. protect->setOwner(owner);
  1830. if(modified && *modified)
  1831. protect->setModified(modified);
  1832. protect->setCount(count);
  1833. protectList.append(*protect.getLink());
  1834. }
  1835. FileDetails.setProtectList(protectList);
  1836. }
  1837. StringBuffer strDesc = df->queryAttributes().queryProp("@description");
  1838. if (description)
  1839. {
  1840. DistributedFilePropertyLock lock(df);
  1841. lock.queryAttributes().setProp("@description",description);
  1842. strDesc = description;
  1843. }
  1844. FileDetails.setDescription(strDesc);
  1845. if (version >= 1.38)
  1846. FileDetails.setFileSizeInt64(size);
  1847. comma c1(size);
  1848. StringBuffer tmpstr;
  1849. tmpstr<<c1;
  1850. FileDetails.setFilesize(tmpstr.str());
  1851. bool isKeyFile = isFileKey(df);
  1852. if (isKeyFile || df->isCompressed())
  1853. {
  1854. if (version < 1.22)
  1855. FileDetails.setZipFile(true);
  1856. else
  1857. {
  1858. FileDetails.setIsCompressed(true);
  1859. if (df->queryAttributes().hasProp("@compressedSize"))
  1860. {
  1861. __int64 compressedSize = df->queryAttributes().getPropInt64("@compressedSize");
  1862. FileDetails.setCompressedFileSize(compressedSize);
  1863. if (version >= 1.34)
  1864. {
  1865. Decimal d(((double) compressedSize)/size*100);
  1866. d.round(2);
  1867. FileDetails.setPercentCompressed(d.getCString());
  1868. }
  1869. }
  1870. else if (isKeyFile)
  1871. FileDetails.setCompressedFileSize(size);
  1872. }
  1873. }
  1874. if (version >= 1.38)
  1875. FileDetails.setRecordSizeInt64(recordSize);
  1876. comma c2(recordSize);
  1877. tmpstr.clear();
  1878. tmpstr<<c2;
  1879. FileDetails.setRecordSize(tmpstr.str());
  1880. tmpstr.clear();
  1881. __int64 recordCount = -1;
  1882. if (df->queryAttributes().hasProp("@recordCount"))
  1883. {
  1884. recordCount = df->queryAttributes().getPropInt64("@recordCount");
  1885. }
  1886. else if (recordSize)
  1887. {
  1888. recordCount = size/recordSize;
  1889. }
  1890. if (version >= 1.38)
  1891. FileDetails.setRecordCountInt64(recordCount);
  1892. if (recordCount != -1)
  1893. {
  1894. comma c3(recordCount);
  1895. tmpstr<<c3;
  1896. }
  1897. FileDetails.setRecordCount(tmpstr.str());
  1898. FileDetails.setOwner(df->queryAttributes().queryProp("@owner"));
  1899. FileDetails.setJobName(df->queryAttributes().queryProp("@job"));
  1900. if (version >= 1.39)
  1901. {
  1902. if (df->queryAttributes().hasProp("@partitionFieldMask"))
  1903. {
  1904. StringArray partitionFieldNames;
  1905. unsigned __int64 partitionFieldMask = df->queryAttributes().getPropInt64("@partitionFieldMask");
  1906. queryFieldNames(context, name, cluster, partitionFieldMask, partitionFieldNames);
  1907. IEspDFUFilePartition &partition = FileDetails.updatePartition();
  1908. partition.setFieldMask(partitionFieldMask);
  1909. partition.setFieldNames(partitionFieldNames);
  1910. }
  1911. IPropertyTree *bloomTree = df->queryAttributes().queryPropTree("Bloom");
  1912. if (bloomTree)
  1913. {
  1914. StringArray bloomFieldNames;
  1915. unsigned __int64 bloomFieldMask = bloomTree->getPropInt64("@bloomFieldMask");
  1916. queryFieldNames(context, name, cluster, bloomFieldMask, bloomFieldNames);
  1917. IEspDFUFileBloom &bloom = FileDetails.updateBloom();
  1918. bloom.setFieldMask(bloomFieldMask);
  1919. bloom.setFieldNames(bloomFieldNames);
  1920. bloom.setLimit(bloomTree->getPropInt64("@bloomLimit"));
  1921. bloom.setProbability(bloomTree->queryProp("@bloomProbability"));
  1922. }
  1923. }
  1924. //#14280
  1925. IDistributedSuperFile *sf = df->querySuperFile();
  1926. if(sf)
  1927. {
  1928. StringArray farray;
  1929. Owned<IDistributedFileIterator> iter=sf->getSubFileIterator();
  1930. ForEach(*iter)
  1931. {
  1932. StringBuffer subfileName;
  1933. iter->getName(subfileName);
  1934. farray.append(subfileName.str());
  1935. }
  1936. unsigned numSubFiles = farray.length();
  1937. if(numSubFiles > 0)
  1938. {
  1939. FileDetails.setSubfiles(farray);
  1940. }
  1941. if ((version >= 1.28) && (numSubFiles > 1))
  1942. FileDetails.setBrowseData(false); //ViewKeyFile Cannot handle superfile with multiple subfiles
  1943. FileDetails.setIsSuperfile(true);
  1944. return;
  1945. }
  1946. //#14280
  1947. FileDetails.setWuid(df->queryAttributes().queryProp("@workunit"));
  1948. if (version >= 1.28)
  1949. FileDetails.setNumParts(df->numParts());
  1950. //#17430
  1951. {
  1952. IArrayOf<IEspDFULogicalFile> LogicalFiles;
  1953. Owned<IDistributedSuperFileIterator> iter = df->getOwningSuperFiles();
  1954. if(iter.get() != NULL)
  1955. {
  1956. ForEach(*iter)
  1957. {
  1958. //printf("%s,%s\n",iter->query().queryLogicalName(),lname);
  1959. Owned<IEspDFULogicalFile> File = createDFULogicalFile("","");
  1960. File->setName(iter->queryName());
  1961. LogicalFiles.append(*File.getClear());
  1962. }
  1963. }
  1964. if(LogicalFiles.length() > 0)
  1965. {
  1966. FileDetails.setSuperfiles(LogicalFiles);
  1967. }
  1968. }
  1969. //#17430
  1970. //new (optional) attribute on a logical file (@persistent)
  1971. //indicates the ESP page that shows the details of a file. It indicates
  1972. //whether the file was created with a PERSIST() ecl attribute.
  1973. FileDetails.setPersistent(df->queryAttributes().queryProp("@persistent"));
  1974. //@format - what format the file is (if not fixed with)
  1975. FileDetails.setFormat(df->queryAttributes().queryProp("@format"));
  1976. if ((version >= 1.21) && (df->queryAttributes().hasProp("@kind")))
  1977. FileDetails.setContentType(df->queryAttributes().queryProp("@kind"));
  1978. //@maxRecordSize - what the maximum length of records is
  1979. FileDetails.setMaxRecordSize(df->queryAttributes().queryProp("@maxRecordSize"));
  1980. //@csvSeparate - separators between fields for a CSV/utf file
  1981. FileDetails.setCsvSeparate(df->queryAttributes().queryProp("@csvSeparate"));
  1982. //@csvQuote - character used to quote fields for a csv/utf file.
  1983. FileDetails.setCsvQuote(df->queryAttributes().queryProp("@csvQuote"));
  1984. //@csvTerminate - characters used to terminate a record in a csv.utf file
  1985. FileDetails.setCsvTerminate(df->queryAttributes().queryProp("@csvTerminate"));
  1986. //@csvEscape - character used to define escape for a csv/utf file.
  1987. if (version >= 1.20)
  1988. FileDetails.setCsvEscape(df->queryAttributes().queryProp("@csvEscape"));
  1989. //Time and date of the file
  1990. tmpstr.clear();
  1991. dt.getDateString(tmpstr);
  1992. tmpstr.append(" ");
  1993. dt.getTimeString(tmpstr);
  1994. FileDetails.setModified(tmpstr.str());
  1995. if(df->queryAttributes().hasProp("ECL"))
  1996. FileDetails.setEcl(df->queryAttributes().queryProp("ECL"));
  1997. StringBuffer clusterStr;
  1998. ForEachItemIn(i, clusters)
  1999. {
  2000. if (!clusterStr.length())
  2001. clusterStr.append(clusters.item(i));
  2002. else
  2003. clusterStr.append(",").append(clusters.item(i));
  2004. }
  2005. if (clusterStr.length() > 0)
  2006. {
  2007. if (!checkFileContent(context, udesc, name, clusterStr.str()))
  2008. FileDetails.setShowFileContent(false);
  2009. if (version > 1.05)
  2010. {
  2011. bool fromRoxieCluster = false;
  2012. StringArray roxieClusterNames;
  2013. IArrayOf<IEspTpCluster> roxieclusters;
  2014. CTpWrapper dummy;
  2015. dummy.getClusterProcessList(eqRoxieCluster, roxieclusters);
  2016. ForEachItemIn(k, roxieclusters)
  2017. {
  2018. IEspTpCluster& r_cluster = roxieclusters.item(k);
  2019. StringBuffer sName = r_cluster.getName();
  2020. if (FindInStringArray(clusters, sName.str()))
  2021. {
  2022. fromRoxieCluster = true;
  2023. break;
  2024. }
  2025. }
  2026. FileDetails.setFromRoxieCluster(fromRoxieCluster);
  2027. }
  2028. }
  2029. offset_t mn=LLC(0x7fffffffffffffff), mx=0, sum=0, count=0;
  2030. if (version >= 1.25)
  2031. getFilePartsOnClusters(context, cluster, clusters, df, FileDetails, mn, mx, sum, count);
  2032. else
  2033. {
  2034. FileDetails.setCluster(clusters.item(0));
  2035. IArrayOf<IConstDFUPart>& PartList = FileDetails.getDFUFileParts();
  2036. Owned<IDistributedFilePartIterator> pi = df->getIterator();
  2037. ForEach(*pi)
  2038. {
  2039. Owned<IDistributedFilePart> part = &pi->get();
  2040. for (unsigned int i=0; i<part->numCopies(); i++)
  2041. {
  2042. Owned<IEspDFUPart> FilePart = createDFUPart("","");
  2043. StringBuffer b;
  2044. part->queryNode(i)->endpoint().getUrlStr(b);
  2045. FilePart->setId(part->getPartIndex()+1);
  2046. FilePart->setCopy(i+1);
  2047. FilePart->setIp(b.str());
  2048. FilePart->setPartsize("<N/A>");
  2049. try
  2050. {
  2051. offset_t size=queryDistributedFileSystem().getSize(part);
  2052. if (version >= 1.38)
  2053. FilePart->setPartSizeInt64(size);
  2054. comma c4(size);
  2055. tmpstr.clear();
  2056. tmpstr<<c4;
  2057. FilePart->setPartsize(tmpstr.str());
  2058. if(size!=-1)
  2059. {
  2060. count+=1;
  2061. sum+=size;
  2062. if(size>mx) mx=size;
  2063. if(size<mn) mn=size;
  2064. }
  2065. }
  2066. catch(IException *e)
  2067. {
  2068. StringBuffer msg;
  2069. ERRLOG("Exception %d:%s in WS_DFU queryDistributedFileSystem().getSize()", e->errorCode(), e->errorMessage(msg).str());
  2070. e->Release();
  2071. }
  2072. catch(...)
  2073. {
  2074. ERRLOG("Unknown exception in WS_DFU queryDistributedFileSystem().getSize()");
  2075. }
  2076. PartList.append(*FilePart.getClear());
  2077. }
  2078. }
  2079. }
  2080. if(count)
  2081. {
  2082. IEspDFUFileStat& Stat = FileDetails.updateStat();
  2083. offset_t avg=sum/count;
  2084. offset_t minSkew = avg-mn;
  2085. offset_t maxSkew = mx-avg;
  2086. if (version >= 1.38)
  2087. {
  2088. Stat.setMinSkewInt64(minSkew);
  2089. Stat.setMaxSkewInt64(maxSkew);
  2090. }
  2091. comma c5(minSkew);
  2092. tmpstr.clear();
  2093. tmpstr<<c5;
  2094. Stat.setMinSkew(tmpstr.str());
  2095. comma c6(maxSkew);
  2096. tmpstr.clear();
  2097. tmpstr<<c6;
  2098. Stat.setMaxSkew(tmpstr.str());
  2099. }
  2100. if (version > 1.06)
  2101. {
  2102. const char *wuid = df->queryAttributes().queryProp("@workunit");
  2103. if (wuid && *wuid && (wuid[0]=='W'))
  2104. {
  2105. try
  2106. {
  2107. CWUWrapper wu(wuid, context);
  2108. StringArray graphs;
  2109. Owned<IPropertyTreeIterator> f=&wu->getFileIterator();
  2110. ForEach(*f)
  2111. {
  2112. IPropertyTree &query = f->query();
  2113. const char *fileName = query.queryProp("@name");
  2114. const char *graphName = query.queryProp("@graph");
  2115. if (!fileName || !graphName || !*graphName || stricmp(fileName, name))
  2116. continue;
  2117. graphs.append(graphName);
  2118. }
  2119. FileDetails.setGraphs(graphs);
  2120. }
  2121. catch(...)
  2122. {
  2123. DBGLOG("Failed in retrieving graphs from workunit %s", wuid);
  2124. }
  2125. }
  2126. }
  2127. if (version > 1.08 && udesc)
  2128. {
  2129. SecAccessFlags permission;
  2130. if (getUserFilePermission(context, udesc, name, permission))
  2131. {
  2132. switch (permission)
  2133. {
  2134. case SecAccess_Full:
  2135. FileDetails.setUserPermission("Full Access Permission");
  2136. break;
  2137. case SecAccess_Write:
  2138. FileDetails.setUserPermission("Write Access Permission");
  2139. break;
  2140. case SecAccess_Read:
  2141. FileDetails.setUserPermission("Read Access Permission");
  2142. break;
  2143. case SecAccess_Access:
  2144. FileDetails.setUserPermission("Access Permission");
  2145. break;
  2146. case SecAccess_None:
  2147. FileDetails.setUserPermission("None Access Permission");
  2148. break;
  2149. default:
  2150. FileDetails.setUserPermission("Permission Unknown");
  2151. break;
  2152. }
  2153. }
  2154. }
  2155. if (includeJsonTypeInfo||includeBinTypeInfo)
  2156. {
  2157. if (df->queryAttributes().hasProp("_rtlType"))
  2158. {
  2159. MemoryBuffer layoutBin;
  2160. df->queryAttributes().getPropBin("_rtlType", layoutBin);
  2161. if (includeJsonTypeInfo)
  2162. {
  2163. Owned<IRtlFieldTypeDeserializer> deserializer(createRtlFieldTypeDeserializer());
  2164. const RtlTypeInfo *typeInfo = deserializer->deserialize(layoutBin);
  2165. StringBuffer jsonFormat;
  2166. dumpTypeInfo(jsonFormat, typeInfo);
  2167. FileDetails.setJsonInfo(jsonFormat);
  2168. layoutBin.reset(0);
  2169. }
  2170. if (includeBinTypeInfo)
  2171. FileDetails.setBinInfo(layoutBin);
  2172. }
  2173. else if (df->queryAttributes().hasProp("ECL"))
  2174. {
  2175. const char * kind = df->queryAttributes().queryProp("@kind");
  2176. bool isIndex = (kind && streq(kind, "key"));
  2177. OwnedHqlExpr record = getEclRecordDefinition(df->queryAttributes().queryProp("ECL"));
  2178. if (df->queryAttributes().hasProp("_record_layout"))
  2179. {
  2180. MemoryBuffer mb;
  2181. df->queryAttributes().getPropBin("_record_layout", mb);
  2182. record.setown(patchEclRecordDefinitionFromRecordLayout(record, mb));
  2183. }
  2184. if (includeJsonTypeInfo)
  2185. {
  2186. StringBuffer jsonFormat;
  2187. exportJsonType(jsonFormat, record, isIndex);
  2188. FileDetails.setJsonInfo(jsonFormat);
  2189. }
  2190. if (includeBinTypeInfo)
  2191. {
  2192. MemoryBuffer binFormat;
  2193. exportBinaryType(binFormat, record, isIndex);
  2194. FileDetails.setBinInfo(binFormat);
  2195. }
  2196. }
  2197. }
  2198. PROGLOG("doGetFileDetails: %s done", name);
  2199. }
  2200. bool CWsDfuEx::getQueryFile(const char *logicalName, const char *querySet, const char *queryID, IEspDFUFileDetail &fileDetails)
  2201. {
  2202. Owned<IConstWUClusterInfo> info = getTargetClusterInfo(querySet);
  2203. if (!info || (info->getPlatform()!=RoxieCluster))
  2204. return false;
  2205. SCMStringBuffer process;
  2206. info->getRoxieProcess(process);
  2207. if (!process.length())
  2208. return false;
  2209. Owned<IHpccPackageSet> ps = createPackageSet(process.str());
  2210. if (!ps)
  2211. return false;
  2212. const IHpccPackageMap *pm = ps->queryActiveMap(querySet);
  2213. if (!pm)
  2214. return false;
  2215. const IHpccPackage *pkg = pm->matchPackage(queryID);
  2216. if (!pkg)
  2217. return false;
  2218. const char *pkgid = pkg->locateSuperFile(logicalName);
  2219. if (!pkgid)
  2220. return false;
  2221. fileDetails.setName(logicalName);
  2222. fileDetails.setIsSuperfile(true);
  2223. fileDetails.setPackageID(pkgid);
  2224. StringArray subFiles;
  2225. Owned<ISimpleSuperFileEnquiry> ssfe = pkg->resolveSuperFile(logicalName);
  2226. if (ssfe && ssfe->numSubFiles()>0)
  2227. {
  2228. unsigned count = ssfe->numSubFiles();
  2229. while (count--)
  2230. {
  2231. StringBuffer subfile;
  2232. ssfe->getSubFileName(count, subfile);
  2233. subFiles.append(subfile.str());
  2234. }
  2235. if (!subFiles.empty())
  2236. fileDetails.setSubfiles(subFiles);
  2237. }
  2238. return true;
  2239. }
  2240. void CWsDfuEx::getLogicalFileAndDirectory(IEspContext &context, IUserDescriptor* udesc, const char *dirname,
  2241. bool includeSuperOwner, IArrayOf<IEspDFULogicalFile>& logicalFiles, int& numFiles, int& numDirs)
  2242. {
  2243. double version = context.getClientVersion();
  2244. if (dirname && *dirname)
  2245. PROGLOG("getLogicalFileAndDirectory: %s", dirname);
  2246. else
  2247. PROGLOG("getLogicalFileAndDirectory: folder not specified");
  2248. numFiles = 0;
  2249. numDirs = 0;
  2250. if (dirname && *dirname)
  2251. {
  2252. StringBuffer filterBuf;
  2253. setFileNameFilter(NULL, dirname, filterBuf);
  2254. if (includeSuperOwner)
  2255. filterBuf.append(DFUQFTincludeFileAttr).append(DFUQFilterSeparator).append(DFUQSFAOincludeSuperOwner).append(DFUQFilterSeparator);
  2256. //filters used to filter query result received from dali server.
  2257. DFUQResultField localFilters[8];
  2258. localFilters[0] = DFUQRFterm;
  2259. DFUQResultField sortOrder[] = {DFUQRFterm};
  2260. __int64 cacheHint = 0; //No page
  2261. unsigned totalFiles = 0;
  2262. bool allMatchingFilesReceived = true;
  2263. Owned<IDFAttributesIterator> it = queryDistributedFileDirectory().getLogicalFiles(udesc, sortOrder, filterBuf.str(),
  2264. localFilters, NULL, 0, (unsigned)-1, &cacheHint, &totalFiles, &allMatchingFilesReceived, false, false);
  2265. if(!it)
  2266. throw MakeStringException(ECLWATCH_CANNOT_GET_FILE_ITERATOR,"Cannot get LogicalFile information from file system.");
  2267. ForEach(*it)
  2268. addToLogicalFileList(it->query(), NULL, version, logicalFiles);
  2269. numFiles = totalFiles;
  2270. }
  2271. Owned<IDFScopeIterator> iter = queryDistributedFileDirectory().getScopeIterator(udesc,dirname,false);
  2272. if(iter)
  2273. {
  2274. ForEach(*iter)
  2275. {
  2276. const char *scope = iter->query();
  2277. if (scope && *scope)
  2278. {
  2279. Owned<IEspDFULogicalFile> file = createDFULogicalFile("","");
  2280. file->setDirectory(scope);
  2281. file->setIsDirectory(true);
  2282. logicalFiles.append(*file.getClear());
  2283. numDirs++;
  2284. }
  2285. }
  2286. }
  2287. }
  2288. bool CWsDfuEx::onDFUFileView(IEspContext &context, IEspDFUFileViewRequest &req, IEspDFUFileViewResponse &resp)
  2289. {
  2290. try
  2291. {
  2292. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  2293. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to Browse Files by Scope. Permission denied.");
  2294. Owned<IUserDescriptor> userdesc;
  2295. StringBuffer username;
  2296. context.getUserID(username);
  2297. if(username.length() > 0)
  2298. {
  2299. userdesc.setown(createUserDescriptor());
  2300. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  2301. }
  2302. int numDirs = 0;
  2303. int numFiles = 0;
  2304. IArrayOf<IEspDFULogicalFile> logicalFiles;
  2305. getLogicalFileAndDirectory(context, userdesc.get(), req.getScope(), !req.getIncludeSuperOwner_isNull() && req.getIncludeSuperOwner(), logicalFiles, numFiles, numDirs);
  2306. if (numFiles > 0)
  2307. resp.setNumFiles(numFiles);
  2308. if (req.getScope() && *req.getScope())
  2309. resp.setScope(req.getScope());
  2310. else
  2311. resp.setScope("");
  2312. resp.setDFULogicalFiles(logicalFiles);
  2313. }
  2314. catch(IException* e)
  2315. {
  2316. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  2317. }
  2318. return true;
  2319. }
  2320. __int64 CWsDfuEx::findPositionBySize(const __int64 size, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2321. {
  2322. __int64 addToPos = -1;
  2323. ForEachItemIn(i, LogicalFiles)
  2324. {
  2325. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2326. const char* sSize = File.getLongSize();
  2327. __int64 nSize = atoi64_l(sSize,strlen(sSize));
  2328. if (descend && size > nSize)
  2329. {
  2330. addToPos = i;
  2331. break;
  2332. }
  2333. if (!descend && size < nSize)
  2334. {
  2335. addToPos = i;
  2336. break;
  2337. }
  2338. }
  2339. return addToPos;
  2340. }
  2341. __int64 CWsDfuEx::findPositionByParts(const __int64 parts, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2342. {
  2343. __int64 addToPos = -1;
  2344. ForEachItemIn(i, LogicalFiles)
  2345. {
  2346. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2347. const char* sParts = File.getParts();
  2348. __int64 nParts = atoi64_l(sParts,strlen(sParts));
  2349. if (descend && parts > nParts)
  2350. {
  2351. addToPos = i;
  2352. break;
  2353. }
  2354. if (!descend && parts < nParts)
  2355. {
  2356. addToPos = i;
  2357. break;
  2358. }
  2359. }
  2360. return addToPos;
  2361. }
  2362. __int64 CWsDfuEx::findPositionByRecords(const __int64 records, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2363. {
  2364. __int64 addToPos = -1;
  2365. ForEachItemIn(i, LogicalFiles)
  2366. {
  2367. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2368. const char* sRecords = File.getLongRecordCount();
  2369. __int64 nRecords = atoi64_l(sRecords,strlen(sRecords));
  2370. if (descend && records > nRecords)
  2371. {
  2372. addToPos = i;
  2373. break;
  2374. }
  2375. if (!descend && records < nRecords)
  2376. {
  2377. addToPos = i;
  2378. break;
  2379. }
  2380. }
  2381. return addToPos;
  2382. }
  2383. __int64 CWsDfuEx::findPositionByName(const char *name, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2384. {
  2385. if (!name || (strlen(name) < 1))
  2386. {
  2387. if (descend)
  2388. return -1;
  2389. else
  2390. return 0;
  2391. }
  2392. __int64 addToPos = -1;
  2393. ForEachItemIn(i, LogicalFiles)
  2394. {
  2395. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2396. const char *Name = File.getName();
  2397. if (!Name)
  2398. continue;
  2399. if (descend && strcmp(name, Name)>0)
  2400. {
  2401. addToPos = i;
  2402. break;
  2403. }
  2404. if (!descend && strcmp(name, Name)<0)
  2405. {
  2406. addToPos = i;
  2407. break;
  2408. }
  2409. }
  2410. return addToPos;
  2411. }
  2412. __int64 CWsDfuEx::findPositionByNodeGroup(double version, const char *node, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2413. {
  2414. if (!node || !*node)
  2415. {
  2416. if (descend)
  2417. return -1;
  2418. else
  2419. return 0;
  2420. }
  2421. __int64 addToPos = -1;
  2422. ForEachItemIn(i, LogicalFiles)
  2423. {
  2424. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2425. const char *nodeGroup = NULL;
  2426. if (version < 1.26)
  2427. nodeGroup = File.getClusterName();
  2428. else
  2429. nodeGroup = File.getNodeGroup();
  2430. if (!nodeGroup)
  2431. continue;
  2432. if (descend && strcmp(node, nodeGroup)>0)
  2433. {
  2434. addToPos = i;
  2435. break;
  2436. }
  2437. if (!descend && strcmp(node, nodeGroup)<0)
  2438. {
  2439. addToPos = i;
  2440. break;
  2441. }
  2442. }
  2443. return addToPos;
  2444. }
  2445. __int64 CWsDfuEx::findPositionByOwner(const char *owner, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2446. {
  2447. if (!owner || (strlen(owner) < 1))
  2448. {
  2449. if (descend)
  2450. return -1;
  2451. else
  2452. return 0;
  2453. }
  2454. __int64 addToPos = -1;
  2455. ForEachItemIn(i, LogicalFiles)
  2456. {
  2457. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2458. const char *Owner = File.getOwner();
  2459. if (!Owner)
  2460. continue;
  2461. if (descend && strcmp(owner, Owner)>0)
  2462. {
  2463. addToPos = i;
  2464. break;
  2465. }
  2466. if (!descend && strcmp(owner, Owner)<0)
  2467. {
  2468. addToPos = i;
  2469. break;
  2470. }
  2471. }
  2472. return addToPos;
  2473. }
  2474. __int64 CWsDfuEx::findPositionByDate(const char *datetime, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2475. {
  2476. if (!datetime || (strlen(datetime) < 1))
  2477. {
  2478. if (descend)
  2479. return -1;
  2480. else
  2481. return 0;
  2482. }
  2483. __int64 addToPos = -1;
  2484. ForEachItemIn(i, LogicalFiles)
  2485. {
  2486. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2487. const char *modDate = File.getModified();
  2488. if (!modDate)
  2489. continue;
  2490. if (descend && strcmp(datetime, modDate)>0)
  2491. {
  2492. addToPos = i;
  2493. break;
  2494. }
  2495. if (!descend && strcmp(datetime, modDate)<0)
  2496. {
  2497. addToPos = i;
  2498. break;
  2499. }
  2500. }
  2501. return addToPos;
  2502. }
  2503. __int64 CWsDfuEx::findPositionByDescription(const char *description, bool descend, IArrayOf<IEspDFULogicalFile>& LogicalFiles)
  2504. {
  2505. if (!description || (strlen(description) < 1))
  2506. {
  2507. if (descend)
  2508. return -1;
  2509. else
  2510. return 0;
  2511. }
  2512. __int64 addToPos = -1;
  2513. ForEachItemIn(i, LogicalFiles)
  2514. {
  2515. IEspDFULogicalFile& File = LogicalFiles.item(i);
  2516. const char *Description = File.getDescription();
  2517. if (!Description)
  2518. continue;
  2519. if (descend && strcmp(description, Description)>0)
  2520. {
  2521. addToPos = i;
  2522. break;
  2523. }
  2524. if (!descend && strcmp(description, Description)<0)
  2525. {
  2526. addToPos = i;
  2527. break;
  2528. }
  2529. }
  2530. return addToPos;
  2531. }
  2532. //The code inside this method is copied from previous code for legacy (< 5.0) dali support
  2533. void CWsDfuEx::getAPageOfSortedLogicalFile(IEspContext &context, IUserDescriptor* udesc, IEspDFUQueryRequest & req, IEspDFUQueryResponse & resp)
  2534. {
  2535. double version = context.getClientVersion();
  2536. IArrayOf<IEspDFULogicalFile> LogicalFiles;
  2537. StringBuffer filter;
  2538. const char* fname = req.getLogicalName();
  2539. if(fname && *fname)
  2540. {
  2541. filter.append(fname);
  2542. }
  2543. else
  2544. {
  2545. if(req.getPrefix() && *req.getPrefix())
  2546. {
  2547. filter.append(req.getPrefix());
  2548. filter.append("::");
  2549. }
  2550. filter.append("*");
  2551. }
  2552. Owned<IDFAttributesIterator> fi;
  2553. bool bNotInSuperfile = false;
  2554. const char* sFileType = req.getFileType();
  2555. if (sFileType && !stricmp(sFileType, "Not in Superfiles"))
  2556. {
  2557. bNotInSuperfile = true;
  2558. }
  2559. if (bNotInSuperfile)
  2560. {
  2561. fi.setown(createSubFileFilter(
  2562. queryDistributedFileDirectory().getDFAttributesIterator(filter.toLowerCase().str(),udesc,true,true, NULL),udesc,false)); // NB wrapper owns wrapped iterator
  2563. }
  2564. else
  2565. {
  2566. fi.setown(queryDistributedFileDirectory().getDFAttributesIterator(filter.toLowerCase().str(), udesc,true,true, NULL));
  2567. }
  2568. if(!fi)
  2569. throw MakeStringException(ECLWATCH_CANNOT_GET_FILE_ITERATOR,"Cannot get information from file system.");
  2570. StringBuffer wuFrom, wuTo;
  2571. if(req.getStartDate() && *req.getStartDate())
  2572. {
  2573. CDateTime wuTime;
  2574. wuTime.setString(req.getStartDate(),NULL,true);
  2575. unsigned year, month, day, hour, minute, second, nano;
  2576. wuTime.getDate(year, month, day, true);
  2577. wuTime.getTime(hour, minute, second, nano, true);
  2578. wuFrom.appendf("%4d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second);
  2579. }
  2580. if(req.getEndDate() && *req.getEndDate())
  2581. {
  2582. CDateTime wuTime;
  2583. wuTime.setString(req.getEndDate(),NULL,true);
  2584. unsigned year, month, day, hour, minute, second, nano;
  2585. wuTime.getDate(year, month, day, true);
  2586. wuTime.getTime(hour, minute, second, nano, true);
  2587. wuTo.appendf("%4d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second);
  2588. }
  2589. StringBuffer sortBy;
  2590. if(req.getSortby() && *req.getSortby())
  2591. {
  2592. sortBy.append(req.getSortby());
  2593. }
  2594. unsigned pagesize = req.getPageSize();
  2595. if (pagesize < 1)
  2596. {
  2597. pagesize = 100;
  2598. }
  2599. __int64 displayStartReq = 1;
  2600. if (req.getPageStartFrom() > 0)
  2601. displayStartReq = req.getPageStartFrom();
  2602. __int64 displayStart = displayStartReq - 1;
  2603. __int64 displayEnd = displayStart + pagesize;
  2604. bool descending = req.getDescending();
  2605. const int nFirstN = req.getFirstN();
  2606. const char* sFirstNType = req.getFirstNType();
  2607. const __int64 nFileSizeFrom = req.getFileSizeFrom();
  2608. const __int64 nFileSizeTo = req.getFileSizeTo();
  2609. if (nFirstN > 0)
  2610. {
  2611. displayStart = 0;
  2612. displayEnd = nFirstN;
  2613. if (!stricmp(sFirstNType, "newest"))
  2614. {
  2615. sortBy.set("Modified");
  2616. descending = true;
  2617. }
  2618. else if (!stricmp(sFirstNType, "oldest"))
  2619. {
  2620. sortBy.set("Modified");
  2621. descending = false;
  2622. }
  2623. else if (!stricmp(sFirstNType, "largest"))
  2624. {
  2625. sortBy.set("FileSize");
  2626. descending = true;
  2627. }
  2628. else if (!stricmp(sFirstNType, "smallest"))
  2629. {
  2630. sortBy.set("FileSize");
  2631. descending = false;
  2632. }
  2633. pagesize = nFirstN;
  2634. }
  2635. StringArray roxieClusterNames;
  2636. IArrayOf<IEspTpCluster> roxieclusters;
  2637. CTpWrapper dummy;
  2638. dummy.getClusterProcessList(eqRoxieCluster, roxieclusters);
  2639. ForEachItemIn(k, roxieclusters)
  2640. {
  2641. IEspTpCluster& cluster = roxieclusters.item(k);
  2642. StringBuffer sName = cluster.getName();
  2643. roxieClusterNames.append(sName.str());
  2644. }
  2645. StringArray nodeGroupsReq;
  2646. const char* nodeGroupsReqString = req.getNodeGroup();
  2647. if (nodeGroupsReqString && *nodeGroupsReqString)
  2648. nodeGroupsReq.appendListUniq(nodeGroupsReqString, ",");
  2649. StringBuffer size;
  2650. __int64 totalFiles = 0;
  2651. IArrayOf<IEspDFULogicalFile> LogicalFileList;
  2652. ForEach(*fi)
  2653. {
  2654. IPropertyTree &attr=fi->query();
  2655. const char* logicalName=attr.queryProp("@name");
  2656. if (!logicalName || (logicalName[0] == 0))
  2657. continue;
  2658. try
  2659. {
  2660. StringBuffer pref;
  2661. const char *c=strstr(logicalName, "::");
  2662. if (c)
  2663. pref.append(c-logicalName, logicalName);
  2664. else
  2665. pref.append(logicalName);
  2666. const char* owner=attr.queryProp("@owner");
  2667. if (req.getOwner() && *req.getOwner()!=0)
  2668. {
  2669. if (!owner || stricmp(owner, req.getOwner()))
  2670. continue;
  2671. }
  2672. StringArray nodeGroups;
  2673. StringArray fileNodeGroups;
  2674. if (getFileGroups(&attr,fileNodeGroups)==0)
  2675. {
  2676. if (!nodeGroupsReq.length())
  2677. nodeGroups.append("");
  2678. }
  2679. else if (nodeGroupsReq.length() > 0) // check specified cluster name in list
  2680. {
  2681. ForEachItemIn(ii,nodeGroupsReq)
  2682. {
  2683. const char* nodeGroupReq = nodeGroupsReq.item(ii);
  2684. ForEachItemIn(i,fileNodeGroups)
  2685. {
  2686. if (strieq(fileNodeGroups.item(i), nodeGroupReq))
  2687. {
  2688. nodeGroups.append(nodeGroupReq);
  2689. break;
  2690. }
  2691. }
  2692. }
  2693. }
  2694. else if (fileNodeGroups.length())
  2695. {
  2696. ForEachItemIn(i,fileNodeGroups)
  2697. nodeGroups.append(fileNodeGroups.item(i));
  2698. }
  2699. if (sFileType && *sFileType)
  2700. {
  2701. bool bHasSubFiles = attr.hasProp("@numsubfiles");
  2702. if (bHasSubFiles && (bNotInSuperfile || !stricmp(sFileType, "Logical Files Only")))
  2703. continue;
  2704. else if (!bHasSubFiles && !stricmp(sFileType, "Superfiles Only"))
  2705. continue;
  2706. }
  2707. __int64 recordSize=attr.getPropInt64("@recordSize",0), size=attr.getPropInt64("@size",-1);
  2708. if (nFileSizeFrom > 0 && size < nFileSizeFrom)
  2709. continue;
  2710. if (nFileSizeTo > 0 && size > nFileSizeTo)
  2711. continue;
  2712. StringBuffer modf(attr.queryProp("@modified"));
  2713. char* t=(char *) strchr(modf.str(),'T');
  2714. if(t) *t=' ';
  2715. if (wuFrom.length() && strcmp(modf.str(),wuFrom.str())<0)
  2716. continue;
  2717. if (wuTo.length() && strcmp(modf.str(),wuTo.str())>0)
  2718. continue;
  2719. __int64 parts = 0;
  2720. if(!attr.hasProp("@numsubfiles"))
  2721. parts = attr.getPropInt64("@numparts");
  2722. __int64 records = 0;
  2723. if (attr.hasProp("@recordCount"))
  2724. records = attr.getPropInt64("@recordCount");
  2725. else if(recordSize)
  2726. records = size/recordSize;
  2727. const char* desc = attr.queryProp("@description");
  2728. ForEachItemIn(i, nodeGroups)
  2729. {
  2730. const char* nodeGroup = nodeGroups.item(i);
  2731. __int64 addToPos = -1; //Add to tail
  2732. if (stricmp(sortBy, "FileSize")==0)
  2733. {
  2734. addToPos = findPositionBySize(size, descending, LogicalFileList);
  2735. }
  2736. else if (stricmp(sortBy, "Parts")==0)
  2737. {
  2738. addToPos = findPositionByParts(parts, descending, LogicalFileList);
  2739. }
  2740. else if (stricmp(sortBy, "Owner")==0)
  2741. {
  2742. addToPos = findPositionByOwner(owner, descending, LogicalFileList);
  2743. }
  2744. else if (stricmp(sortBy, "NodeGroup")==0)
  2745. {
  2746. addToPos = findPositionByNodeGroup(version, nodeGroup, descending, LogicalFileList);
  2747. }
  2748. else if (stricmp(sortBy, "Records")==0)
  2749. {
  2750. addToPos = findPositionByRecords(records, descending, LogicalFileList);
  2751. }
  2752. else if (stricmp(sortBy, "Modified")==0)
  2753. {
  2754. addToPos = findPositionByDate(modf.str(), descending, LogicalFileList);
  2755. }
  2756. else if (stricmp(sortBy, "Description")==0)
  2757. {
  2758. addToPos = findPositionByDescription(desc, descending, LogicalFileList);
  2759. }
  2760. else
  2761. {
  2762. addToPos = findPositionByName(logicalName, descending, LogicalFileList);
  2763. }
  2764. totalFiles++;
  2765. if (addToPos < 0 && (totalFiles > displayEnd))
  2766. continue;
  2767. Owned<IEspDFULogicalFile> File = createDFULogicalFile("","");
  2768. File->setPrefix(pref);
  2769. if (version < 1.26)
  2770. File->setClusterName(nodeGroup);
  2771. else
  2772. File->setNodeGroup(nodeGroup);
  2773. File->setName(logicalName);
  2774. File->setOwner(owner);
  2775. File->setDescription(desc);
  2776. File->setModified(modf.str());
  2777. File->setReplicate(true);
  2778. ForEachItemIn(j, roxieClusterNames)
  2779. {
  2780. const char* roxieClusterName = roxieClusterNames.item(j);
  2781. if (roxieClusterName && nodeGroup && strieq(roxieClusterName, nodeGroup))
  2782. {
  2783. File->setFromRoxieCluster(true);
  2784. break;
  2785. }
  2786. }
  2787. bool bSuperfile = false;
  2788. int numSubFiles = attr.hasProp("@numsubfiles");
  2789. if(!numSubFiles)
  2790. {
  2791. File->setDirectory(attr.queryProp("@directory"));
  2792. File->setParts(attr.queryProp("@numparts"));
  2793. }
  2794. else
  2795. {
  2796. bSuperfile = true;
  2797. }
  2798. File->setIsSuperfile(bSuperfile);
  2799. if (version < 1.22)
  2800. File->setIsZipfile(isCompressed(attr));
  2801. else
  2802. {
  2803. File->setIsCompressed(isCompressed(attr));
  2804. if (attr.hasProp("@compressedSize"))
  2805. File->setCompressedFileSize(attr.getPropInt64("@compressedSize"));
  2806. }
  2807. //File->setBrowseData(bKeyFile); //Bug: 39750 - All files should be viewable through ViewKeyFile function
  2808. if (numSubFiles > 1) //Bug 41379 - ViewKeyFile Cannot handle superfile with multiple subfiles
  2809. File->setBrowseData(false);
  2810. else
  2811. File->setBrowseData(true);
  2812. if (version > 1.13)
  2813. {
  2814. bool bKeyFile = false;
  2815. const char * kind = attr.queryProp("@kind");
  2816. if (kind && (stricmp(kind, "key") == 0))
  2817. {
  2818. bKeyFile = true;
  2819. }
  2820. if (version < 1.24)
  2821. File->setIsKeyFile(bKeyFile);
  2822. else if (kind && *kind)
  2823. File->setContentType(kind);
  2824. }
  2825. StringBuffer buf;
  2826. buf << comma(size);
  2827. File->setTotalsize(buf.str());
  2828. char temp[64];
  2829. numtostr(temp, size);
  2830. File->setLongSize(temp);
  2831. numtostr(temp, records);
  2832. File->setLongRecordCount(temp);
  2833. if (records > 0)
  2834. File->setRecordCount((buf.clear()<<comma(records)).str());
  2835. if (addToPos < 0)
  2836. LogicalFileList.append(*File.getClear());
  2837. else
  2838. LogicalFileList.add(*File.getClear(), (int) addToPos);
  2839. if (LogicalFileList.length() > displayEnd)
  2840. LogicalFileList.pop();
  2841. }
  2842. }
  2843. catch(IException* e)
  2844. {
  2845. VStringBuffer msg("Failed to retrieve data for logical file %s: ", logicalName);
  2846. int code = e->errorCode();
  2847. e->errorMessage(msg);
  2848. e->Release();
  2849. throw MakeStringException(code, "%s", msg.str());
  2850. }
  2851. }
  2852. if (displayEnd > LogicalFileList.length())
  2853. displayEnd = LogicalFileList.length();
  2854. for (int i = (int) displayStart; i < (int) displayEnd; i++)
  2855. {
  2856. Owned<IEspDFULogicalFile> File = createDFULogicalFile("","");
  2857. IEspDFULogicalFile& File0 = LogicalFileList.item(i);
  2858. File->copy(File0);
  2859. LogicalFiles.append(*File.getClear());
  2860. }
  2861. resp.setNumFiles(totalFiles);
  2862. resp.setPageSize(pagesize);
  2863. resp.setPageStartFrom(displayStart+1);
  2864. resp.setPageEndAt(displayEnd);
  2865. if (displayStart - pagesize > 0)
  2866. resp.setPrevPageFrom(displayStart - pagesize + 1);
  2867. else if(displayStart > 0)
  2868. resp.setPrevPageFrom(1);
  2869. if(displayEnd < totalFiles)
  2870. {
  2871. resp.setNextPageFrom(displayEnd+1);
  2872. resp.setLastPageFrom((int)(pagesize * floor((double) ((totalFiles-1) / pagesize)) + 1));
  2873. }
  2874. StringBuffer basicQuery;
  2875. if (req.getNodeGroup() && *req.getNodeGroup())
  2876. {
  2877. if (version < 1.26)
  2878. resp.setClusterName(req.getNodeGroup());
  2879. else
  2880. resp.setNodeGroup(req.getNodeGroup());
  2881. addToQueryString(basicQuery, "NodeGroup", req.getNodeGroup());
  2882. }
  2883. if (req.getOwner() && *req.getOwner())
  2884. {
  2885. resp.setOwner(req.getOwner());
  2886. addToQueryString(basicQuery, "Owner", req.getOwner());
  2887. }
  2888. if (req.getPrefix() && *req.getPrefix())
  2889. {
  2890. resp.setPrefix(req.getPrefix());
  2891. addToQueryString(basicQuery, "Prefix", req.getPrefix());
  2892. }
  2893. if (req.getLogicalName() && *req.getLogicalName())
  2894. {
  2895. resp.setLogicalName(req.getLogicalName());
  2896. addToQueryString(basicQuery, "LogicalName", req.getLogicalName());
  2897. }
  2898. if (req.getStartDate() && *req.getStartDate())
  2899. {
  2900. resp.setStartDate(req.getStartDate());
  2901. addToQueryString(basicQuery, "StartDate", req.getStartDate());
  2902. }
  2903. if (req.getEndDate() && *req.getEndDate())
  2904. {
  2905. resp.setEndDate(req.getEndDate());
  2906. addToQueryString(basicQuery, "EndDate", req.getEndDate());
  2907. }
  2908. if (req.getFileType() && *req.getFileType())
  2909. {
  2910. resp.setFileType(req.getFileType());
  2911. addToQueryString(basicQuery, "FileType", req.getFileType());
  2912. }
  2913. if (req.getFileSizeFrom())
  2914. {
  2915. resp.setFileSizeFrom(req.getFileSizeFrom());
  2916. addToQueryStringFromInt(basicQuery, "FileSizeFrom", req.getFileSizeFrom());
  2917. }
  2918. if (req.getFileSizeTo())
  2919. {
  2920. resp.setFileSizeTo(req.getFileSizeTo());
  2921. addToQueryStringFromInt(basicQuery, "FileSizeTo", req.getFileSizeTo());
  2922. }
  2923. StringBuffer ParametersForFilters = basicQuery;
  2924. StringBuffer ParametersForPaging = basicQuery;
  2925. addToQueryStringFromInt(ParametersForFilters, "PageSize",pagesize);
  2926. addToQueryStringFromInt(ParametersForPaging, "PageSize", pagesize);
  2927. if (ParametersForFilters.length() > 0)
  2928. resp.setFilters(ParametersForFilters.str());
  2929. sortBy.clear();
  2930. descending = false;
  2931. if ((req.getFirstN() > 0) && req.getFirstNType() && *req.getFirstNType())
  2932. {
  2933. const char *sFirstNType = req.getFirstNType();
  2934. if (!stricmp(sFirstNType, "newest"))
  2935. {
  2936. sortBy.set("Modified");
  2937. descending = true;
  2938. }
  2939. else if (!stricmp(sFirstNType, "oldest"))
  2940. {
  2941. sortBy.set("Modified");
  2942. descending = false;
  2943. }
  2944. else if (!stricmp(sFirstNType, "largest"))
  2945. {
  2946. sortBy.set("FileSize");
  2947. descending = true;
  2948. }
  2949. else if (!stricmp(sFirstNType, "smallest"))
  2950. {
  2951. sortBy.set("FileSize");
  2952. descending = false;
  2953. }
  2954. }
  2955. else if (req.getSortby() && *req.getSortby())
  2956. {
  2957. sortBy.set(req.getSortby());
  2958. if (req.getDescending())
  2959. descending = req.getDescending();
  2960. }
  2961. if (sortBy.length())
  2962. {
  2963. resp.setSortby(sortBy);
  2964. resp.setDescending(descending);
  2965. StringBuffer strbuf = sortBy;
  2966. strbuf.append("=");
  2967. String str1(strbuf.str());
  2968. String str(basicQuery.str());
  2969. if (str.indexOf(str1) < 0)
  2970. {
  2971. addToQueryString(ParametersForPaging, "Sortby", sortBy);
  2972. addToQueryString(basicQuery, "Sortby", sortBy);
  2973. if (descending)
  2974. {
  2975. addToQueryString(ParametersForPaging, "Descending", "1");
  2976. addToQueryString(basicQuery, "Descending", "1");
  2977. }
  2978. }
  2979. }
  2980. if (basicQuery.length() > 0)
  2981. resp.setBasicQuery(basicQuery.str());
  2982. if (ParametersForPaging.length() > 0)
  2983. resp.setParametersForPaging(ParametersForPaging.str());
  2984. resp.setDFULogicalFiles(LogicalFiles);
  2985. return;
  2986. }
  2987. bool CWsDfuEx::addDFUQueryFilter(DFUQResultField *filters, unsigned short &count, MemoryBuffer &buff, const char* value, DFUQResultField name)
  2988. {
  2989. if (!value || !*value)
  2990. return false;
  2991. filters[count++] = name;
  2992. buff.append(value);
  2993. return true;
  2994. }
  2995. void CWsDfuEx::appendDFUQueryFilter(const char *name, DFUQFilterType type, const char *value, StringBuffer& filterBuf)
  2996. {
  2997. if (!name || !*name || !value || !*value)
  2998. return;
  2999. filterBuf.append(type).append(DFUQFilterSeparator).append(name).append(DFUQFilterSeparator).append(value).append(DFUQFilterSeparator);
  3000. }
  3001. void CWsDfuEx::appendDFUQueryFilter(const char *name, DFUQFilterType type, const char *value, const char *valueHigh, StringBuffer& filterBuf)
  3002. {
  3003. if (!name || !*name || !value || !*value)
  3004. return;
  3005. filterBuf.append(type).append(DFUQFilterSeparator).append(name).append(DFUQFilterSeparator).append(value).append(DFUQFilterSeparator);
  3006. filterBuf.append(valueHigh).append(DFUQFilterSeparator);
  3007. }
  3008. void CWsDfuEx::setFileTypeFilter(const char* fileType, StringBuffer& filterBuf)
  3009. {
  3010. DFUQFileTypeFilter fileTypeFilter = DFUQFFTall;
  3011. if (!fileType || !*fileType)
  3012. {
  3013. filterBuf.append(DFUQFTspecial).append(DFUQFilterSeparator).append(DFUQSFFileType).append(DFUQFilterSeparator).append(fileTypeFilter).append(DFUQFilterSeparator);
  3014. return;
  3015. }
  3016. bool notInSuperfile = false;
  3017. if (strieq(fileType, "Superfiles Only"))
  3018. fileTypeFilter = DFUQFFTsuperfileonly;
  3019. else if (strieq(fileType, "Logical Files Only"))
  3020. fileTypeFilter = DFUQFFTnonsuperfileonly;
  3021. else if (strieq(fileType, "Not in Superfiles"))
  3022. notInSuperfile = true;
  3023. else
  3024. fileTypeFilter = DFUQFFTall;
  3025. filterBuf.append(DFUQFTspecial).append(DFUQFilterSeparator).append(DFUQSFFileType).append(DFUQFilterSeparator).append(fileTypeFilter).append(DFUQFilterSeparator);
  3026. if (notInSuperfile)
  3027. appendDFUQueryFilter(getDFUQFilterFieldName(DFUQFFsuperowner), DFUQFThasProp, "0", filterBuf);
  3028. }
  3029. void CWsDfuEx::setFileNameFilter(const char* fname, const char* prefix, StringBuffer &filterBuf)
  3030. {
  3031. StringBuffer fileNameFilter;
  3032. if(fname && *fname)
  3033. fileNameFilter.append(fname);//ex. *part_of_file_name*
  3034. else
  3035. {
  3036. if(prefix && *prefix)
  3037. {
  3038. fileNameFilter.append(prefix);
  3039. fileNameFilter.append("::");
  3040. }
  3041. fileNameFilter.append("*");
  3042. }
  3043. fileNameFilter.toLowerCase();
  3044. filterBuf.append(DFUQFTspecial).append(DFUQFilterSeparator).append(DFUQSFFileNameWithPrefix).append(DFUQFilterSeparator).append(fileNameFilter.str()).append(DFUQFilterSeparator);
  3045. }
  3046. void CWsDfuEx::setFileIterateFilter(unsigned maxFiles, StringBuffer &filterBuf)
  3047. {
  3048. filterBuf.append(DFUQFTspecial).append(DFUQFilterSeparator).append(DFUQSFMaxFiles).append(DFUQFilterSeparator)
  3049. .append(maxFiles).append(DFUQFilterSeparator);
  3050. }
  3051. void CWsDfuEx::setDFUQueryFilters(IEspDFUQueryRequest& req, StringBuffer& filterBuf)
  3052. {
  3053. setFileNameFilter(req.getLogicalName(), req.getPrefix(), filterBuf);
  3054. setFileTypeFilter(req.getFileType(), filterBuf);
  3055. appendDFUQueryFilter(getDFUQFilterFieldName(DFUQFFattrowner), DFUQFTwildcardMatch, req.getOwner(), filterBuf);
  3056. appendDFUQueryFilter(getDFUQFilterFieldName(DFUQFFkind), DFUQFTwildcardMatch, req.getContentType(), filterBuf);
  3057. appendDFUQueryFilter(getDFUQFilterFieldName(DFUQFFgroup), DFUQFTcontainString, req.getNodeGroup(), ",", filterBuf);
  3058. if (!req.getIncludeSuperOwner_isNull() && req.getIncludeSuperOwner())
  3059. filterBuf.append(DFUQFTincludeFileAttr).append(DFUQFilterSeparator).append(DFUQSFAOincludeSuperOwner).append(DFUQFilterSeparator);
  3060. __int64 sizeFrom = req.getFileSizeFrom();
  3061. __int64 sizeTo = req.getFileSizeTo();
  3062. if ((sizeFrom > 0) || (sizeTo > 0))
  3063. {
  3064. StringBuffer buf;
  3065. if (sizeFrom > 0)
  3066. buf.append(sizeFrom);
  3067. buf.append("|");
  3068. if (sizeTo > 0)
  3069. buf.append(sizeTo);
  3070. filterBuf.append(DFUQFTinteger64Range).append(DFUQFilterSeparator).append(getDFUQFilterFieldName(DFUQFFattrsize));
  3071. filterBuf.append(DFUQFilterSeparator).append(buf.str()).append(DFUQFilterSeparator);
  3072. }
  3073. const char* startDate = req.getStartDate();
  3074. const char* endDate = req.getEndDate();
  3075. if((startDate && *startDate) || (endDate && *endDate))
  3076. {
  3077. StringBuffer buf;
  3078. if(startDate && *startDate)
  3079. {
  3080. StringBuffer wuFrom;
  3081. CDateTime wuTime;
  3082. wuTime.setString(startDate,NULL);
  3083. buf.append(wuTime.getString(wuFrom).str());
  3084. }
  3085. buf.append("|");
  3086. if(endDate && *endDate)
  3087. {
  3088. StringBuffer wuTo;
  3089. CDateTime wuTime;
  3090. wuTime.setString(endDate,NULL);
  3091. buf.append(wuTime.getString(wuTo).str());
  3092. }
  3093. filterBuf.append(DFUQFTstringRange).append(DFUQFilterSeparator).append(getDFUQFilterFieldName(DFUQFFtimemodified));
  3094. filterBuf.append(DFUQFilterSeparator).append(buf.str()).append(DFUQFilterSeparator);
  3095. }
  3096. }
  3097. void CWsDfuEx::setDFUQuerySortOrder(IEspDFUQueryRequest& req, StringBuffer& sortBy, bool& descending, DFUQResultField* sortOrder)
  3098. {
  3099. const char* sortByReq = req.getSortby();
  3100. if (!sortByReq || !*sortByReq)
  3101. return;
  3102. sortBy.set(sortByReq);
  3103. if (req.getDescending())
  3104. descending = req.getDescending();
  3105. const char* sortByPtr = sortBy.str();
  3106. if (strieq(sortByPtr, "FileSize"))
  3107. sortOrder[0] = (DFUQResultField) (DFUQRFsize | DFUQRFnumeric);
  3108. else if (strieq(sortByPtr, "IsCompressed"))
  3109. sortOrder[0] = (DFUQResultField) (DFUQRFiscompressed | DFUQRFnumeric);
  3110. else if (strieq(sortByPtr, "CompressedSize"))
  3111. sortOrder[0] = (DFUQResultField) (DFUQRFcompressedsize | DFUQRFnumeric);
  3112. else if (strieq(sortByPtr, "Parts"))
  3113. sortOrder[0] = (DFUQResultField) (DFUQRFnumparts | DFUQRFnumeric);
  3114. else if (strieq(sortByPtr, "Records"))
  3115. sortOrder[0] = (DFUQResultField) (DFUQRFrecordcount | DFUQRFnumeric);
  3116. else if (strieq(sortByPtr, "Owner"))
  3117. sortOrder[0] = DFUQRFowner;
  3118. else if (strieq(sortByPtr, "NodeGroup"))
  3119. sortOrder[0] = DFUQRFnodegroup;
  3120. else if (strieq(sortByPtr, "Modified"))
  3121. sortOrder[0] = DFUQRFtimemodified;
  3122. else if (strieq(sortByPtr, "ContentType"))
  3123. sortOrder[0] = DFUQRFkind;
  3124. else
  3125. sortOrder[0] = DFUQRFname;
  3126. sortOrder[0] = (DFUQResultField) (sortOrder[0] | DFUQRFnocase);
  3127. if (descending)
  3128. sortOrder[0] = (DFUQResultField) (sortOrder[0] | DFUQRFreverse);
  3129. return;
  3130. }
  3131. const char* CWsDfuEx::getPrefixFromLogicalName(const char* logicalName, StringBuffer& prefix)
  3132. {
  3133. if (!logicalName || !*logicalName)
  3134. return NULL;
  3135. const char *c=strstr(logicalName, "::");
  3136. if (c)
  3137. prefix.append(c-logicalName, logicalName);
  3138. else
  3139. prefix.append(logicalName);
  3140. return prefix.str();
  3141. }
  3142. bool CWsDfuEx::addToLogicalFileList(IPropertyTree& file, const char* nodeGroup, double version, IArrayOf<IEspDFULogicalFile>& logicalFiles)
  3143. {
  3144. const char* logicalName = file.queryProp(getDFUQResultFieldName(DFUQRFname));
  3145. if (!logicalName || !*logicalName)
  3146. return false;
  3147. try
  3148. {
  3149. Owned<IEspDFULogicalFile> lFile = createDFULogicalFile("","");
  3150. lFile->setName(logicalName);
  3151. lFile->setOwner(file.queryProp(getDFUQResultFieldName(DFUQRFowner)));
  3152. StringBuffer buf(file.queryProp(getDFUQResultFieldName(DFUQRFtimemodified)));
  3153. lFile->setModified(buf.replace('T', ' ').str());
  3154. lFile->setPrefix(getPrefixFromLogicalName(logicalName, buf.clear()));
  3155. lFile->setDescription(file.queryProp(getDFUQResultFieldName(DFUQRFdescription)));
  3156. if (!nodeGroup || !*nodeGroup)
  3157. nodeGroup = file.queryProp(getDFUQResultFieldName(DFUQRFnodegroup));
  3158. if (nodeGroup && *nodeGroup)
  3159. {
  3160. if (version < 1.26)
  3161. lFile->setClusterName(nodeGroup);
  3162. else
  3163. lFile->setNodeGroup(nodeGroup);
  3164. }
  3165. int numSubFiles = file.hasProp(getDFUQResultFieldName(DFUQRFnumsubfiles));
  3166. if(numSubFiles)
  3167. lFile->setIsSuperfile(true);
  3168. else
  3169. {
  3170. lFile->setIsSuperfile(false);
  3171. lFile->setDirectory(file.queryProp(getDFUQResultFieldName(DFUQRFdirectory)));
  3172. lFile->setParts(file.queryProp(getDFUQResultFieldName(DFUQRFnumparts)));
  3173. }
  3174. lFile->setBrowseData(numSubFiles > 1 ? false : true); ////Bug 41379 - ViewKeyFile Cannot handle superfile with multiple subfiles
  3175. if (version >= 1.30)
  3176. {
  3177. bool persistent = file.getPropBool(getDFUQResultFieldName(DFUQRFpersistent), false);
  3178. if (persistent)
  3179. lFile->setPersistent(true);
  3180. if (file.hasProp(getDFUQResultFieldName(DFUQRFsuperowners)))
  3181. lFile->setSuperOwners(file.queryProp(getDFUQResultFieldName(DFUQRFsuperowners)));
  3182. if (file.hasProp(getDFUQResultFieldName(DFUQRFprotect)))
  3183. lFile->setIsProtected(true);
  3184. }
  3185. __int64 size = file.getPropInt64(getDFUQResultFieldName(DFUQRForigsize),0);
  3186. if (size > 0)
  3187. {
  3188. lFile->setIntSize(size);
  3189. lFile->setTotalsize((buf.clear()<<comma(size)).str());
  3190. }
  3191. __int64 records = file.getPropInt64(getDFUQResultFieldName(DFUQRFrecordcount),0);
  3192. if (!records)
  3193. records = file.getPropInt64(getDFUQResultFieldName(DFUQRForigrecordcount),0);
  3194. if (!records)
  3195. {
  3196. __int64 recordSize=file.getPropInt64(getDFUQResultFieldName(DFUQRFrecordsize),0);
  3197. if(recordSize > 0)
  3198. records = size/recordSize;
  3199. }
  3200. if (records > 0)
  3201. {
  3202. lFile->setIntRecordCount(records);
  3203. lFile->setRecordCount((buf.clear()<<comma(records)).str());
  3204. }
  3205. bool isKeyFile = false;
  3206. if (version > 1.13)
  3207. {
  3208. const char * kind = file.queryProp(getDFUQResultFieldName(DFUQRFkind));
  3209. if (kind && *kind)
  3210. {
  3211. if (strieq(kind, "key"))
  3212. isKeyFile = true;
  3213. if (version >= 1.24)
  3214. lFile->setContentType(kind);
  3215. else
  3216. lFile->setIsKeyFile(isKeyFile);
  3217. }
  3218. }
  3219. bool isFileCompressed = file.getPropBool(getDFUQResultFieldName(DFUQRFiscompressed));
  3220. if (isFileCompressed)
  3221. {
  3222. if (version >= 1.22)
  3223. {
  3224. if (file.hasProp(getDFUQResultFieldName(DFUQRFcompressedsize)))
  3225. lFile->setCompressedFileSize(file.getPropInt64(getDFUQResultFieldName(DFUQRFcompressedsize)));
  3226. else if (isKeyFile)
  3227. lFile->setCompressedFileSize(size);
  3228. }
  3229. }
  3230. if (version < 1.22)
  3231. lFile->setIsZipfile(isFileCompressed);
  3232. else
  3233. lFile->setIsCompressed(isFileCompressed);
  3234. logicalFiles.append(*lFile.getClear());
  3235. }
  3236. catch(IException* e)
  3237. {
  3238. VStringBuffer msg("Failed to retrieve data for logical file %s: ", logicalName);
  3239. int code = e->errorCode();
  3240. e->errorMessage(msg);
  3241. e->Release();
  3242. throw MakeStringException(code, "%s", msg.str());
  3243. }
  3244. return true;
  3245. }
  3246. void CWsDfuEx::setDFUQueryResponse(IEspContext &context, unsigned totalFiles, StringBuffer& sortBy, bool descending, unsigned pageStart, unsigned pageSize,
  3247. IEspDFUQueryRequest& req, IEspDFUQueryResponse& resp)
  3248. {
  3249. //for legacy
  3250. double version = context.getClientVersion();
  3251. unsigned pageEnd = pageStart + pageSize;
  3252. if (pageEnd > totalFiles)
  3253. pageEnd = totalFiles;
  3254. resp.setNumFiles(totalFiles);
  3255. resp.setPageSize(pageSize);
  3256. resp.setPageStartFrom(pageStart+1);
  3257. resp.setPageEndAt(pageEnd);
  3258. if (pageStart > pageSize)
  3259. resp.setPrevPageFrom(pageStart - pageSize + 1);
  3260. else if(pageStart > 0)
  3261. resp.setPrevPageFrom(1);
  3262. if(pageEnd < totalFiles)
  3263. {
  3264. resp.setNextPageFrom(pageEnd+1);
  3265. resp.setLastPageFrom((int)(pageSize * floor((double) ((totalFiles-1) / pageSize)) + 1));
  3266. }
  3267. StringBuffer queryReq;
  3268. if (req.getNodeGroup() && *req.getNodeGroup())
  3269. {
  3270. if (version < 1.26)
  3271. resp.setClusterName(req.getNodeGroup());
  3272. else
  3273. resp.setNodeGroup(req.getNodeGroup());
  3274. addToQueryString(queryReq, "NodeGroup", req.getNodeGroup());
  3275. }
  3276. if (req.getOwner() && *req.getOwner())
  3277. {
  3278. resp.setOwner(req.getOwner());
  3279. addToQueryString(queryReq, "Owner", req.getOwner());
  3280. }
  3281. if (req.getPrefix() && *req.getPrefix())
  3282. {
  3283. resp.setPrefix(req.getPrefix());
  3284. addToQueryString(queryReq, "Prefix", req.getPrefix());
  3285. }
  3286. if (req.getLogicalName() && *req.getLogicalName())
  3287. {
  3288. resp.setLogicalName(req.getLogicalName());
  3289. addToQueryString(queryReq, "LogicalName", req.getLogicalName());
  3290. }
  3291. if (req.getStartDate() && *req.getStartDate())
  3292. {
  3293. resp.setStartDate(req.getStartDate());
  3294. addToQueryString(queryReq, "StartDate", req.getStartDate());
  3295. }
  3296. if (req.getEndDate() && *req.getEndDate())
  3297. {
  3298. resp.setEndDate(req.getEndDate());
  3299. addToQueryString(queryReq, "EndDate", req.getEndDate());
  3300. }
  3301. if (req.getFileType() && *req.getFileType())
  3302. {
  3303. resp.setFileType(req.getFileType());
  3304. addToQueryString(queryReq, "FileType", req.getFileType());
  3305. }
  3306. if (req.getFileSizeFrom())
  3307. {
  3308. resp.setFileSizeFrom(req.getFileSizeFrom());
  3309. addToQueryStringFromInt(queryReq, "FileSizeFrom", req.getFileSizeFrom());
  3310. }
  3311. if (req.getFileSizeTo())
  3312. {
  3313. resp.setFileSizeTo(req.getFileSizeTo());
  3314. addToQueryStringFromInt(queryReq, "FileSizeTo", req.getFileSizeTo());
  3315. }
  3316. StringBuffer queryReqNoPageSize = queryReq;
  3317. addToQueryStringFromInt(queryReq, "PageSize", pageSize);
  3318. resp.setFilters(queryReq.str());
  3319. if (sortBy.length())
  3320. {
  3321. resp.setSortby(sortBy.str());
  3322. resp.setDescending(descending);
  3323. addToQueryString(queryReq, "Sortby", sortBy.str());
  3324. addToQueryString(queryReqNoPageSize, "Sortby", sortBy.str());
  3325. if (descending)
  3326. {
  3327. addToQueryString(queryReq, "Descending", "1");
  3328. addToQueryString(queryReqNoPageSize, "Descending", "1");
  3329. }
  3330. }
  3331. resp.setBasicQuery(queryReqNoPageSize.str());
  3332. resp.setParametersForPaging(queryReq.str());
  3333. return;
  3334. }
  3335. bool CWsDfuEx::doLogicalFileSearch(IEspContext &context, IUserDescriptor* udesc, IEspDFUQueryRequest & req, IEspDFUQueryResponse & resp)
  3336. {
  3337. double version = context.getClientVersion();
  3338. if (req.getOneLevelDirFileReturn())
  3339. {
  3340. int numDirs = 0;
  3341. int numFiles = 0;
  3342. IArrayOf<IEspDFULogicalFile> logicalFiles;
  3343. getLogicalFileAndDirectory(context, udesc, req.getLogicalName(), !req.getIncludeSuperOwner_isNull() && req.getIncludeSuperOwner(), logicalFiles, numFiles, numDirs);
  3344. return true;
  3345. }
  3346. if (queryDaliServerVersion().compare("3.11") < 0)
  3347. {//Dali server does not support Filtered File Query. Use legacy code.
  3348. PROGLOG("DFUQuery: getAPageOfSortedLogicalFile");
  3349. getAPageOfSortedLogicalFile(context, udesc, req, resp);
  3350. return true;
  3351. }
  3352. StringBuffer filterBuf;
  3353. setDFUQueryFilters(req, filterBuf);
  3354. //Now, set filters which are used to filter query result received from dali server.
  3355. unsigned short localFilterCount = 0;
  3356. DFUQResultField localFilters[8];
  3357. MemoryBuffer localFilterBuf;
  3358. addDFUQueryFilter(localFilters, localFilterCount, localFilterBuf, req.getNodeGroup(), DFUQRFnodegroup);
  3359. localFilters[localFilterCount] = DFUQRFterm;
  3360. StringBuffer sortBy;
  3361. bool descending = false;
  3362. DFUQResultField sortOrder[2] = {DFUQRFname, DFUQRFterm};
  3363. setDFUQuerySortOrder(req, sortBy, descending, sortOrder);
  3364. unsigned pageStart = 0;
  3365. if (req.getPageStartFrom() > 0)
  3366. pageStart = req.getPageStartFrom() - 1;
  3367. unsigned pageSize = req.getPageSize();
  3368. if (pageSize < 1)
  3369. pageSize = 100;
  3370. const int firstN = req.getFirstN();
  3371. if (firstN > 0)
  3372. {
  3373. pageStart = 0;
  3374. pageSize = firstN;
  3375. }
  3376. unsigned maxFiles = 0;
  3377. if(!req.getMaxNumberOfFiles_isNull())
  3378. maxFiles = req.getMaxNumberOfFiles();
  3379. if (maxFiles == 0)
  3380. maxFiles = ITERATE_FILTEREDFILES_LIMIT;
  3381. if (maxFiles != ITERATE_FILTEREDFILES_LIMIT)
  3382. setFileIterateFilter(maxFiles, filterBuf);
  3383. __int64 cacheHint = 0;
  3384. if (!req.getCacheHint_isNull())
  3385. cacheHint = req.getCacheHint();
  3386. bool allMatchingFilesReceived = true;
  3387. unsigned totalFiles = 0;
  3388. PROGLOG("DFUQuery: getLogicalFilesSorted");
  3389. Owned<IDFAttributesIterator> it = queryDistributedFileDirectory().getLogicalFilesSorted(udesc, sortOrder, filterBuf.str(),
  3390. localFilters, localFilterBuf.bufferBase(), pageStart, pageSize, &cacheHint, &totalFiles, &allMatchingFilesReceived);
  3391. if(!it)
  3392. throw MakeStringException(ECLWATCH_CANNOT_GET_FILE_ITERATOR,"Cannot get information from file system.");
  3393. PROGLOG("DFUQuery: getLogicalFilesSorted done");
  3394. IArrayOf<IEspDFULogicalFile> logicalFiles;
  3395. ForEach(*it)
  3396. addToLogicalFileList(it->query(), NULL, version, logicalFiles);
  3397. if (!allMatchingFilesReceived)
  3398. {
  3399. VStringBuffer warning("The returned results (%d files) represent a subset of the total number of matches. Using a correct filter may reduce the number of matches.",
  3400. maxFiles);
  3401. resp.setWarning(warning.str());
  3402. resp.setIsSubsetOfFiles(!allMatchingFilesReceived);
  3403. }
  3404. resp.setCacheHint(cacheHint);
  3405. resp.setDFULogicalFiles(logicalFiles);
  3406. setDFUQueryResponse(context, totalFiles, sortBy, descending, pageStart, pageSize, req, resp); //This call may be removed after 5.0
  3407. return true;
  3408. }
  3409. bool CWsDfuEx::onSuperfileList(IEspContext &context, IEspSuperfileListRequest &req, IEspSuperfileListResponse &resp)
  3410. {
  3411. try
  3412. {
  3413. const char* superfile = req.getSuperfile();
  3414. if (!superfile || !*superfile)
  3415. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Superfile name required");
  3416. PROGLOG("SuperfileList: %s", superfile);
  3417. StringBuffer username;
  3418. context.getUserID(username);
  3419. Owned<IUserDescriptor> userdesc;
  3420. if(username.length() > 0)
  3421. {
  3422. userdesc.setown(createUserDescriptor());
  3423. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  3424. }
  3425. Owned<IDFUhelper> dfuhelper = createIDFUhelper();
  3426. StringArray farray;
  3427. StringAttrArray subfiles;
  3428. dfuhelper->listSubFiles(req.getSuperfile(), subfiles, userdesc.get());
  3429. for(unsigned i = 0; i < subfiles.length(); i++)
  3430. {
  3431. StringAttrItem& subfile = subfiles.item(i);
  3432. farray.append(subfile.text);
  3433. }
  3434. if(farray.length() > 0)
  3435. resp.setSubfiles(farray);
  3436. resp.setSuperfile(req.getSuperfile());
  3437. }
  3438. catch(IException* e)
  3439. {
  3440. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  3441. }
  3442. return true;
  3443. }
  3444. bool CWsDfuEx::onSuperfileAction(IEspContext &context, IEspSuperfileActionRequest &req, IEspSuperfileActionResponse &resp)
  3445. {
  3446. try
  3447. {
  3448. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Write, false))
  3449. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to Superfile action. Permission denied.");
  3450. const char* action = req.getAction();
  3451. const char* superfile = req.getSuperfile();
  3452. superfileAction(context, action, superfile, req.getSubfiles(), req.getBefore(), true, true, req.getDelete(), req.getRemoveSuperfile());
  3453. resp.setRetcode(0);
  3454. if (superfile && *superfile && action && strieq(action, "remove"))
  3455. {
  3456. Owned<IUserDescriptor> udesc;
  3457. udesc.setown(createUserDescriptor());
  3458. udesc->set(context.queryUserId(), context.queryPassword(), context.querySignature());
  3459. Owned<IDistributedSuperFile> fp = queryDistributedFileDirectory().lookupSuperFile(superfile,udesc);
  3460. if (!fp)
  3461. resp.setRetcode(-1); //Superfile has been removed.
  3462. }
  3463. resp.setSuperfile(req.getSuperfile());
  3464. }
  3465. catch(IException* e)
  3466. {
  3467. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  3468. }
  3469. return true;
  3470. }
  3471. bool CWsDfuEx::onSavexml(IEspContext &context, IEspSavexmlRequest &req, IEspSavexmlResponse &resp)
  3472. {
  3473. try
  3474. {
  3475. StringBuffer username;
  3476. context.getUserID(username);
  3477. Owned<IUserDescriptor> userdesc;
  3478. if(username.length() > 0)
  3479. {
  3480. userdesc.setown(createUserDescriptor());
  3481. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  3482. }
  3483. if (!req.getName() || !*req.getName())
  3484. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Name required");
  3485. PROGLOG("getFileXML: %s", req.getName());
  3486. Owned<IDFUhelper> dfuhelper = createIDFUhelper();
  3487. StringBuffer out;
  3488. dfuhelper->getFileXML(req.getName(), out, userdesc.get());
  3489. MemoryBuffer xmlmap;
  3490. int len = out.length();
  3491. xmlmap.setBuffer(len, out.detach(), true);
  3492. resp.setXmlmap(xmlmap);
  3493. }
  3494. catch(IException* e)
  3495. {
  3496. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  3497. }
  3498. return true;
  3499. }
  3500. bool CWsDfuEx::onAdd(IEspContext &context, IEspAddRequest &req, IEspAddResponse &resp)
  3501. {
  3502. try
  3503. {
  3504. StringBuffer username;
  3505. context.getUserID(username);
  3506. Owned<IUserDescriptor> userdesc;
  3507. if(username.length() > 0)
  3508. {
  3509. userdesc.setown(createUserDescriptor());
  3510. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  3511. }
  3512. if (!req.getDstname() || !*req.getDstname())
  3513. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Dstname required.");
  3514. PROGLOG("addFileXML: %s", req.getDstname());
  3515. Owned<IDFUhelper> dfuhelper = createIDFUhelper();
  3516. StringBuffer xmlstr(req.getXmlmap().length(),(const char*)req.getXmlmap().bufferBase());
  3517. dfuhelper->addFileXML(req.getDstname(), xmlstr, userdesc.get());
  3518. }
  3519. catch(IException* e)
  3520. {
  3521. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  3522. }
  3523. return true;
  3524. }
  3525. bool CWsDfuEx::onAddRemote(IEspContext &context, IEspAddRemoteRequest &req, IEspAddRemoteResponse &resp)
  3526. {
  3527. try
  3528. {
  3529. StringBuffer username;
  3530. context.getUserID(username);
  3531. Owned<IUserDescriptor> userdesc;
  3532. if(username.length() > 0)
  3533. {
  3534. userdesc.setown(createUserDescriptor());
  3535. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  3536. }
  3537. const char* srcusername = req.getSrcusername();
  3538. Owned<IUserDescriptor> srcuserdesc;
  3539. if(srcusername && *srcusername)
  3540. {
  3541. srcuserdesc.setown(createUserDescriptor());
  3542. srcuserdesc->set(srcusername, req.getSrcpassword(), context.querySignature());
  3543. }
  3544. const char* srcname = req.getSrcname();
  3545. if(srcname == NULL || *srcname == '\0')
  3546. throw MakeStringException(ECLWATCH_INVALID_INPUT, "srcname can't be empty.");
  3547. const char* srcdali = req.getSrcdali();
  3548. if(srcdali == NULL || *srcdali == '\0')
  3549. throw MakeStringException(ECLWATCH_INVALID_INPUT, "srcdali can't be empty.");
  3550. const char* dstname = req.getDstname();
  3551. if(dstname == NULL || *dstname == '\0')
  3552. throw MakeStringException(ECLWATCH_INVALID_INPUT, "dstname can't be empty.");
  3553. PROGLOG("addFileRemote: Srcdali %s, Srcname %s, Dstname %s", srcdali, srcname, dstname);
  3554. SocketEndpoint ep(srcdali);
  3555. Owned<IDFUhelper> dfuhelper = createIDFUhelper();
  3556. dfuhelper->addFileRemote(dstname, ep, srcname, srcuserdesc.get(), userdesc.get());
  3557. }
  3558. catch(IException* e)
  3559. {
  3560. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  3561. }
  3562. return true;
  3563. }
  3564. const int INTEGELSIZE = 20;
  3565. const int REALSIZE = 32;
  3566. const int STRINGSIZE = 128;
  3567. bool CWsDfuEx::onDFUGetDataColumns(IEspContext &context, IEspDFUGetDataColumnsRequest &req, IEspDFUGetDataColumnsResponse &resp)
  3568. {
  3569. try
  3570. {
  3571. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  3572. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to View Data File. Permission denied.");
  3573. StringBuffer logicalNameStr;
  3574. char* logicalName0 = (char*) req.getOpenLogicalName();
  3575. if (logicalName0 && *logicalName0)
  3576. {
  3577. logicalNameStr.append(logicalName0);
  3578. logicalNameStr.trim();
  3579. }
  3580. if (logicalNameStr.length() > 0)
  3581. {
  3582. PROGLOG("DFUGetDataColumns: %s", logicalNameStr.str());
  3583. __int64 startIndex = req.getStartIndex();
  3584. __int64 endIndex = req.getEndIndex();
  3585. if (startIndex < 1)
  3586. startIndex = 1;
  3587. if (endIndex < 1)
  3588. endIndex = 100;
  3589. StringArray filterByNames, filterByValues;
  3590. double version = context.getClientVersion();
  3591. if (version > 1.04)
  3592. {
  3593. const char* filterBy = req.getFilterBy();
  3594. if (filterBy && *filterBy)
  3595. {
  3596. parseTwoStringArrays(filterBy, filterByNames, filterByValues);
  3597. }
  3598. const char* showColumns = req.getShowColumns();
  3599. if (showColumns && *showColumns)
  3600. {
  3601. resp.setShowColumns(showColumns);
  3602. }
  3603. }
  3604. StringBuffer username;
  3605. context.getUserID(username);
  3606. Owned<IUserDescriptor> userdesc;
  3607. userdesc.setown(createUserDescriptor());
  3608. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  3609. {
  3610. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(logicalNameStr.str(), userdesc);
  3611. if(!df)
  3612. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Could not find file %s.", logicalNameStr.str());
  3613. IDistributedSuperFile *sf = df->querySuperFile();
  3614. if (sf && (sf->numSubFiles() > 1))
  3615. throw MakeStringException(ECLWATCH_INVALID_ACTION,"This feature is not designed to work with a superfile which contains multiple subfiles.");
  3616. }
  3617. Owned<IResultSetFactory> resultSetFactory = getSecResultSetFactory(context.querySecManager(), context.queryUser(), context.queryUserId(), context.queryPassword());
  3618. Owned<INewResultSet> result;
  3619. if (m_clusterName.length() > 0)
  3620. {
  3621. result.setown(resultSetFactory->createNewFileResultSet(logicalNameStr.str(), m_clusterName.str()));
  3622. }
  3623. else
  3624. {
  3625. result.setown(resultSetFactory->createNewFileResultSet(logicalNameStr.str(), NULL));
  3626. }
  3627. __int64 total=result->getNumRows();
  3628. {
  3629. IArrayOf<IEspDFUDataColumn> dataKeyedColumns[MAX_KEY_ROWS];
  3630. IArrayOf<IEspDFUDataColumn> dataNonKeyedColumns[MAX_KEY_ROWS];
  3631. const IResultSetMetaData & meta = result->getMetaData();
  3632. int columnCount = meta.getColumnCount();
  3633. int keyedColumnCount = meta.getNumKeyedColumns();
  3634. unsigned columnSize = 0;
  3635. int lineSizeCount = 0;
  3636. int lineCount = 0;
  3637. for (int i = 0; i < keyedColumnCount; i++)
  3638. {
  3639. Owned<IEspDFUDataColumn> item = createDFUDataColumn("","");
  3640. bool bNaturalColumn = true;
  3641. SCMStringBuffer columnLabel;
  3642. if (meta.hasSetTranslation(i))
  3643. {
  3644. meta.getNaturalColumnLabel(columnLabel, i);
  3645. }
  3646. if (columnLabel.length() < 1)
  3647. {
  3648. meta.getColumnLabel(columnLabel, i);
  3649. bNaturalColumn = false;
  3650. }
  3651. item->setColumnLabel(columnLabel.str());
  3652. if (version > 1.04 && filterByNames.length() > 0)
  3653. {
  3654. for (unsigned ii = 0; ii < filterByNames.length(); ii++)
  3655. {
  3656. const char* name = filterByNames.item(ii);
  3657. if (name && !stricmp(name, columnLabel.str()))
  3658. {
  3659. const char* value = filterByValues.item(ii);
  3660. if (value && *value)
  3661. {
  3662. item->setColumnValue(value);
  3663. break;
  3664. }
  3665. }
  3666. }
  3667. }
  3668. DisplayType columnType = meta.getColumnDisplayType(i);
  3669. if (bNaturalColumn)
  3670. {
  3671. item->setColumnType("Others");
  3672. item->setColumnSize(STRINGSIZE);
  3673. columnSize = STRINGSIZE;
  3674. item->setMaxSize(columnSize);
  3675. }
  3676. else if (columnType == TypeBoolean)
  3677. {
  3678. item->setColumnType("Boolean");
  3679. item->setMaxSize(1);
  3680. item->setColumnSize(strlen(columnLabel.str()));
  3681. columnSize = 2;
  3682. }
  3683. else
  3684. {
  3685. if (columnType == TypeInteger || columnType == TypeUnsignedInteger)
  3686. {
  3687. item->setColumnType("Integer");
  3688. item->setMaxSize(INTEGELSIZE);
  3689. columnSize = INTEGELSIZE;
  3690. if (strlen(columnLabel.str()) > columnSize)
  3691. columnSize = strlen(columnLabel.str());
  3692. item->setColumnSize(columnSize);
  3693. }
  3694. else if (columnType == TypeReal)
  3695. {
  3696. item->setColumnType("Real");
  3697. item->setMaxSize(REALSIZE);
  3698. columnSize = REALSIZE;
  3699. if (strlen(columnLabel.str()) > columnSize)
  3700. columnSize = strlen(columnLabel.str());
  3701. item->setColumnSize(columnSize);
  3702. }
  3703. else if (columnType == TypeString)
  3704. {
  3705. columnSize = meta.getColumnRawSize(i);
  3706. columnSize = rtlQStrLength(columnSize);
  3707. if (columnSize < 1)
  3708. columnSize = STRINGSIZE;
  3709. else if (columnSize > STRINGSIZE)
  3710. columnSize = STRINGSIZE;
  3711. item->setColumnType("String");
  3712. item->setMaxSize(columnSize);
  3713. if (strlen(columnLabel.str()) > columnSize)
  3714. columnSize = strlen(columnLabel.str());
  3715. item->setColumnSize(columnSize);
  3716. }
  3717. else if (columnType == TypeUnicode)
  3718. {
  3719. item->setColumnType("Others");
  3720. columnSize = (int) (meta.getColumnRawSize(i) * 0.5);
  3721. if (columnSize > STRINGSIZE)
  3722. columnSize = STRINGSIZE;
  3723. item->setColumnSize(columnSize);
  3724. item->setMaxSize(columnSize);
  3725. }
  3726. else
  3727. {
  3728. item->setColumnType("Others");
  3729. columnSize = STRINGSIZE;
  3730. item->setColumnSize(columnSize);
  3731. item->setMaxSize(columnSize);
  3732. }
  3733. }
  3734. columnSize += 7;
  3735. if ((lineSizeCount == 0) && (columnSize > STRINGSIZE)) //One field is big enough to use one line
  3736. {
  3737. if (lineCount >= MAX_KEY_ROWS)
  3738. break;
  3739. dataKeyedColumns[lineCount].append(*item.getLink());
  3740. lineCount++;
  3741. }
  3742. else
  3743. {
  3744. if (lineSizeCount + columnSize < STRINGSIZE)
  3745. {
  3746. lineSizeCount += columnSize;
  3747. }
  3748. else //too big in this line...so, switch to another line
  3749. {
  3750. lineCount++;
  3751. lineSizeCount = columnSize;
  3752. }
  3753. if (lineCount >= MAX_KEY_ROWS)
  3754. break;
  3755. dataKeyedColumns[lineCount].append(*item.getLink());
  3756. }
  3757. }
  3758. columnSize = 0;
  3759. lineSizeCount = 0;
  3760. lineCount = 0;
  3761. for (int ii = keyedColumnCount; ii < columnCount; ii++)
  3762. {
  3763. Owned<IEspDFUDataColumn> item = createDFUDataColumn("","");
  3764. bool bNaturalColumn = true;
  3765. SCMStringBuffer columnLabel;
  3766. if (meta.hasSetTranslation(ii))
  3767. {
  3768. meta.getNaturalColumnLabel(columnLabel, ii);
  3769. }
  3770. if (columnLabel.length() < 1)
  3771. {
  3772. meta.getColumnLabel(columnLabel, ii);
  3773. bNaturalColumn = false;
  3774. }
  3775. item->setColumnLabel(columnLabel.str());
  3776. if (version > 1.04 && filterByNames.length() > 0)
  3777. {
  3778. for (unsigned ii = 0; ii < filterByNames.length(); ii++)
  3779. {
  3780. const char* name = filterByNames.item(ii);
  3781. if (name && !stricmp(name, columnLabel.str()))
  3782. {
  3783. const char* value = filterByValues.item(ii);
  3784. if (value && *value)
  3785. {
  3786. item->setColumnValue(value);
  3787. break;
  3788. }
  3789. }
  3790. }
  3791. }
  3792. DisplayType columnType = meta.getColumnDisplayType(ii);
  3793. if (bNaturalColumn)
  3794. {
  3795. item->setColumnType("Others");
  3796. item->setColumnSize(STRINGSIZE);
  3797. columnSize = STRINGSIZE;
  3798. }
  3799. else if (columnType == TypeBoolean)
  3800. {
  3801. item->setColumnType("Boolean");
  3802. item->setMaxSize(1);
  3803. item->setColumnSize(strlen(columnLabel.str()));
  3804. columnSize = 2;
  3805. }
  3806. else
  3807. {
  3808. if (columnType == TypeInteger || columnType == TypeUnsignedInteger)
  3809. {
  3810. item->setColumnType("Integer");
  3811. item->setMaxSize(INTEGELSIZE);
  3812. columnSize = INTEGELSIZE;
  3813. if (strlen(columnLabel.str()) > columnSize)
  3814. columnSize = strlen(columnLabel.str());
  3815. item->setColumnSize(columnSize);
  3816. }
  3817. else if (columnType == TypeReal)
  3818. {
  3819. item->setColumnType("Real");
  3820. item->setMaxSize(REALSIZE);
  3821. columnSize = REALSIZE;
  3822. if (strlen(columnLabel.str()) > columnSize)
  3823. columnSize = strlen(columnLabel.str());
  3824. item->setColumnSize(columnSize);
  3825. }
  3826. else if (columnType == TypeString)
  3827. {
  3828. columnSize = meta.getColumnRawSize(ii);
  3829. columnSize = rtlQStrLength(columnSize);
  3830. if (columnSize < 1)
  3831. columnSize = STRINGSIZE;
  3832. else if (columnSize > STRINGSIZE)
  3833. columnSize = STRINGSIZE;
  3834. item->setColumnType("String");
  3835. item->setMaxSize(columnSize);
  3836. if (strlen(columnLabel.str()) > columnSize)
  3837. columnSize = strlen(columnLabel.str());
  3838. item->setColumnSize(columnSize);
  3839. }
  3840. else if (columnType == TypeUnicode)
  3841. {
  3842. item->setColumnType("Others");
  3843. columnSize = (int) (meta.getColumnRawSize(ii) * 0.5);
  3844. if (columnSize > STRINGSIZE)
  3845. columnSize = STRINGSIZE;
  3846. item->setColumnSize(columnSize);
  3847. item->setMaxSize(columnSize);
  3848. }
  3849. else
  3850. {
  3851. item->setColumnType("Others");
  3852. columnSize = STRINGSIZE;
  3853. item->setColumnSize(columnSize);
  3854. item->setMaxSize(columnSize);
  3855. }
  3856. }
  3857. columnSize += 7;
  3858. if ((lineSizeCount == 0) && (columnSize > STRINGSIZE))
  3859. {
  3860. if (lineCount >= MAX_KEY_ROWS)
  3861. break;
  3862. dataNonKeyedColumns[lineCount].append(*item.getLink());
  3863. lineCount++;
  3864. }
  3865. else
  3866. {
  3867. if (lineSizeCount + columnSize < STRINGSIZE)
  3868. {
  3869. lineSizeCount += columnSize;
  3870. }
  3871. else
  3872. {
  3873. lineCount++;
  3874. lineSizeCount = columnSize;
  3875. }
  3876. if (lineCount >= MAX_KEY_ROWS)
  3877. break;
  3878. dataNonKeyedColumns[lineCount].append(*item.getLink());
  3879. }
  3880. }
  3881. if (dataKeyedColumns[0].length() > 0)
  3882. resp.setDFUDataKeyedColumns1(dataKeyedColumns[0]);
  3883. if (dataKeyedColumns[1].length() > 0)
  3884. resp.setDFUDataKeyedColumns2(dataKeyedColumns[1]);
  3885. if (dataKeyedColumns[2].length() > 0)
  3886. resp.setDFUDataKeyedColumns3(dataKeyedColumns[2]);
  3887. if (dataKeyedColumns[3].length() > 0)
  3888. resp.setDFUDataKeyedColumns4(dataKeyedColumns[3]);
  3889. if (dataKeyedColumns[4].length() > 0)
  3890. resp.setDFUDataKeyedColumns5(dataKeyedColumns[4]);
  3891. if (dataKeyedColumns[5].length() > 0)
  3892. resp.setDFUDataKeyedColumns6(dataKeyedColumns[5]);
  3893. if (dataKeyedColumns[6].length() > 0)
  3894. resp.setDFUDataKeyedColumns7(dataKeyedColumns[6]);
  3895. if (dataKeyedColumns[7].length() > 0)
  3896. resp.setDFUDataKeyedColumns8(dataKeyedColumns[7]);
  3897. if (dataKeyedColumns[8].length() > 0)
  3898. resp.setDFUDataKeyedColumns9(dataKeyedColumns[8]);
  3899. if (dataKeyedColumns[9].length() > 0)
  3900. resp.setDFUDataKeyedColumns10(dataKeyedColumns[9]);
  3901. if (version > 1.14)
  3902. {
  3903. if (dataKeyedColumns[10].length() > 0)
  3904. resp.setDFUDataKeyedColumns11(dataKeyedColumns[10]);
  3905. if (dataKeyedColumns[11].length() > 0)
  3906. resp.setDFUDataKeyedColumns12(dataKeyedColumns[11]);
  3907. if (dataKeyedColumns[12].length() > 0)
  3908. resp.setDFUDataKeyedColumns13(dataKeyedColumns[12]);
  3909. if (dataKeyedColumns[13].length() > 0)
  3910. resp.setDFUDataKeyedColumns14(dataKeyedColumns[13]);
  3911. if (dataKeyedColumns[14].length() > 0)
  3912. resp.setDFUDataKeyedColumns15(dataKeyedColumns[14]);
  3913. if (dataKeyedColumns[15].length() > 0)
  3914. resp.setDFUDataKeyedColumns16(dataKeyedColumns[15]);
  3915. if (dataKeyedColumns[16].length() > 0)
  3916. resp.setDFUDataKeyedColumns17(dataKeyedColumns[16]);
  3917. if (dataKeyedColumns[17].length() > 0)
  3918. resp.setDFUDataKeyedColumns18(dataKeyedColumns[17]);
  3919. if (dataKeyedColumns[18].length() > 0)
  3920. resp.setDFUDataKeyedColumns19(dataKeyedColumns[18]);
  3921. if (dataKeyedColumns[19].length() > 0)
  3922. resp.setDFUDataKeyedColumns20(dataKeyedColumns[19]);
  3923. }
  3924. if (dataNonKeyedColumns[0].length() > 0)
  3925. resp.setDFUDataNonKeyedColumns1(dataNonKeyedColumns[0]);
  3926. if (dataNonKeyedColumns[1].length() > 0)
  3927. resp.setDFUDataNonKeyedColumns2(dataNonKeyedColumns[1]);
  3928. if (dataNonKeyedColumns[2].length() > 0)
  3929. resp.setDFUDataNonKeyedColumns3(dataNonKeyedColumns[2]);
  3930. if (dataNonKeyedColumns[3].length() > 0)
  3931. resp.setDFUDataNonKeyedColumns4(dataNonKeyedColumns[3]);
  3932. if (dataNonKeyedColumns[4].length() > 0)
  3933. resp.setDFUDataNonKeyedColumns5(dataNonKeyedColumns[4]);
  3934. if (dataNonKeyedColumns[5].length() > 0)
  3935. resp.setDFUDataNonKeyedColumns6(dataNonKeyedColumns[5]);
  3936. if (dataNonKeyedColumns[6].length() > 0)
  3937. resp.setDFUDataNonKeyedColumns7(dataNonKeyedColumns[6]);
  3938. if (dataNonKeyedColumns[7].length() > 0)
  3939. resp.setDFUDataNonKeyedColumns8(dataNonKeyedColumns[7]);
  3940. if (dataNonKeyedColumns[8].length() > 0)
  3941. resp.setDFUDataNonKeyedColumns9(dataNonKeyedColumns[8]);
  3942. if (dataNonKeyedColumns[9].length() > 0)
  3943. resp.setDFUDataNonKeyedColumns10(dataNonKeyedColumns[9]);
  3944. if (version > 1.14)
  3945. {
  3946. if (dataNonKeyedColumns[10].length() > 0)
  3947. resp.setDFUDataNonKeyedColumns11(dataNonKeyedColumns[10]);
  3948. if (dataNonKeyedColumns[11].length() > 0)
  3949. resp.setDFUDataNonKeyedColumns12(dataNonKeyedColumns[11]);
  3950. if (dataNonKeyedColumns[12].length() > 0)
  3951. resp.setDFUDataNonKeyedColumns13(dataNonKeyedColumns[12]);
  3952. if (dataNonKeyedColumns[13].length() > 0)
  3953. resp.setDFUDataNonKeyedColumns14(dataNonKeyedColumns[13]);
  3954. if (dataNonKeyedColumns[14].length() > 0)
  3955. resp.setDFUDataNonKeyedColumns15(dataNonKeyedColumns[14]);
  3956. if (dataNonKeyedColumns[15].length() > 0)
  3957. resp.setDFUDataNonKeyedColumns16(dataNonKeyedColumns[15]);
  3958. if (dataNonKeyedColumns[16].length() > 0)
  3959. resp.setDFUDataNonKeyedColumns17(dataNonKeyedColumns[16]);
  3960. if (dataNonKeyedColumns[17].length() > 0)
  3961. resp.setDFUDataNonKeyedColumns18(dataNonKeyedColumns[17]);
  3962. if (dataNonKeyedColumns[18].length() > 0)
  3963. resp.setDFUDataNonKeyedColumns19(dataNonKeyedColumns[18]);
  3964. if (dataNonKeyedColumns[19].length() > 0)
  3965. resp.setDFUDataNonKeyedColumns20(dataNonKeyedColumns[19]);
  3966. }
  3967. //resp.setColumnCount(columnCount);
  3968. resp.setRowCount(total);
  3969. }
  3970. resp.setLogicalName(logicalNameStr.str());
  3971. resp.setStartIndex(startIndex);
  3972. resp.setEndIndex(endIndex);
  3973. if (version > 1.11)
  3974. {
  3975. if (req.getCluster() && *req.getCluster())
  3976. {
  3977. resp.setCluster(req.getCluster());
  3978. }
  3979. if (req.getClusterType() && *req.getClusterType())
  3980. {
  3981. resp.setClusterType(req.getClusterType());
  3982. }
  3983. }
  3984. }
  3985. if (req.getChooseFile())
  3986. resp.setChooseFile(1);
  3987. else
  3988. resp.setChooseFile(0);
  3989. }
  3990. catch(IException* e)
  3991. {
  3992. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  3993. }
  3994. return true;
  3995. }
  3996. bool CWsDfuEx::onDFUSearchData(IEspContext &context, IEspDFUSearchDataRequest &req, IEspDFUSearchDataResponse &resp)
  3997. {
  3998. try
  3999. {
  4000. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  4001. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to View Data File. Permission denied.");
  4002. double version = context.getClientVersion();
  4003. resp.setCluster(req.getCluster());
  4004. resp.setClusterType(req.getClusterType());
  4005. resp.setFile(req.getFile());
  4006. resp.setKey(req.getKey());
  4007. const char* selectedKey = req.getSelectedKey();
  4008. if (strlen(selectedKey) > 0)
  4009. {
  4010. resp.setSelectedKey(req.getSelectedKey());
  4011. }
  4012. else
  4013. {
  4014. resp.setSelectedKey(req.getKey());
  4015. }
  4016. resp.setParentName(req.getParentName());
  4017. resp.setRoxieSelections(req.getRoxieSelections());
  4018. resp.setDisableUppercaseTranslation(req.getDisableUppercaseTranslation());
  4019. const char* openLogicalName = req.getOpenLogicalName();
  4020. if (strlen(openLogicalName) > 0)
  4021. {
  4022. PROGLOG("DFUSearchData: %s", openLogicalName);
  4023. Owned<IEspDFUGetDataColumnsRequest> DataColumnsRequest = createDFUGetDataColumnsRequest();
  4024. Owned<IEspDFUGetDataColumnsResponse> DataColumnsResponse = createDFUGetDataColumnsResponse();
  4025. DataColumnsRequest->setOpenLogicalName(req.getOpenLogicalName());
  4026. DataColumnsRequest->setFilterBy(req.getFilterBy());
  4027. DataColumnsRequest->setShowColumns(req.getShowColumns());
  4028. DataColumnsRequest->setChooseFile(req.getChooseFile());
  4029. DataColumnsRequest->setCluster(req.getCluster());
  4030. DataColumnsRequest->setClusterType(req.getClusterType());
  4031. try
  4032. {
  4033. onDFUGetDataColumns(context, *DataColumnsRequest, *DataColumnsResponse);
  4034. }
  4035. catch(IException* e)
  4036. {
  4037. if (version < 1.08)
  4038. throw e;
  4039. StringBuffer emsg;
  4040. e->errorMessage(emsg);
  4041. e->Release();
  4042. resp.setMsgToDisplay(emsg);
  4043. return true;
  4044. }
  4045. resp.setOpenLogicalName(req.getOpenLogicalName());
  4046. resp.setLogicalName(DataColumnsResponse->getLogicalName());
  4047. resp.setStartIndex(DataColumnsResponse->getStartIndex());
  4048. resp.setEndIndex(DataColumnsResponse->getEndIndex());
  4049. resp.setDFUDataKeyedColumns1(DataColumnsResponse->getDFUDataKeyedColumns1());
  4050. resp.setDFUDataKeyedColumns2(DataColumnsResponse->getDFUDataKeyedColumns2());
  4051. resp.setDFUDataKeyedColumns3(DataColumnsResponse->getDFUDataKeyedColumns3());
  4052. resp.setDFUDataKeyedColumns4(DataColumnsResponse->getDFUDataKeyedColumns4());
  4053. resp.setDFUDataKeyedColumns5(DataColumnsResponse->getDFUDataKeyedColumns5());
  4054. resp.setDFUDataKeyedColumns6(DataColumnsResponse->getDFUDataKeyedColumns6());
  4055. resp.setDFUDataKeyedColumns7(DataColumnsResponse->getDFUDataKeyedColumns7());
  4056. resp.setDFUDataKeyedColumns8(DataColumnsResponse->getDFUDataKeyedColumns8());
  4057. resp.setDFUDataKeyedColumns9(DataColumnsResponse->getDFUDataKeyedColumns9());
  4058. resp.setDFUDataKeyedColumns10(DataColumnsResponse->getDFUDataKeyedColumns10());
  4059. if (version > 1.14)
  4060. {
  4061. resp.setDFUDataKeyedColumns11(DataColumnsResponse->getDFUDataKeyedColumns11());
  4062. resp.setDFUDataKeyedColumns12(DataColumnsResponse->getDFUDataKeyedColumns12());
  4063. resp.setDFUDataKeyedColumns13(DataColumnsResponse->getDFUDataKeyedColumns13());
  4064. resp.setDFUDataKeyedColumns14(DataColumnsResponse->getDFUDataKeyedColumns14());
  4065. resp.setDFUDataKeyedColumns15(DataColumnsResponse->getDFUDataKeyedColumns15());
  4066. resp.setDFUDataKeyedColumns16(DataColumnsResponse->getDFUDataKeyedColumns16());
  4067. resp.setDFUDataKeyedColumns17(DataColumnsResponse->getDFUDataKeyedColumns17());
  4068. resp.setDFUDataKeyedColumns18(DataColumnsResponse->getDFUDataKeyedColumns18());
  4069. resp.setDFUDataKeyedColumns19(DataColumnsResponse->getDFUDataKeyedColumns19());
  4070. resp.setDFUDataKeyedColumns20(DataColumnsResponse->getDFUDataKeyedColumns20());
  4071. }
  4072. resp.setDFUDataNonKeyedColumns1(DataColumnsResponse->getDFUDataNonKeyedColumns1());
  4073. resp.setDFUDataNonKeyedColumns2(DataColumnsResponse->getDFUDataNonKeyedColumns2());
  4074. resp.setDFUDataNonKeyedColumns3(DataColumnsResponse->getDFUDataNonKeyedColumns3());
  4075. resp.setDFUDataNonKeyedColumns4(DataColumnsResponse->getDFUDataNonKeyedColumns4());
  4076. resp.setDFUDataNonKeyedColumns5(DataColumnsResponse->getDFUDataNonKeyedColumns5());
  4077. resp.setDFUDataNonKeyedColumns6(DataColumnsResponse->getDFUDataNonKeyedColumns6());
  4078. resp.setDFUDataNonKeyedColumns7(DataColumnsResponse->getDFUDataNonKeyedColumns7());
  4079. resp.setDFUDataNonKeyedColumns8(DataColumnsResponse->getDFUDataNonKeyedColumns8());
  4080. resp.setDFUDataNonKeyedColumns9(DataColumnsResponse->getDFUDataNonKeyedColumns9());
  4081. resp.setDFUDataNonKeyedColumns10(DataColumnsResponse->getDFUDataNonKeyedColumns10());
  4082. if (version > 1.14)
  4083. {
  4084. resp.setDFUDataNonKeyedColumns11(DataColumnsResponse->getDFUDataNonKeyedColumns11());
  4085. resp.setDFUDataNonKeyedColumns12(DataColumnsResponse->getDFUDataNonKeyedColumns12());
  4086. resp.setDFUDataNonKeyedColumns13(DataColumnsResponse->getDFUDataNonKeyedColumns13());
  4087. resp.setDFUDataNonKeyedColumns14(DataColumnsResponse->getDFUDataNonKeyedColumns14());
  4088. resp.setDFUDataNonKeyedColumns15(DataColumnsResponse->getDFUDataNonKeyedColumns15());
  4089. resp.setDFUDataNonKeyedColumns16(DataColumnsResponse->getDFUDataNonKeyedColumns16());
  4090. resp.setDFUDataNonKeyedColumns17(DataColumnsResponse->getDFUDataNonKeyedColumns17());
  4091. resp.setDFUDataNonKeyedColumns18(DataColumnsResponse->getDFUDataNonKeyedColumns18());
  4092. resp.setDFUDataNonKeyedColumns19(DataColumnsResponse->getDFUDataNonKeyedColumns19());
  4093. resp.setDFUDataNonKeyedColumns20(DataColumnsResponse->getDFUDataNonKeyedColumns20());
  4094. }
  4095. resp.setRowCount(DataColumnsResponse->getRowCount());
  4096. resp.setShowColumns(DataColumnsResponse->getShowColumns());
  4097. resp.setChooseFile(DataColumnsResponse->getChooseFile());
  4098. }
  4099. const char* logicalName = req.getLogicalName();
  4100. if (strlen(logicalName) == 0 && strlen(openLogicalName) > 0)
  4101. {
  4102. logicalName = openLogicalName;
  4103. }
  4104. if (strlen(logicalName) > 0)
  4105. {
  4106. Owned<IEspDFUBrowseDataRequest> browseDataRequest = createDFUBrowseDataRequest();
  4107. Owned<IEspDFUBrowseDataResponse> browseDataResponse = createDFUBrowseDataResponse();
  4108. browseDataRequest->setLogicalName(logicalName);
  4109. const char* parentName = req.getParentName();
  4110. if (parentName && *parentName)
  4111. browseDataRequest->setParentName(parentName);
  4112. browseDataRequest->setFilterBy(req.getFilterBy());
  4113. browseDataRequest->setShowColumns(req.getShowColumns());
  4114. browseDataRequest->setStartForGoback(req.getStartForGoback());
  4115. browseDataRequest->setCountForGoback(req.getCountForGoback());
  4116. browseDataRequest->setChooseFile(req.getChooseFile());
  4117. browseDataRequest->setStart(req.getStart());
  4118. browseDataRequest->setCount(req.getCount());
  4119. browseDataRequest->setSchemaOnly(req.getSchemaOnly());
  4120. browseDataRequest->setCluster(req.getCluster());
  4121. browseDataRequest->setClusterType(req.getClusterType());
  4122. browseDataRequest->setDisableUppercaseTranslation(req.getDisableUppercaseTranslation());
  4123. onDFUBrowseData(context, *browseDataRequest, *browseDataResponse);
  4124. resp.setName(browseDataResponse->getName());
  4125. resp.setLogicalName(browseDataResponse->getLogicalName());
  4126. resp.setFilterBy(browseDataResponse->getFilterBy());
  4127. resp.setFilterForGoBack(browseDataResponse->getFilterForGoBack());
  4128. resp.setColumnsHidden(browseDataResponse->getColumnsHidden());
  4129. resp.setColumnsHidden(browseDataResponse->getColumnsHidden());
  4130. resp.setColumnCount(browseDataResponse->getColumnCount());
  4131. resp.setStartForGoback(browseDataResponse->getStartForGoback());
  4132. resp.setCountForGoback(browseDataResponse->getCountForGoback());
  4133. resp.setChooseFile(browseDataResponse->getChooseFile());
  4134. resp.setStart(browseDataResponse->getStart());
  4135. resp.setCount(browseDataResponse->getCount());
  4136. resp.setPageSize(browseDataResponse->getPageSize());
  4137. resp.setTotal(browseDataResponse->getTotal());
  4138. resp.setResult(browseDataResponse->getResult());
  4139. resp.setMsgToDisplay(browseDataResponse->getMsgToDisplay());
  4140. resp.setSchemaOnly(browseDataResponse->getSchemaOnly());
  4141. resp.setAutoUppercaseTranslation(!m_disableUppercaseTranslation);
  4142. }
  4143. }
  4144. catch(IException* e)
  4145. {
  4146. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  4147. }
  4148. return true;
  4149. }
  4150. static const char * const columnTypes[] = { "Boolean", "Integer", "Unsigned Integer", "Real", "String",
  4151. "Data", "Unicode", "Unknown", "BeginIfBlock", "EndIfBlock", "BeginRecord", "EndRecord", "Set", "Dataset", NULL };
  4152. bool CWsDfuEx::onDFUGetFileMetaData(IEspContext &context, IEspDFUGetFileMetaDataRequest & req, IEspDFUGetFileMetaDataResponse & resp)
  4153. {
  4154. class CDFUFileMetaDataReader
  4155. {
  4156. unsigned totalColumnCount;
  4157. unsigned keyedColumnCount;
  4158. StringBuffer XmlSchema, XmlXPathSchema;
  4159. IArrayOf<IEspDFUDataColumn> dataColumns;
  4160. const IResultSetMetaData& metaRoot;
  4161. bool readRootLevelColumns;
  4162. IEspContext &context;
  4163. bool readColumnLabel(const IResultSetMetaData* meta, unsigned columnID, IEspDFUDataColumn* out)
  4164. {
  4165. SCMStringBuffer columnLabel;
  4166. bool isNaturalColumn = true;
  4167. if (meta->hasSetTranslation(columnID))
  4168. meta->getNaturalColumnLabel(columnLabel, columnID);
  4169. if (columnLabel.length() < 1)
  4170. {
  4171. meta->getColumnLabel(columnLabel, columnID);
  4172. isNaturalColumn = false;
  4173. }
  4174. out->setColumnLabel(columnLabel.str());
  4175. out->setIsNaturalColumn(isNaturalColumn);
  4176. return isNaturalColumn;
  4177. }
  4178. void readColumn(const IResultSetMetaData* meta, unsigned& columnID, const bool isKeyed,
  4179. IArrayOf<IEspDFUDataColumn>& dataColumns)
  4180. {
  4181. double version = context.getClientVersion();
  4182. Owned<IEspDFUDataColumn> dataItem = createDFUDataColumn();
  4183. dataItem->setColumnID(columnID+1);
  4184. dataItem->setIsKeyedColumn(isKeyed);
  4185. SCMStringBuffer s;
  4186. dataItem->setColumnEclType(meta->getColumnEclType(s, columnID).str());
  4187. DisplayType columnType = meta->getColumnDisplayType(columnID);
  4188. if ((columnType == TypeUnicode) || columnType == TypeString)
  4189. dataItem->setColumnRawSize(meta->getColumnRawSize(columnID));
  4190. if (readColumnLabel(meta, columnID, dataItem))
  4191. dataItem->setColumnType("Others");
  4192. else if (columnType == TypeBeginRecord)
  4193. dataItem->setColumnType("Record");
  4194. else
  4195. dataItem->setColumnType(columnTypes[columnType]);
  4196. if ((version >= 1.31) && ((columnType == TypeSet) || (columnType == TypeDataset) || (columnType == TypeBeginRecord)))
  4197. checkAndReadNestedColumn(meta, columnID, columnType, dataItem);
  4198. dataColumns.append(*dataItem.getClear());
  4199. }
  4200. void readColumns(const IResultSetMetaData* meta, IArrayOf<IEspDFUDataColumn>& dataColumnArray)
  4201. {
  4202. if (!meta)
  4203. return;
  4204. if (readRootLevelColumns)
  4205. {
  4206. readRootLevelColumns = false;
  4207. totalColumnCount = (unsigned)meta->getColumnCount();
  4208. keyedColumnCount = meta->getNumKeyedColumns();
  4209. unsigned i = 0;
  4210. for (; i < keyedColumnCount; i++)
  4211. readColumn(meta, i, true, dataColumnArray);
  4212. for (i = keyedColumnCount; i < totalColumnCount; i++)
  4213. readColumn(meta, i, false, dataColumnArray);
  4214. }
  4215. else
  4216. {
  4217. unsigned columnCount = (unsigned)meta->getColumnCount();
  4218. for (unsigned i = 0; i < columnCount; i++)
  4219. readColumn(meta, i, false, dataColumnArray);
  4220. }
  4221. }
  4222. void checkAndReadNestedColumn(const IResultSetMetaData* meta, unsigned& columnID,
  4223. DisplayType columnType, IEspDFUDataColumn* dataItem)
  4224. {
  4225. IArrayOf<IEspDFUDataColumn> curDataColumnArray;
  4226. if (columnType == TypeBeginRecord)
  4227. {
  4228. columnID++;
  4229. do
  4230. {
  4231. readColumn(meta, columnID, false, curDataColumnArray);
  4232. } while (meta->getColumnDisplayType(++columnID) != TypeEndRecord);
  4233. }
  4234. else
  4235. readColumns(meta->getChildMeta(columnID), curDataColumnArray);
  4236. dataItem->setDataColumns(curDataColumnArray);
  4237. }
  4238. public:
  4239. CDFUFileMetaDataReader(IEspContext& _context, const IResultSetMetaData& _meta)
  4240. : context(_context), metaRoot(_meta), readRootLevelColumns(true)
  4241. {
  4242. readColumns(&metaRoot, dataColumns);
  4243. };
  4244. inline unsigned getTotalColumnCount() { return totalColumnCount; }
  4245. inline unsigned getKeyedColumnCount() { return keyedColumnCount; }
  4246. inline IArrayOf<IEspDFUDataColumn>& getDataColumns() { return dataColumns; }
  4247. inline StringBuffer& getXmlSchema(StringBuffer& s, const bool addHeader)
  4248. {
  4249. StringBufferAdaptor schema(s);
  4250. metaRoot.getXmlSchema(schema, addHeader);
  4251. return s;
  4252. }
  4253. inline StringBuffer& getXmlXPathSchema(StringBuffer& s, const bool addHeader)
  4254. {
  4255. StringBufferAdaptor XPathSchema(s);
  4256. metaRoot.getXmlXPathSchema(XPathSchema, addHeader);
  4257. return s;
  4258. }
  4259. };
  4260. try
  4261. {
  4262. StringBuffer fileNameStr = req.getLogicalFileName();
  4263. const char* fileName = fileNameStr.trim().str();
  4264. if (!fileName || !*fileName)
  4265. throw MakeStringException(ECLWATCH_INVALID_INPUT, "CWsDfuEx::onDFUGetFileMetaData: LogicalFileName not set");
  4266. {//Check whether the meta data is available for the file. If not, throw an exception.
  4267. StringBuffer nameStr;
  4268. Owned<IUserDescriptor> userdesc = createUserDescriptor();
  4269. userdesc->set(context.getUserID(nameStr).str(), context.queryPassword(), context.querySignature());
  4270. Owned<IDistributedFile> df = queryDistributedFileDirectory().lookup(fileName, userdesc);
  4271. if(!df)
  4272. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"CWsDfuEx::onDFUGetFileMetaData: Could not find file %s.", fileName);
  4273. IDistributedSuperFile *sf = df->querySuperFile();
  4274. if (sf && (sf->numSubFiles() > 1))
  4275. throw MakeStringException(ECLWATCH_INVALID_ACTION, "CWsDfuEx::onDFUGetFileMetaData: This feature is not designed to work with a superfile which contains multiple subfiles.");
  4276. }
  4277. const char* cluster = NULL;
  4278. StringBuffer clusterNameStr = req.getClusterName();
  4279. if (clusterNameStr.trim().length() > 0)
  4280. cluster = clusterNameStr.str();
  4281. PROGLOG("DFUGetFileMetaData: %s", fileName);
  4282. Owned<IResultSetFactory> resultSetFactory = getSecResultSetFactory(context.querySecManager(), context.queryUser(), context.queryUserId(), context.queryPassword());
  4283. Owned<INewResultSet> result = resultSetFactory->createNewFileResultSet(fileName, cluster);
  4284. if (!result)
  4285. throw MakeStringException(ECLWATCH_INVALID_INPUT, "CWsDfuEx::onDFUGetFileMetaData: Failed to access FileResultSet for %s.", fileName);
  4286. CDFUFileMetaDataReader dataReader(context, result->getMetaData());
  4287. resp.setTotalColumnCount(dataReader.getTotalColumnCount());
  4288. resp.setKeyedColumnCount(dataReader.getKeyedColumnCount());
  4289. resp.setDataColumns(dataReader.getDataColumns());
  4290. StringBuffer s, s1;
  4291. if (req.getIncludeXmlSchema())
  4292. resp.setXmlSchema(dataReader.getXmlSchema(s, req.getAddHeaderInXmlSchema()).str());
  4293. if (req.getIncludeXmlXPathSchema())
  4294. resp.setXmlXPathSchema(dataReader.getXmlXPathSchema(s1, req.getAddHeaderInXmlXPathSchema()).str());
  4295. resp.setTotalResultRows(result->getNumRows());
  4296. }
  4297. catch(IException* e)
  4298. {
  4299. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  4300. }
  4301. return true;
  4302. }
  4303. bool CWsDfuEx::onDFUBrowseData(IEspContext &context, IEspDFUBrowseDataRequest &req, IEspDFUBrowseDataResponse &resp)
  4304. {
  4305. try
  4306. {
  4307. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  4308. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to View Data File. Permission denied.");
  4309. const char* logicalName0 = req.getLogicalName();
  4310. const char* parentName = req.getParentName();
  4311. if (!logicalName0 || !*logicalName0)
  4312. throw MakeStringException(ECLWATCH_INVALID_INPUT,"No LogicalName defined.");
  4313. StringBuffer logicalNameStr;
  4314. if (logicalName0 && *logicalName0)
  4315. {
  4316. logicalNameStr.append(logicalName0);
  4317. logicalNameStr.trim();
  4318. if (logicalNameStr.length() < 1)
  4319. throw MakeStringException(ECLWATCH_INVALID_INPUT,"No LogicalName defined.");
  4320. }
  4321. PROGLOG("DFUBrowseData: %s", logicalNameStr.str());
  4322. __int64 start = req.getStart() > 0 ? req.getStart() : 0;
  4323. __int64 count=req.getCount() ? req.getCount() : 20, requested=count;
  4324. if (count > MAX_VIEWKEYFILE_ROWS)
  4325. throw MakeStringException(ECLWATCH_TOO_MANY_DATA_ROWS,"Browser Cannot display more than %d data rows.", MAX_VIEWKEYFILE_ROWS);
  4326. bool bSchemaOnly=req.getSchemaOnly() ? req.getSchemaOnly() : false;
  4327. bool bDisableUppercaseTranslation = req.getDisableUppercaseTranslation() ? req.getDisableUppercaseTranslation() : false;
  4328. const char* filterBy = req.getFilterBy();
  4329. const char* showColumns = req.getShowColumns();
  4330. __int64 read=0;
  4331. __int64 total = 0;
  4332. StringBuffer msg;
  4333. StringArray columnLabels, columnLabelsType;
  4334. IArrayOf<IEspDFUData> DataList;
  4335. int iRet = GetIndexData(context, bSchemaOnly, logicalNameStr.str(), parentName, filterBy, start, count, read, total, msg, columnLabels, columnLabelsType, DataList, bDisableUppercaseTranslation);
  4336. if (iRet > 0)
  4337. resp.setMsgToDisplay("This search has timed out due to the restrictive filter. There may be more records.");
  4338. //GetIndexData(context, bSchemaOnly, logicalNameStr.str(), "roxie::thor_data400::key::bankruptcyv2::20090721::search::tmsid", filterBy, start, count, read, total, msg, columnLabels, columnLabelsType, DataList);
  4339. resp.setResult(DataList.item(0).getData());
  4340. unsigned int max_name_length = 3; //max length for name length
  4341. unsigned int max_value_length = 4; //max length for value length:
  4342. StringBuffer filterByStr, filterByStr0;
  4343. filterByStr0.appendf("%d%d", max_name_length, max_value_length);
  4344. unsigned columnCount = columnLabels.length();
  4345. IArrayOf<IEspDFUDataColumn> dataColumns;
  4346. double version = context.getClientVersion();
  4347. if (version > 1.04 && columnCount > 0)
  4348. {
  4349. //Find out which columns need to be displayed
  4350. int lenShowCols = 0, showCols[1024];
  4351. const char* showColumns = req.getShowColumns();
  4352. char *pShowColumns = (char*) showColumns;
  4353. while (pShowColumns && *pShowColumns)
  4354. {
  4355. StringBuffer buf;
  4356. while (pShowColumns && isdigit(pShowColumns[0]))
  4357. {
  4358. buf.append(pShowColumns[0]);
  4359. pShowColumns++;
  4360. }
  4361. if (buf.length() > 0)
  4362. {
  4363. showCols[lenShowCols] = atoi(buf.str());
  4364. lenShowCols++;
  4365. }
  4366. if (!pShowColumns || !*pShowColumns)
  4367. break;
  4368. pShowColumns++;
  4369. }
  4370. for(unsigned col = 0; col < columnCount; col++)
  4371. {
  4372. const char* label = columnLabels.item(col);
  4373. const char* type = columnLabelsType.item(col);
  4374. if (!label || !*label || !type || !*type)
  4375. continue;
  4376. Owned<IEspDFUDataColumn> item = createDFUDataColumn("","");
  4377. item->setColumnLabel(label);
  4378. item->setColumnType(type);
  4379. item->setColumnSize(0); //not show this column
  4380. if (!showColumns || !*showColumns)
  4381. {
  4382. item->setColumnSize(1); //Show this column
  4383. }
  4384. else
  4385. {
  4386. for(int col1 = 0; col1 < lenShowCols; col1++)
  4387. {
  4388. if (col == showCols[col1])
  4389. {
  4390. item->setColumnSize(1); //Show this column
  4391. break;
  4392. }
  4393. }
  4394. }
  4395. dataColumns.append(*item.getLink());
  4396. }
  4397. //Re-build filters
  4398. if (filterBy && *filterBy)
  4399. {
  4400. StringArray filterByNames, filterByValues;
  4401. parseTwoStringArrays(filterBy, filterByNames, filterByValues);
  4402. if (filterByNames.length() > 0)
  4403. {
  4404. for (unsigned ii = 0; ii < filterByNames.length(); ii++)
  4405. {
  4406. const char* columnName = filterByNames.item(ii);
  4407. const char* columnValue = filterByValues.item(ii);
  4408. if (columnName && *columnName && columnValue && *columnValue)
  4409. {
  4410. filterByStr.appendf("%s[%s]", columnName, columnValue);
  4411. filterByStr0.appendf("%03d%04d%s%s", (int) strlen(columnName), (int) strlen(columnValue), columnName, columnValue);
  4412. }
  4413. }
  4414. }
  4415. }
  4416. if (req.getStartForGoback())
  4417. resp.setStartForGoback(req.getStartForGoback());
  4418. if (req.getCountForGoback())
  4419. resp.setCountForGoback(req.getCountForGoback());
  4420. }
  4421. //resp.setFilterBy(filterByStr.str());
  4422. if (filterByStr.length() > 0)
  4423. {
  4424. const char* oldStr = "&";
  4425. const char* newStr = "&amp;";
  4426. filterByStr.replaceString(oldStr, newStr);
  4427. resp.setFilterBy(filterByStr.str());
  4428. }
  4429. if (version > 1.04)
  4430. {
  4431. //resp.setFilterForGoBack(filterByStr0.str());
  4432. if (filterByStr0.length() > 0)
  4433. {
  4434. const char* oldStr = "&";
  4435. const char* newStr = "&amp;";
  4436. filterByStr0.replaceString(oldStr, newStr);
  4437. resp.setFilterForGoBack(filterByStr0.str());
  4438. }
  4439. resp.setColumnCount(columnCount);
  4440. if (dataColumns.length() > 0)
  4441. resp.setColumnsHidden(dataColumns);
  4442. }
  4443. if (version > 1.10)
  4444. {
  4445. resp.setSchemaOnly(bSchemaOnly);
  4446. }
  4447. //resp.setName(name.str());
  4448. resp.setLogicalName(logicalNameStr.str());
  4449. resp.setStart(start);
  4450. //if (requested > read)
  4451. // requested = read;
  4452. resp.setPageSize(requested);
  4453. if (count > read)
  4454. {
  4455. count = read;
  4456. }
  4457. resp.setCount(count);
  4458. if (total != UNKNOWN_NUM_ROWS)
  4459. resp.setTotal(total);
  4460. else
  4461. resp.setTotal(-1);
  4462. if (req.getChooseFile())
  4463. resp.setChooseFile(1);
  4464. else
  4465. resp.setChooseFile(0);
  4466. if (version > 1.11)
  4467. {
  4468. if (req.getCluster() && *req.getCluster())
  4469. {
  4470. resp.setCluster(req.getCluster());
  4471. }
  4472. if (req.getClusterType() && *req.getClusterType())
  4473. {
  4474. resp.setClusterType(req.getClusterType());
  4475. }
  4476. }
  4477. if ((version > 1.12) && parentName && *parentName)
  4478. {
  4479. resp.setParentName(parentName);
  4480. }
  4481. }
  4482. catch(IException* e)
  4483. {
  4484. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  4485. }
  4486. return true;
  4487. }
  4488. void storeHistoryTreeToArray(IPropertyTree *history, IArrayOf<IEspHistory>& arrHistory)
  4489. {
  4490. Owned<IPropertyTreeIterator> historyIter = history->getElements("*");
  4491. ForEach(*historyIter)
  4492. {
  4493. Owned<IEspHistory> historyRecord = createHistory();
  4494. IPropertyTree & item = historyIter->query();
  4495. historyRecord->setIP(item.queryProp("@ip"));
  4496. historyRecord->setName(item.queryProp("@name"));
  4497. historyRecord->setOperation(item.queryProp("@operation"));
  4498. historyRecord->setOwner(item.queryProp("@owner"));
  4499. historyRecord->setPath(item.queryProp("@path"));
  4500. historyRecord->setTimestamp(item.queryProp("@timestamp"));
  4501. historyRecord->setWorkunit(item.queryProp("@workunit"));
  4502. arrHistory.append(*historyRecord.getClear());
  4503. }
  4504. }
  4505. bool CWsDfuEx::onListHistory(IEspContext &context, IEspListHistoryRequest &req, IEspListHistoryResponse &resp)
  4506. {
  4507. try
  4508. {
  4509. StringBuffer username;
  4510. context.getUserID(username);
  4511. Owned<IUserDescriptor> userdesc;
  4512. if (username.length() > 0)
  4513. {
  4514. userdesc.setown(createUserDescriptor());
  4515. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  4516. }
  4517. if (!req.getName() || !*req.getName())
  4518. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Name required");
  4519. PROGLOG("onListHistory: %s", req.getName());
  4520. MemoryBuffer xmlmap;
  4521. IArrayOf<IEspHistory> arrHistory;
  4522. Owned<IDistributedFile> file = queryDistributedFileDirectory().lookup(req.getName(),userdesc.get());
  4523. if (file)
  4524. {
  4525. IPropertyTree *history = file->queryHistory();
  4526. if (history)
  4527. {
  4528. storeHistoryTreeToArray(history, arrHistory);
  4529. if (context.getClientVersion() < 1.36)
  4530. history->serialize(xmlmap);
  4531. }
  4532. if (arrHistory.ordinality())
  4533. resp.setHistory(arrHistory);
  4534. }
  4535. else
  4536. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"CWsDfuEx::onListHistory: Could not find file '%s'.", req.getName());
  4537. if (xmlmap.length())
  4538. resp.setXmlmap(xmlmap);
  4539. }
  4540. catch(IException* e)
  4541. {
  4542. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  4543. }
  4544. return true;
  4545. }
  4546. bool CWsDfuEx::onEraseHistory(IEspContext &context, IEspEraseHistoryRequest &req, IEspEraseHistoryResponse &resp)
  4547. {
  4548. try
  4549. {
  4550. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Full, false))
  4551. throw MakeStringException(ECLWATCH_DFU_ACCESS_DENIED, "Failed to Erase History. Permission denied (requires Full).");
  4552. StringBuffer username;
  4553. context.getUserID(username);
  4554. Owned<IUserDescriptor> userdesc;
  4555. if (username.length() > 0)
  4556. {
  4557. userdesc.setown(createUserDescriptor());
  4558. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  4559. }
  4560. if (!req.getName() || !*req.getName())
  4561. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Name required");
  4562. PROGLOG("onEraseHistory: %s", req.getName());
  4563. MemoryBuffer xmlmap;
  4564. IArrayOf<IEspHistory> arrHistory;
  4565. Owned<IDistributedFile> file = queryDistributedFileDirectory().lookup(req.getName(),userdesc.get());
  4566. if (file)
  4567. {
  4568. IPropertyTree *history = file->queryHistory();
  4569. if (history)
  4570. {
  4571. storeHistoryTreeToArray(history, arrHistory);
  4572. if (context.getClientVersion() < 1.36)
  4573. history->serialize(xmlmap);
  4574. file->resetHistory();
  4575. }
  4576. if (arrHistory.ordinality())
  4577. resp.setHistory(arrHistory);
  4578. }
  4579. else
  4580. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"CWsDfuEx::onEraseHistory: Could not find file '%s'.", req.getName());
  4581. if (xmlmap.length())
  4582. resp.setXmlmap(xmlmap);
  4583. }
  4584. catch(IException* e)
  4585. {
  4586. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  4587. }
  4588. return true;
  4589. }
  4590. //////////////////////HPCC Browser//////////////////////////
  4591. static const char* SCHEMANAME = "myschema";
  4592. //void CWsDfuEx::setRootFilter(INewResultSet* result, const char* filterBy, IFilteredResultSet* filter)
  4593. void CWsDfuEx::setRootFilter(INewResultSet* result, const char* filterBy, IResultSetFilter* filter, bool disableUppercaseTranslation)
  4594. {
  4595. if (!filterBy || !*filterBy || !result)
  4596. return;
  4597. //Owned<IFilteredResultSet> filter = result->createFiltered();
  4598. filter->clearFilters();
  4599. const IResultSetMetaData &meta = result->getMetaData();
  4600. unsigned columnCount = meta.getColumnCount();
  4601. if (columnCount < 1)
  4602. return;
  4603. StringArray filterByNames, filterByValues;
  4604. parseTwoStringArrays(filterBy, filterByNames, filterByValues);
  4605. if (filterByNames.length() < 1)
  4606. return;
  4607. for (unsigned ii = 0; ii < filterByNames.length(); ii++)
  4608. {
  4609. const char* columnName = filterByNames.item(ii);
  4610. const char* columnValue0 = filterByValues.item(ii);
  4611. if (!columnName || !*columnName || !columnValue0 || !*columnValue0)
  4612. continue;
  4613. StringBuffer buf(columnValue0);
  4614. if (!disableUppercaseTranslation)
  4615. buf.toUpperCase();
  4616. const char* columnValue = buf.str();
  4617. for(unsigned col = 0; col < columnCount; col++)
  4618. {
  4619. bool hasSetTranslation = false;
  4620. SCMStringBuffer scmbuf;
  4621. if (meta.hasSetTranslation(col))
  4622. {
  4623. hasSetTranslation = true;
  4624. meta.getNaturalColumnLabel(scmbuf, col);
  4625. }
  4626. if (scmbuf.length() < 1)
  4627. {
  4628. meta.getColumnLabel(scmbuf, col);
  4629. }
  4630. if (!stricmp(scmbuf.str(), columnName))
  4631. {
  4632. //filter->addFilter(col, columnValue);
  4633. //filterByStr.appendf("%s[%s]", columnName, columnValue);
  4634. //filterByStr0.appendf("%03d%04d%s%s", strlen(columnName), strlen(columnValue), columnName, columnValue);
  4635. if (hasSetTranslation)
  4636. filter->addNaturalFilter(col, strlen(columnValue), columnValue);
  4637. else
  4638. filter->addFilter(col, strlen(columnValue), columnValue);
  4639. break;
  4640. }
  4641. }
  4642. }
  4643. //result.setown(filter->create());
  4644. return;
  4645. }
  4646. void CWsDfuEx::getMappingColumns(IRelatedBrowseFile * file, bool isPrimary, UnsignedArray& cols)
  4647. {
  4648. const char* logicalName = file->queryDefinition()->queryDistributedFile()->queryLogicalName();
  4649. const char* primaryName = file->queryParentRelation()->queryFileRelationship()->queryPrimaryFilename();
  4650. if (!logicalName || !primaryName || strcmp(logicalName, primaryName))
  4651. return;
  4652. IViewRelation* parentRelation = file->queryParentRelation();
  4653. for (unsigned i=0; i < parentRelation->numMappingFields(); i++)
  4654. {
  4655. //find out the column numbers to remove
  4656. unsigned col = parentRelation->queryMappingField(i, isPrimary);
  4657. cols.append(col);
  4658. }
  4659. #ifdef TESTDATASET
  4660. cols.kill();
  4661. cols.append(2);
  4662. cols.append(3);
  4663. #endif
  4664. return;
  4665. }
  4666. void CWsDfuEx::readColumnsForDisplay(StringBuffer& schemaText, StringArray& columnsDisplay, StringArray& columnsDisplayType)
  4667. {
  4668. if (schemaText.length() < 1)
  4669. return;
  4670. Owned<IPropertyTree> schema = createPTreeFromXMLString(schemaText.str());
  4671. if (!schema)
  4672. return;
  4673. //Find out labels from the second schema used for column mapping
  4674. columnsDisplay.kill();
  4675. Owned<IPropertyTreeIterator> rows4 = schema->getElements("xs:element[@name=\"Dataset\"]/xs:complexType/xs:sequence/xs:element[@name=\"Row\"]/xs:complexType/xs:sequence/*");
  4676. ForEach(*rows4)
  4677. {
  4678. IPropertyTree &e = rows4->query();
  4679. const char* name = e.queryProp("@name");
  4680. const char* type = e.queryProp("@type");
  4681. bool hasChildren = e.hasChildren();
  4682. if (!name || !*name)
  4683. continue;
  4684. columnsDisplay.append(name); //Display this column
  4685. if (type && *type)
  4686. columnsDisplayType.append(type);
  4687. else if (hasChildren)
  4688. columnsDisplayType.append("Object");
  4689. else
  4690. columnsDisplayType.append("Unknown");
  4691. }
  4692. return;
  4693. }
  4694. void CWsDfuEx::mergeSchema(IRelatedBrowseFile * file, StringBuffer& schemaText, StringBuffer schemaText2,
  4695. StringArray& columnsDisplay, StringArray& columnsDisplayType, StringArray& columnsHide)
  4696. {
  4697. if (schemaText.length() < 1)
  4698. return;
  4699. if (schemaText2.length() < 1)
  4700. return;
  4701. Owned<IPropertyTree> schema = createPTreeFromXMLString(schemaText.str());
  4702. Owned<IPropertyTree> schema2 = createPTreeFromXMLString(schemaText2.str());
  4703. if (!schema || !schema2)
  4704. return;
  4705. //Process simpleType part
  4706. Owned<IPropertyTreeIterator> rows1 = schema->getElements("xs:simpleType");
  4707. Owned<IPropertyTreeIterator> rows2 = schema2->getElements("xs:simpleType");
  4708. if (!rows1 || !rows2)
  4709. return;
  4710. ForEach(*rows2)
  4711. {
  4712. IPropertyTree &e = rows2->query();
  4713. const char* name = e.queryProp("@name");
  4714. if (!name || !*name)
  4715. continue;
  4716. bool bFound = false;
  4717. ForEach(*rows1)
  4718. {
  4719. IPropertyTree &e1 = rows1->query();
  4720. const char* name1 = e1.queryProp("@name");
  4721. if (!name1 || !*name1 || stricmp(name1, name))
  4722. continue;
  4723. bFound = true;
  4724. break;
  4725. }
  4726. if (!bFound)
  4727. schema->addPropTree(e.queryName(), LINK(&e));
  4728. }
  4729. IPropertyTree* rows = schema->queryBranch("xs:element[@name=\"Dataset\"]/xs:complexType/xs:sequence/xs:element[@name=\"Row\"]/xs:complexType/xs:sequence");
  4730. if (!rows)
  4731. return;
  4732. //Find out labels used for column mapping
  4733. columnsDisplay.kill();
  4734. columnsDisplayType.kill();
  4735. columnsHide.kill();
  4736. Owned<IPropertyTreeIterator> rows4 = schema->getElements("xs:element[@name=\"Dataset\"]/xs:complexType/xs:sequence/xs:element[@name=\"Row\"]/xs:complexType/xs:sequence/*");
  4737. ForEach(*rows4)
  4738. {
  4739. IPropertyTree &e = rows4->query();
  4740. const char* name = e.queryProp("@name");
  4741. const char* type = e.queryProp("@type");
  4742. bool hasChildren = e.hasChildren();
  4743. if (!name || !*name)
  4744. continue;
  4745. columnsDisplay.append(name); //Display this column
  4746. if (type && *type)
  4747. columnsDisplayType.append(type);
  4748. else if (hasChildren)
  4749. columnsDisplayType.append("Object");
  4750. else
  4751. columnsDisplayType.append("Unknown");
  4752. }
  4753. UnsignedArray cols;
  4754. bool isPrimary = true;
  4755. getMappingColumns(file, isPrimary, cols);
  4756. //Process complexType part for labels
  4757. unsigned col0 = 0;
  4758. Owned<IPropertyTreeIterator> rows3 = schema2->getElements("xs:element[@name=\"Dataset\"]/xs:complexType/xs:sequence/xs:element[@name=\"Row\"]/xs:complexType/xs:sequence/*");
  4759. ForEach(*rows3)
  4760. {
  4761. IPropertyTree &e = rows3->query();
  4762. const char* name = e.queryProp("@name");
  4763. const char* type = e.queryProp("@type");
  4764. bool hasChildren = e.hasChildren();
  4765. if (!name || !*name)
  4766. continue;
  4767. bool bAdd = true;
  4768. bool bRename = false;
  4769. if (cols.ordinality() != 0)
  4770. {
  4771. ForEachItemIn(i1,cols)
  4772. {
  4773. unsigned col = cols.item(i1);
  4774. if (col == col0)
  4775. {
  4776. bAdd = false;
  4777. break;
  4778. }
  4779. }
  4780. }
  4781. #define RENAMESAMECOLUMN
  4782. #ifdef RENAMESAMECOLUMN
  4783. if (columnsDisplay.length() > 0)
  4784. {
  4785. for (unsigned i = 0; i < columnsDisplay.length(); i++)
  4786. {
  4787. const char* label = columnsDisplay.item(i);
  4788. if (!label || strcmp(label, name))
  4789. continue;
  4790. bRename = true;
  4791. break;
  4792. }
  4793. }
  4794. #endif
  4795. if (!bAdd)
  4796. {
  4797. columnsHide.append(name); //hide this column
  4798. }
  4799. else
  4800. {
  4801. if (type && *type)
  4802. columnsDisplayType.append(type);
  4803. else if (hasChildren)
  4804. columnsDisplayType.append("Object");
  4805. else
  4806. columnsDisplayType.append("Unknown");
  4807. #ifdef RENAMESAMECOLUMN
  4808. if (bRename)
  4809. {
  4810. StringBuffer newName(name);
  4811. newName.append("-2");
  4812. columnsDisplay.append(newName.str()); //Display this column
  4813. e.setProp("@name", newName.str());
  4814. rows->addPropTree(e.queryName(), LINK(&e));
  4815. }
  4816. else
  4817. {
  4818. #endif
  4819. columnsDisplay.append(name); //Display this column
  4820. rows->addPropTree(e.queryName(), LINK(&e));
  4821. #ifdef RENAMESAMECOLUMN
  4822. }
  4823. #endif
  4824. }
  4825. col0++;
  4826. }
  4827. //Convert schema tree to schame now
  4828. schemaText.clear();
  4829. toXML(schema, schemaText);
  4830. return;
  4831. }
  4832. void CWsDfuEx::mergeDataRow(StringBuffer& newRow, int depth, IPropertyTreeIterator* it, StringArray& columnsHide, StringArray& columnsUsed)
  4833. {
  4834. if (!it)
  4835. return;
  4836. it->first();
  4837. while(it->isValid())
  4838. {
  4839. IPropertyTree* e = &it->query();
  4840. if (e)
  4841. {
  4842. const char* label = e->queryName();
  4843. if (label && *label)
  4844. {
  4845. #ifdef RENAMESAMECOLUMN
  4846. if (depth < 1)
  4847. columnsUsed.append(label);
  4848. #endif
  4849. bool bHide = false;
  4850. if (columnsHide.length() > 0)
  4851. {
  4852. for (unsigned i = 0 ; i < columnsHide.length(); i++)
  4853. {
  4854. const char* key = columnsHide.item(i);
  4855. if (!key || strcmp(key, label))
  4856. continue;
  4857. bHide = true;
  4858. break;
  4859. }
  4860. }
  4861. #ifdef RENAMESAMECOLUMN
  4862. if (!bHide && depth > 0 && columnsUsed.length() > 0)
  4863. {
  4864. for (unsigned i = 0 ; i < columnsUsed.length(); i++)
  4865. {
  4866. const char* key = columnsUsed.item(i);
  4867. if (!key || strcmp(key, label))
  4868. continue;
  4869. StringBuffer newName(label);
  4870. newName.append("-2");
  4871. e->renameProp("/", newName.str());
  4872. break;
  4873. }
  4874. }
  4875. #endif
  4876. if (!bHide)
  4877. {
  4878. StringBuffer dataRow;
  4879. toXML(e, dataRow);
  4880. newRow.append(dataRow);
  4881. }
  4882. }
  4883. }
  4884. it->next();
  4885. }
  4886. return;
  4887. }
  4888. void CWsDfuEx::mergeDataRow(StringBuffer& newRow, StringBuffer dataRow1, StringBuffer dataRow2, StringArray& columnsHide)
  4889. {
  4890. if (dataRow1.length() < 1)
  4891. return;
  4892. if (dataRow2.length() < 1)
  4893. return;
  4894. Owned<IPropertyTree> data1 = createPTreeFromXMLString(dataRow1.str());
  4895. Owned<IPropertyTree> data2 = createPTreeFromXMLString(dataRow2.str());
  4896. if (!data1 || !data2)
  4897. return;
  4898. newRow.clear();
  4899. newRow.append("<Row>");
  4900. StringArray columnLabels;
  4901. Owned<IPropertyTreeIterator> it = data1->getElements("*");
  4902. if (it)
  4903. {
  4904. StringArray columnLabels0;
  4905. mergeDataRow(newRow, 0, it, columnLabels0, columnLabels);
  4906. }
  4907. Owned<IPropertyTreeIterator> it2 = data2->getElements("*");
  4908. if (it2)
  4909. {
  4910. mergeDataRow(newRow, 1, it2, columnsHide, columnLabels);
  4911. }
  4912. newRow.append("</Row>");
  4913. return;
  4914. }
  4915. void CWsDfuEx::browseRelatedFileSchema(IRelatedBrowseFile * file, const char* parentName, unsigned depth, StringBuffer& schemaText,
  4916. StringArray& columnsDisplay, StringArray& columnsDisplayType, StringArray& columnsHide)
  4917. {
  4918. //if (file in set of files to display or iterate)
  4919. IResultSetCursor * cursor = file->queryCursor();
  4920. if (cursor && cursor->first())
  4921. {
  4922. if (depth < 1)
  4923. {
  4924. const IResultSetMetaData & meta = cursor->queryResultSet()->getMetaData();
  4925. StringBufferAdaptor adaptor(schemaText);
  4926. meta.getXmlSchema(adaptor, false);
  4927. #ifdef TESTDATASET
  4928. schemaText.clear();
  4929. schemaText.append("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\"");
  4930. schemaText.append(" attributeFormDefault=\"unqualified\">");
  4931. schemaText.append("<xs:element name=\"Dataset\"><xs:complexType><xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">");
  4932. schemaText.append("<xs:element name=\"Row\"><xs:complexType><xs:sequence>");
  4933. schemaText.append("<xs:element name=\"state\" type=\"string2\"/>");
  4934. schemaText.append("<xs:element name=\"rtype\" type=\"string2\"/>");
  4935. schemaText.append("<xs:element name=\"id\" type=\"string20\"/>");
  4936. schemaText.append("<xs:element name=\"seq\" type=\"xs:nonNegativeInteger\"/>");
  4937. schemaText.append("<xs:element name=\"num\" type=\"xs:nonNegativeInteger\"/>");
  4938. schemaText.append("<xs:element name=\"date\" type=\"string8\"/>");
  4939. schemaText.append("<xs:element name=\"imglength\" type=\"xs:nonNegativeInteger\"/>");
  4940. schemaText.append("<xs:element name=\"__filepos\" type=\"xs:nonNegativeInteger\"/>");
  4941. schemaText.append("</xs:sequence></xs:complexType></xs:element>");
  4942. schemaText.append("</xs:sequence></xs:complexType></xs:element>");
  4943. schemaText.append("<xs:simpleType name=\"string2\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"2\"/>");
  4944. schemaText.append("</xs:restriction></xs:simpleType>");
  4945. schemaText.append("<xs:simpleType name=\"string20\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"20\"/>");
  4946. schemaText.append("</xs:restriction></xs:simpleType>");
  4947. schemaText.append("<xs:simpleType name=\"string8\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"8\"/>");
  4948. schemaText.append("</xs:restriction></xs:simpleType>");
  4949. schemaText.append("</xs:schema>");
  4950. #endif
  4951. readColumnsForDisplay(schemaText, columnsDisplay, columnsDisplayType);
  4952. }
  4953. else
  4954. {
  4955. StringBuffer schemaText0;
  4956. const IResultSetMetaData & meta = cursor->queryResultSet()->getMetaData();
  4957. StringBufferAdaptor adaptor(schemaText0);
  4958. meta.getXmlSchema(adaptor, false);
  4959. #ifdef TESTDATASET
  4960. schemaText0.clear();
  4961. schemaText0.append("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\"");
  4962. schemaText0.append(" attributeFormDefault=\"unqualified\">");
  4963. schemaText0.append("<xs:element name=\"Dataset\"><xs:complexType><xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">");
  4964. schemaText0.append("<xs:element name=\"Row\"><xs:complexType><xs:sequence>");
  4965. schemaText0.append("<xs:element name=\"date_first_reported\" type=\"string12\"/>");
  4966. schemaText0.append("<xs:element name=\"msa\" type=\"string8\"/>");
  4967. schemaText0.append("<xs:element name=\"sid\" type=\"string20\"/>");
  4968. schemaText0.append("<xs:element name=\"seq\" type=\"xs:nonNegativeInteger\"/>"); //not add
  4969. schemaText0.append("</xs:sequence></xs:complexType></xs:element>");
  4970. schemaText0.append("</xs:sequence></xs:complexType></xs:element>");
  4971. schemaText0.append("<xs:simpleType name=\"string12\"><xs:restriction base=\"xs:string\"><xs:maxLength value=\"12\"/>");
  4972. schemaText0.append("</xs:restriction></xs:simpleType>");
  4973. schemaText0.append("</xs:schema>");
  4974. #endif
  4975. mergeSchema(file, schemaText, schemaText0, columnsDisplay, columnsDisplayType, columnsHide);
  4976. }
  4977. if (parentName && *parentName)
  4978. {
  4979. for (unsigned i = 0;;i++)
  4980. {
  4981. IRelatedBrowseFile * next = file->queryChild(i);
  4982. if (!next)
  4983. break;
  4984. IViewRelatedFile * viewRelatedFile = next->queryDefinition();
  4985. if (!viewRelatedFile)
  4986. continue;
  4987. IDistributedFile * file = viewRelatedFile->queryDistributedFile();
  4988. if (!file)
  4989. continue;
  4990. const char* logicName0 = file->queryLogicalName();
  4991. if (logicName0 && !strcmp(logicName0, parentName))
  4992. browseRelatedFileSchema(next, NULL, depth+1, schemaText, columnsDisplay, columnsDisplayType, columnsHide);
  4993. }
  4994. }
  4995. }
  4996. return;
  4997. }
  4998. int CWsDfuEx::browseRelatedFileDataSet(double version, IRelatedBrowseFile * file, const char* parentName, unsigned depth, __int64 start, __int64& count, __int64& read,
  4999. StringArray& columnsHide, StringArray& dataSetOutput)
  5000. {
  5001. int iRet = 0;
  5002. int rows = 0;
  5003. try
  5004. {
  5005. //if (file in set of files to display or iterate)
  5006. IResultSetCursor * cursor = file->queryCursor();
  5007. if (cursor->first())
  5008. {
  5009. for(bool ok=cursor->absolute(start);ok;ok=cursor->next())
  5010. {
  5011. StringBuffer text;
  5012. StringBufferAdaptor adaptor2(text);
  5013. cursor->getXmlRow(adaptor2);
  5014. StringArray dataSetOutput0;
  5015. if (parentName && *parentName)
  5016. {
  5017. for (unsigned i = 0;;i++)
  5018. {
  5019. IRelatedBrowseFile * next = file->queryChild(i);
  5020. if (!next)
  5021. break;
  5022. IViewRelatedFile * viewRelatedFile = next->queryDefinition();
  5023. if (!viewRelatedFile)
  5024. continue;
  5025. IDistributedFile * file = viewRelatedFile->queryDistributedFile();
  5026. if (!file)
  5027. continue;
  5028. const char* logicName0 = file->queryLogicalName();
  5029. if (logicName0 && !strcmp(logicName0, parentName))
  5030. iRet = browseRelatedFileDataSet(version, next, NULL, depth+1, 0, count, read, columnsHide, dataSetOutput0);
  5031. }
  5032. }
  5033. if (dataSetOutput0.length() < 1)
  5034. {
  5035. dataSetOutput.append(text);
  5036. }
  5037. else
  5038. {
  5039. for (unsigned ii = 0; ii<dataSetOutput0.length(); ii++)
  5040. {
  5041. StringBuffer text0;
  5042. StringBuffer text1 = dataSetOutput0.item(ii);
  5043. if (text1.length() > 0)
  5044. {
  5045. mergeDataRow(text0, text, text1, columnsHide);
  5046. }
  5047. dataSetOutput.append(text0);
  5048. }
  5049. }
  5050. if (depth < 1)
  5051. {
  5052. read++;
  5053. if(read>=count)
  5054. break;
  5055. }
  5056. }
  5057. if (depth < 1)
  5058. {
  5059. if (count > read)
  5060. count = read;
  5061. }
  5062. }
  5063. }
  5064. catch(IException* e)
  5065. {
  5066. if ((version < 1.08) || (e->errorCode() != FVERR_FilterTooRestrictive))
  5067. throw e;
  5068. e->Release();
  5069. iRet = 1;
  5070. }
  5071. return iRet;
  5072. }
  5073. //sample filterBy: 340020001id1
  5074. //sample data: <XmlSchema name="myschema">...</XmlSchema><Dataset xmlSchema="myschema">...</Dataset>
  5075. int CWsDfuEx::GetIndexData(IEspContext &context, bool bSchemaOnly, const char* indexName, const char* parentName, const char* filterBy, __int64 start,
  5076. __int64& count, __int64& read, __int64& total, StringBuffer& message, StringArray& columnLabels,
  5077. StringArray& columnLabelsType, IArrayOf<IEspDFUData>& DataList, bool webDisableUppercaseTranslation)
  5078. {
  5079. if (!indexName || !*indexName)
  5080. return -1;
  5081. double version = context.getClientVersion();
  5082. StringBuffer username;
  5083. context.getUserID(username);
  5084. StringBuffer cluster;
  5085. Owned<IUserDescriptor> userdesc;
  5086. bool disableUppercaseTranslation = false;
  5087. Owned<IDistributedFile> df;
  5088. try
  5089. {
  5090. userdesc.setown(createUserDescriptor());
  5091. userdesc->set(username.str(), context.queryPassword(), context.querySignature());
  5092. df.setown(queryDistributedFileDirectory().lookup(indexName, userdesc));
  5093. if(!df)
  5094. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST,"Could not find file %s.", indexName);
  5095. //Check disableUppercaseTranslation
  5096. StringBuffer mapping;
  5097. df->getColumnMapping(mapping);
  5098. if (mapping.length() > 37 && strstr(mapping.str(), "word{set(stringlib.StringToLowerCase)}"))
  5099. disableUppercaseTranslation = true;
  5100. else if (webDisableUppercaseTranslation)
  5101. disableUppercaseTranslation = webDisableUppercaseTranslation;
  5102. else
  5103. disableUppercaseTranslation = m_disableUppercaseTranslation;
  5104. const char* wuid = df->queryAttributes().queryProp("@workunit");
  5105. if (wuid && *wuid)
  5106. {
  5107. CWUWrapper wu(wuid, context);
  5108. if (wu)
  5109. cluster.append(wu->queryClusterName());
  5110. }
  5111. }
  5112. catch (IException *e)
  5113. {
  5114. DBGLOG(e);
  5115. e->Release();
  5116. }
  5117. catch(...)
  5118. {
  5119. DBGLOG("Unknown Exception - view data file: %s", indexName);
  5120. }
  5121. Owned<IResultSetFactory> resultSetFactory = getSecResultSetFactory(context.querySecManager(), context.queryUser(), context.queryUserId(), context.queryPassword());
  5122. Owned<IViewFileWeb> web;
  5123. Owned<IUserDescriptor> udesc;
  5124. ISecUser * secUser = context.queryUser();
  5125. if(secUser && secUser->getName() && *secUser->getName())
  5126. {
  5127. udesc.setown(createUserDescriptor());
  5128. udesc->set(secUser->getName(), secUser->credentials().getPassword(), context.querySignature());
  5129. }
  5130. if (cluster.length())
  5131. {
  5132. web.setown(createViewFileWeb(*resultSetFactory, cluster, udesc.getLink()));
  5133. }
  5134. else if (m_clusterName.length() > 0)
  5135. {
  5136. web.setown(createViewFileWeb(*resultSetFactory, m_clusterName.str(), udesc.getLink()));
  5137. }
  5138. else
  5139. {
  5140. web.setown(createViewFileWeb(*resultSetFactory, NULL, udesc.getLink()));
  5141. }
  5142. ViewGatherOptions options;
  5143. options.primaryDepth = 100; // we want to traverse secondary->primary, but not the reverse
  5144. options.secondaryDepth = 0;
  5145. options.setPayloadFilter(true); // we're only interested in payload links
  5146. char *indexName0 = (char *) indexName;
  5147. Owned<IFileTreeBrowser> browser;
  5148. try
  5149. {
  5150. web->gatherWeb(indexName0, df, options);
  5151. browser.setown(web->createBrowseTree(indexName0));
  5152. }
  5153. catch(IException* e)
  5154. {
  5155. if ((e->errorCode() != FVERR_CouldNotResolveX) || (indexName[0] != '~'))
  5156. {
  5157. throw e;
  5158. }
  5159. else
  5160. {
  5161. e->Release();
  5162. indexName0 = (char *) (indexName+1);
  5163. web->gatherWeb(indexName0, df, options);
  5164. browser.setown(web->createBrowseTree(indexName0));
  5165. }
  5166. }
  5167. Owned<INewResultSet> result;
  5168. if (cluster && *cluster)
  5169. {
  5170. result.setown(resultSetFactory->createNewFileResultSet(indexName0, cluster));
  5171. }
  5172. else if (m_clusterName.length() > 0)
  5173. {
  5174. result.setown(resultSetFactory->createNewFileResultSet(indexName0, m_clusterName.str()));
  5175. }
  5176. else
  5177. {
  5178. result.setown(resultSetFactory->createNewFileResultSet(indexName0, NULL));
  5179. }
  5180. // Apply the filter to the root node
  5181. if (filterBy && *filterBy)
  5182. {
  5183. //Owned<IFilteredResultSet> filter = result->createFiltered();
  5184. IResultSetFilter* filter = browser->queryRootFilter();
  5185. setRootFilter(result, filterBy, filter, disableUppercaseTranslation);
  5186. ///result.setown(filter->create());
  5187. }
  5188. StringBuffer text, schemaText;
  5189. StringArray columnsHide;
  5190. browseRelatedFileSchema(browser->queryRootFile(), parentName, 0, schemaText, columnLabels, columnLabelsType, columnsHide);
  5191. text.appendf("<XmlSchema name=\"%s\">", SCHEMANAME);
  5192. text.append(schemaText);
  5193. text.append("</XmlSchema>").newline();
  5194. int iRet = 0;
  5195. if (!bSchemaOnly)
  5196. {
  5197. StringArray dataSetOutput;
  5198. iRet = browseRelatedFileDataSet(version, browser->queryRootFile(), parentName, 0, start, count, read, columnsHide, dataSetOutput);
  5199. StringBuffer dataSetText;
  5200. dataSetText.appendf("<Dataset xmlSchema=\"%s\" >", SCHEMANAME);
  5201. dataSetText.newline();
  5202. for (unsigned i = 0; i<dataSetOutput.length(); i++)
  5203. {
  5204. StringBuffer text0 = dataSetOutput.item(i);
  5205. if (text0.length() > 0)
  5206. {
  5207. dataSetText.append(text0);
  5208. dataSetText.newline();
  5209. }
  5210. }
  5211. dataSetText.append("</Dataset>");
  5212. text.append(dataSetText.str());
  5213. }
  5214. MemoryBuffer data;
  5215. struct MemoryBuffer2IStringVal : public CInterface, implements IStringVal
  5216. {
  5217. MemoryBuffer2IStringVal(MemoryBuffer & _buffer) : buffer(_buffer) {}
  5218. IMPLEMENT_IINTERFACE;
  5219. virtual const char * str() const { UNIMPLEMENTED; }
  5220. virtual void set(const char *val) { buffer.append(strlen(val),val); }
  5221. virtual void clear() { } // clearing when appending does nothing
  5222. virtual void setLen(const char *val, unsigned length) { buffer.append(length, val); }
  5223. virtual unsigned length() const { return buffer.length(); };
  5224. MemoryBuffer & buffer;
  5225. } adaptor0(data);
  5226. adaptor0.set(text.str());
  5227. data.append(0);
  5228. total=result->getNumRows();
  5229. Owned<IEspDFUData> item = createDFUData("","");
  5230. item->setName(indexName);
  5231. item->setNumRows(total);
  5232. item->setData(data.toByteArray());
  5233. DataList.append(*item.getClear());
  5234. return iRet;
  5235. }
  5236. //////////////////////HPCC Browser//////////////////////////