WsDeployService.cpp 253 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502
  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 "WsDeployService.hpp"
  15. #include "WsDeployEngine.hpp"
  16. #include "jwrapper.hpp"
  17. #include "daclient.hpp"
  18. #include "dadfs.hpp"
  19. #include "jencrypt.hpp"
  20. #ifdef _WINDOWS
  21. #include <winsock2.h>
  22. #define strlwr _strlwr
  23. #endif
  24. #define STANDARD_CONFIG_BACKUPDIR CONFIG_DIR"/backup"
  25. #define STANDARD_CONFIG_SOURCEDIR CONFIG_DIR
  26. #define STANDARD_CONFIG_BUILDSETFILE "buildset.xml"
  27. #define STANDARD_CONFIG_CONFIGXML_DIR "/componentfiles/configxml/"
  28. #define STANDARD_CONFIG_STAGED_PATH "/etc/HPCCSystems/environment.xml"
  29. #define DEFAULT_DIRECTORIES "<Directories name=\""DIR_NAME"\">\
  30. <Category dir=\""EXEC_PREFIX"/log/[NAME]/[INST]\" name=\"log\"/>\
  31. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/[INST]\" name=\"run\"/>\
  32. <Category dir=\""CONFIG_PREFIX"/[NAME]/[INST]\" name=\"conf\"/>\
  33. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/[INST]/temp\" name=\"temp\"/> \
  34. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/hpcc-data/[COMPONENT]\" name=\"data\"/> \
  35. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/hpcc-data2/[COMPONENT]\" name=\"data2\"/> \
  36. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/hpcc-data3/[COMPONENT]\" name=\"data3\"/> \
  37. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/hpcc-mirror/[COMPONENT]\" name=\"mirror\"/> \
  38. <Category dir=\""EXEC_PREFIX"/lib/[NAME]/queries/[INST]\" name=\"query\"/> \
  39. <Category dir=\""EXEC_PREFIX"/lock/[NAME]/[INST]\" name=\"lock\"/> \
  40. </Directories>"
  41. #include <vector>
  42. using namespace std;
  43. typedef vector<IPropertyTree*> IPropertyTreePtrArray;
  44. bool CCloudTaskThread::s_abort = false;
  45. bool supportedInEEOnly()
  46. {
  47. throw MakeStringException(-1, "This operation is supported in Enterprise and above editions only. Please contact HPCC Systems at http://www.hpccsystems.com/contactus");
  48. }
  49. void substituteParameters(const IPropertyTree* pEnv, const char *xpath, IPropertyTree* pNode, StringBuffer& result)
  50. {
  51. const char* xpathorig = xpath;
  52. while (*xpath)
  53. {
  54. if (*xpath=='$')
  55. {
  56. if (strncmp(xpath, "$build", 6)==0)
  57. {
  58. result.append('\"');
  59. result.append(pNode->queryProp(XML_ATTR_BUILD));
  60. result.append('\"');
  61. xpath+=6;
  62. }
  63. else if (strncmp(xpath, "$model", 6)==0)
  64. {
  65. result.append("Model");
  66. const char *datamodel = pNode->queryProp("@dataModel");
  67. if (datamodel)
  68. {
  69. result.append("[@name=\"");
  70. result.append(datamodel);
  71. result.append("\"]");
  72. }
  73. xpath+=6;
  74. }
  75. else if (strncmp(xpath, "$parentmodel", 12)==0)
  76. {
  77. // Find the model that I am in - HACK
  78. result.append( "Model");
  79. const char *datamodel = NULL;
  80. const IPropertyTree *root = pEnv;
  81. IPropertyTree *current = pNode;
  82. Owned<IPropertyTreeIterator> allModels = root->getElements("Data/Model");
  83. ForEach(*allModels)
  84. {
  85. IPropertyTree &model = allModels->query();
  86. Owned<IPropertyTreeIterator> children = model.getElements("*");
  87. ForEach(*children)
  88. {
  89. if (&children->query()==current)
  90. {
  91. datamodel = model.queryProp("@name");
  92. break;
  93. }
  94. }
  95. if (datamodel)
  96. break;
  97. }
  98. if (datamodel)
  99. {
  100. result.append("[@name=\"");
  101. result.append(datamodel);
  102. result.append("\"]");
  103. }
  104. xpath+=12;
  105. }
  106. else if (strncmp(xpath, "$./*", 4) == 0)
  107. {
  108. String xpath2(xpath+4);
  109. StringBuffer sb(xpath2);
  110. String xpath3(xpathorig);
  111. String* pstr = xpath3.substring(xpath3.lastIndexOf('[', xpath3.indexOf("$./*")) + 1, xpath3.indexOf("$./*"));
  112. int pos1 = xpath2.indexOf(']');
  113. int pos2 = xpath2.lastIndexOf('/');
  114. if (pos1 != -1 && pos2 != -1)
  115. sb.clear().append(xpath2.substring(0, pos2)->toCharArray());
  116. else if (pos1 != -1)
  117. sb.clear().append(xpath2.substring(0, pos1)->toCharArray());
  118. Owned<IPropertyTreeIterator> elems = pNode->getElements(sb.str());
  119. if (pos2 != -1)
  120. sb.clear().append(xpath2.substring(pos2+ 1, pos1)->toCharArray());
  121. ForEach(*elems)
  122. {
  123. IPropertyTree* elem = &elems->query();
  124. result.append('\"');
  125. result.append(elem->queryProp(sb.str()));
  126. result.append("\"").append("][").append(pstr->toCharArray());
  127. }
  128. result.setLength(result.length() - pstr->length() - 2);
  129. delete pstr;
  130. xpath+=pos1+4;
  131. }
  132. else if (strncmp(xpath, "$./", 3) == 0)
  133. {
  134. String xpath2(xpath+3);
  135. StringBuffer sb(xpath2);
  136. int pos = xpath2.indexOf(']');
  137. if (pos != -1)
  138. sb.clear().append(xpath2.substring(0, pos)->toCharArray());
  139. result.append('\"');
  140. result.append(pNode->queryProp(sb.str()));
  141. result.append('\"');
  142. xpath+=pos+3; //skip past $./ and xpath2
  143. }
  144. else
  145. result.append(*xpath++);
  146. }
  147. else
  148. result.append(*xpath++);
  149. }
  150. }
  151. void expandRange(IPropertyTree* pComputers)
  152. {
  153. if (pComputers && pComputers->hasProp("@hasrange"))
  154. {
  155. if(!strcmp(pComputers->queryProp("@hasrange"), "true"))
  156. {
  157. Owned<IPropertyTreeIterator> rangeIter = pComputers->getElements("ComputerRange");
  158. ForEach(*rangeIter)
  159. {
  160. StringArray ipList;
  161. IPropertyTree* pEachComp = &rangeIter->query();
  162. formIPList(pEachComp->queryProp(XML_ATTR_NETADDRESS), ipList);
  163. for(unsigned i = 0 ; i < ipList.ordinality(); i++)
  164. {
  165. IPropertyTree* pElem = pComputers->addPropTree(XML_TAG_COMPUTER,createPTree());
  166. pElem->addProp(XML_ATTR_NETADDRESS,ipList.item(i));
  167. }
  168. pComputers->removeTree(pEachComp);
  169. }
  170. pComputers->removeProp("@hasrange");
  171. }
  172. }
  173. }
  174. CConfigHelper::CConfigHelper()
  175. {
  176. }
  177. CConfigHelper::~CConfigHelper()
  178. {
  179. }
  180. void CConfigHelper::init(const IPropertyTree *cfg, const char* esp_name)
  181. {
  182. StringBuffer xpath;
  183. xpath.clear().appendf("%s/%s/%s[%s='%s']/%s",XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS, XML_TAG_ESPSERVICE, XML_ATTR_NAME, esp_name, XML_TAG_LOCALCONFFILE);
  184. m_strConfFile = cfg->queryProp(xpath.str());
  185. xpath.clear().appendf("%s/%s/%s[%s='%s']/%s",XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS, XML_TAG_ESPSERVICE, XML_ATTR_NAME, esp_name, XML_TAG_LOCALENVCONFFILE);
  186. m_strEnvConfFile = cfg->queryProp(xpath.str());
  187. if (m_strConfFile.length() > 0 && m_strEnvConfFile.length() > 0)
  188. {
  189. Owned<IProperties> pParams = createProperties(m_strConfFile);
  190. Owned<IProperties> pEnvParams = createProperties(m_strEnvConfFile);
  191. m_strConfigXMLDir = pEnvParams->queryProp(TAG_PATH);
  192. if ( m_strConfigXMLDir.length() == 0)
  193. {
  194. m_strConfigXMLDir = INSTALL_DIR;
  195. }
  196. m_strBuildSetFileName = pParams->queryProp(TAG_BUILDSET);
  197. m_strBuildSetFilePath.append(m_strConfigXMLDir).append(STANDARD_CONFIG_CONFIGXML_DIR).append( m_strBuildSetFileName.length() > 0 ? m_strBuildSetFileName : STANDARD_CONFIG_BUILDSETFILE);
  198. m_pDefBldSet.set(createPTreeFromXMLFile(m_strBuildSetFilePath.str()));
  199. }
  200. }
  201. bool CConfigHelper::isInBuildSet(const char* comp_process_name, const char* comp_name) const
  202. {
  203. StringBuffer xpath;
  204. xpath.appendf("./%s/%s/%s[%s=\"%s\"][%s=\"%s\"]", XML_TAG_PROGRAMS, XML_TAG_BUILD, XML_TAG_BUILDSET, XML_ATTR_PROCESS_NAME, comp_process_name, XML_ATTR_NAME, comp_name);
  205. if (strcmp(XML_TAG_DIRECTORIES,comp_name) != 0 && m_pDefBldSet->queryPropTree(xpath.str()) == NULL)
  206. {
  207. return false;
  208. }
  209. else
  210. {
  211. return true;
  212. }
  213. }
  214. CWsDeployExCE::~CWsDeployExCE()
  215. {
  216. m_pCfg.clear();
  217. closeEnvironment();
  218. closedownClientProcess();
  219. HashIterator iter(m_fileInfos);
  220. ForEach(iter)
  221. {
  222. IMapping &cur = iter.query();
  223. CWsDeployFileInfo* pInfo = m_fileInfos.mapToValue(&cur);
  224. pInfo->Release();
  225. }
  226. m_fileInfos.kill();
  227. }
  228. IPropertyTree* CWsDeployFileInfo::getEnvTree(IEspContext &context, IConstWsDeployReqInfo *reqInfo)
  229. {
  230. StringBuffer sbName, sbUserIp;
  231. if (reqInfo)
  232. sbName.clear().append(reqInfo->getUserId());
  233. context.getPeer(sbUserIp);
  234. if (m_userWithLock.length() && !strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()) && m_Environment != NULL)
  235. return &m_Environment->getPTree();
  236. else
  237. return &m_constEnvRdOnly->getPTree();
  238. }
  239. void CWsDeployFileInfo::activeUserNotResponding()
  240. {
  241. m_activeUserNotResp = true;
  242. }
  243. void CWsDeployExCE::init(IPropertyTree *cfg, const char *process, const char *service)
  244. {
  245. if (m_lastStarted.isNull())
  246. m_lastStarted.setNow();
  247. if (m_pCfg.get() == NULL)
  248. m_pCfg.setown(createPTreeFromIPT(cfg));
  249. if (m_process.length() == 0)
  250. m_process.append(process);
  251. if (m_service.length() == 0)
  252. m_service.append(service);
  253. m_bCloud = false;
  254. StringBuffer xpath;
  255. m_envFile.clear();
  256. m_configHelper.init(cfg,service);
  257. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvConfFile", service);
  258. const char* tmp = cfg->queryProp(xpath.str());
  259. if (tmp && *tmp)
  260. {
  261. Owned<IProperties> pParams = createProperties(tmp);
  262. m_sourceDir.clear().append(pParams->queryProp("sourcedir"));
  263. if (!m_sourceDir.length())
  264. m_sourceDir.clear().append(STANDARD_CONFIG_SOURCEDIR);
  265. m_backupDir.clear().append(m_sourceDir).append(PATHSEPSTR"backup");
  266. }
  267. if (m_backupDir.length() == 0)
  268. m_backupDir.clear().append(STANDARD_CONFIG_BACKUPDIR);
  269. if (!m_sourceDir.length())
  270. m_sourceDir.clear().append(STANDARD_CONFIG_SOURCEDIR);
  271. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvFile", service);
  272. const char* pEnvFile = cfg->queryProp(xpath.str());
  273. if (pEnvFile && *pEnvFile)
  274. {
  275. CWsDeployFileInfo* fi = m_fileInfos.getValue(pEnvFile);
  276. StringBuffer sb;
  277. if (!fi)
  278. {
  279. synchronized block(m_mutexSrv);
  280. StringBuffer filePath(pEnvFile);
  281. if (strstr(pEnvFile, m_sourceDir.str()) != pEnvFile)
  282. {
  283. filePath.clear().append(m_sourceDir);
  284. filePath.append(PATHSEPCHAR);
  285. filePath.append(pEnvFile);
  286. }
  287. fi = new CWsDeployFileInfo(this, filePath.str(), m_bCloud);
  288. const char* psz = strrchr(pEnvFile, PATHSEPCHAR);
  289. if (!psz)
  290. psz = strrchr(pEnvFile, PATHSEPCHAR == '\\' ? '/' : '\\');
  291. if (!psz)
  292. sb.append(pEnvFile);
  293. else
  294. sb.append(psz + 1);
  295. m_fileInfos.setValue(sb.str(), fi);
  296. }
  297. try
  298. {
  299. fi->initFileInfo(false);
  300. }
  301. catch (IException* e)
  302. {
  303. m_fileInfos.remove(sb.str());
  304. delete fi;
  305. e->Release();
  306. }
  307. m_envFile.append(pEnvFile);
  308. }
  309. }
  310. bool CWsDeployFileInfo::navMenuEvent(IEspContext &context,
  311. IEspNavMenuEventRequest &req,
  312. IEspNavMenuEventResponse &resp)
  313. {
  314. synchronized block(m_mutex);
  315. checkForRefresh(context, &req.getReqInfo(), false);
  316. const char* cmd = req.getCmd();
  317. const char* xmlArg = req.getXmlArgs();
  318. if (!cmd || !*cmd)
  319. throw ::MakeStringException(-1, "Invalid command specified!");
  320. if (!strcmp(cmd, "LockEnvironment"))
  321. {
  322. StringBuffer sbName, sbUserIp;
  323. sbName.clear().append(req.getReqInfo().getUserId());
  324. context.getPeer(sbUserIp);
  325. if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()))
  326. throw MakeStringException(-1, "Another browser window already has write access on machine '%s'. Please use that window.", sbUserIp.str());
  327. }
  328. else if (strcmp(cmd, "SaveEnvironmentAs"))
  329. checkForRefresh(context, &req.getReqInfo(), true);
  330. if (!stricmp(cmd, "Deploy"))
  331. {
  332. /* xmlArg for is of the form:
  333. <EspNavigationData>
  334. <Folder name="Environment">
  335. <Folder name="Software">
  336. <Folder name="EspProcesses">
  337. <Link name="ESP Process - esp1" selected="true"/>
  338. <Link name="ESP Process - esp2" selected="true"/>
  339. </Folder>
  340. <Folder name="EclServerProcess - eclserver" selected="true"/>
  341. </Folder>
  342. </Folder>
  343. </EspNavigationData>
  344. There are one or more attributes and modules marked as @selected
  345. so enumerate these selected nodes and produce xml of the form:
  346. <Deploy>
  347. <SelectedComponents>
  348. <EspProcess name="esp1"/>//deploy all instances
  349. <EspProcess name="esp2"/>
  350. <Instance name="s1" computer="2wd20"/> //deploy selected instances only
  351. </EspProcess>
  352. </SelectedComponents>
  353. </Deploy>
  354. */
  355. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  356. IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree(XML_TAG_SOFTWARE);
  357. Owned<IPropertyTree> pDeploy = createPTree("Deploy");
  358. IPropertyTree* pComponents = pDeploy->addPropTree("Components", createPTree());
  359. if (pEnvSoftware)
  360. {
  361. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  362. IPropertyTree* pSoftwareFolder = pSrcTree->queryPropTree("Folder[@name='Environment']/Folder[@name='Software']");
  363. if (pSoftwareFolder)
  364. {
  365. bool bSelected = pSoftwareFolder->getPropBool("@selected", false);
  366. if (bSelected)
  367. {
  368. Owned<IPropertyTreeIterator> iComp = pEnvSoftware->getElements("*", iptiter_sort );
  369. ForEach(*iComp)
  370. addDeployableComponentAndInstances(pEnvRoot, &iComp->query(), pComponents, NULL, NULL);
  371. }
  372. else
  373. {
  374. Owned<IPropertyTreeIterator> iFolder = pSoftwareFolder->getElements( "*" );
  375. ForEach (*iFolder)
  376. {
  377. IPropertyTree* pFolder = &iFolder->query();
  378. bool bSelected = pFolder->getPropBool("@selected", false);
  379. const char* szFolderName = pFolder->queryProp(XML_ATTR_NAME);
  380. if (strstr(szFolderName, " - ") != NULL)
  381. {
  382. IPropertyTree* pCompInEnv = findComponentForFolder(pFolder, pEnvSoftware);
  383. if (pCompInEnv)
  384. addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pFolder, NULL);
  385. }
  386. else if (!strcmp(szFolderName, "ECL Servers"))
  387. {
  388. Owned<IPropertyTreeIterator> iSubFolder = pFolder->getElements( "*" );
  389. ForEach (*iSubFolder)
  390. {
  391. IPropertyTree* pSubFolder = &iSubFolder->query();
  392. IPropertyTree* pCompInEnv = findComponentForFolder(pSubFolder, pEnvSoftware);
  393. if (pCompInEnv)
  394. addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pSubFolder, NULL);
  395. }
  396. }
  397. else
  398. {
  399. //this folder bundles multiple components and has name like "ESP Servers"
  400. //
  401. if (bSelected)
  402. {
  403. //if selected, deploy all its components like deploy all ESP servers
  404. //
  405. const char* params = pFolder->queryProp("@params");
  406. if (params)
  407. {
  408. // pFolder's @params has string of the form: "comp=EspProcess"
  409. //
  410. Owned<IProperties> pParams = createProperties();
  411. pParams->loadProps(params);
  412. const char* comp = pParams->queryProp("comp");
  413. if (comp && *comp)
  414. {
  415. Owned<IPropertyTreeIterator> iComp = pEnvSoftware->getElements(comp);
  416. ForEach(*iComp)
  417. addDeployableComponentAndInstances(pEnvRoot, &iComp->query(), pComponents, NULL, szFolderName);
  418. }
  419. }
  420. }
  421. else
  422. {
  423. //deploy only selected components under this folder
  424. //
  425. Owned<IPropertyTreeIterator> iFolder = pFolder->getElements("*[@selected='true']");
  426. ForEach(*iFolder)
  427. {
  428. IPropertyTree* pFolder = &iFolder->query();
  429. IPropertyTree* pCompInEnv = findComponentForFolder(pFolder, pEnvSoftware);
  430. if (pCompInEnv)
  431. addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pFolder, szFolderName);
  432. }
  433. }
  434. }
  435. }
  436. }//software folder is not selected
  437. }//pSoftwareFolder
  438. }//pEnvSoftware
  439. StringBuffer xml;
  440. toXML(pDeploy, xml, false);
  441. resp.setComponent( "WsDeploy" );
  442. resp.setCommand ( "Deploy" );
  443. resp.setXmlArgs( xml.str() );
  444. }//deploy
  445. else
  446. if (!stricmp(cmd, "Dependencies"))
  447. {
  448. /* xmlArg for is of the form:
  449. <EspNavigationData>
  450. <Folder name="Environment">
  451. <Folder name="Hardware">
  452. <Folder name="Computers">
  453. <Link name="machine1"/>
  454. <Link name="machine2"/>
  455. </Folder>
  456. </Folder>
  457. </Folder>
  458. </EspNavigationData>
  459. There are one or more attributes and modules marked as @selected
  460. so enumerate these selected nodes and produce xml of the form:
  461. <Deploy>
  462. <SelectedComponents>
  463. <EspProcess name="esp1"/>//deploy all instances
  464. <EspProcess name="esp2"/>
  465. <Instance name="s1" computer="2wd20"/> //deploy selected instances only
  466. </EspProcess>
  467. </SelectedComponents>
  468. </Deploy>
  469. */
  470. Owned<IPropertyTree> pDeploy = createPTree("Deploy");
  471. IPropertyTree* pComponents = pDeploy->addPropTree("Components", createPTree());
  472. if (xmlArg && *xmlArg)
  473. {
  474. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString( xmlArg);
  475. IPropertyTree* pComputersFolder = pSrcTree->queryPropTree("Folder[@name='Environment']/Folder[@name='Hardware']/Folder[@name='Computers']");
  476. if (pComputersFolder)
  477. {
  478. Owned<IPropertyTreeIterator> iLink = pComputersFolder->getElements( "Link" );
  479. ForEach (*iLink)
  480. {
  481. IPropertyTree* pLink = &iLink->query();
  482. const bool bSelected = pLink->getPropBool("@selected", false);
  483. const char* szComputerName = pLink->queryProp(XML_ATTR_NAME);
  484. //this folder bundles multiple components and has name like "ESP Servers"
  485. //
  486. if (bSelected)
  487. {
  488. //deploy all its components like deploy all ESP servers
  489. //addDeployableComponentAndInstances(pEnvRoot, pCompInEnv, pComponents, pFolder, szFolderName);
  490. }
  491. }
  492. }//pSoftwareFolder
  493. }//pEnvSoftware
  494. StringBuffer xml;
  495. toXML(pDeploy, xml, false);
  496. resp.setComponent( "WsDeploy" );
  497. resp.setCommand ( "Deploy" );
  498. resp.setXmlArgs( xml.str() );
  499. }//dependencies
  500. else if (!stricmp(cmd, "LockEnvironment"))
  501. {
  502. StringBuffer xml;
  503. try
  504. {
  505. if (m_userWithLock.length() == 0 || m_activeUserNotResp)
  506. {
  507. StringBuffer sbName, sbUserIp;
  508. sbName.clear().append(req.getReqInfo().getUserId());
  509. context.getPeer(sbUserIp);
  510. if (m_pFile.get() && m_pFile->isReadOnly())
  511. {
  512. xml.appendf("Write access to the Environment cannot be provided as %s is Read Only.", m_envFile.str());
  513. resp.setXmlArgs(xml.str());
  514. return true;
  515. }
  516. if (m_bCloud)
  517. {
  518. StringBuffer sbMsg;
  519. Owned<IPropertyTree> pComputers = createPTreeFromXMLString(xmlArg);
  520. CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_UNLOCK_ENV, sbName.str(), "8015", pComputers);
  521. bool ret = lockCloud.start(sbMsg);
  522. if (!ret || sbMsg.length())
  523. {
  524. xml.appendf("Write access to the Environment cannot be provided. Reason(s):\n%s", sbMsg.str());
  525. resp.setXmlArgs(xml.str());
  526. return true;
  527. }
  528. else if (pComputers && pComputers->numChildren())
  529. m_lockedNodesBeforeEnv.set(pComputers);
  530. }
  531. StringBuffer sb;
  532. if (m_userWithLock.length() == 0)
  533. sb.append(sbName).append(sbUserIp);
  534. else
  535. {
  536. sb.append(m_userWithLock).append(m_userIp);
  537. m_userWithLock.clear();
  538. m_userIp.clear();
  539. m_Environment.clear();
  540. m_activeUserNotResp = false;
  541. }
  542. CClientAliveThread* th = m_keepAliveHTable.getValue(sb.str());
  543. if (th)
  544. {
  545. th->Release();
  546. m_keepAliveHTable.remove(sb.str());
  547. }
  548. StringBuffer sbxml;
  549. if (m_pFileIO.get())
  550. {
  551. Owned <IPropertyTree> pTree = createPTree(*m_pFileIO);
  552. toXML(pTree, sbxml);
  553. }
  554. else
  555. toXML(&m_constEnvRdOnly->getPTree(), sbxml);
  556. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  557. m_Environment.setown(factory->loadLocalEnvironment(sbxml.str()));
  558. m_userWithLock.clear().append(req.getReqInfo().getUserId());
  559. context.getPeer(m_userIp.clear());
  560. Owned<IPropertyTree> pEnvRoot = &m_Environment->getPTree();
  561. unsigned timeout = pEnvRoot->getPropInt(XML_TAG_ENVSETTINGS"/brokenconntimeout", 60);
  562. th = new CClientAliveThread(this, timeout * 60 * 1000);
  563. m_keepAliveHTable.setValue(sb.str(), th);
  564. th->init();
  565. StringBuffer tmp;
  566. m_lastSaved.getString(tmp);
  567. resp.setLastSaved(tmp.str());
  568. resp.setComponent( "WsDeploy" );
  569. resp.setCommand ( "LockEnvironment" );
  570. }
  571. else
  572. {
  573. StringBuffer sbName, sbUserIp;
  574. sbName.clear().append(req.getReqInfo().getUserId());
  575. context.getPeer(sbUserIp);
  576. if (strcmp(sbName.str(), m_userWithLock.str()) || strcmp(sbUserIp.str(), m_userIp.str()))
  577. {
  578. xml.appendf("Write access to the Environment cannot be provided as it is currently being used on machine %s.", m_userIp.str());
  579. resp.setXmlArgs(xml.str());
  580. }
  581. }
  582. }
  583. catch (IException* e)
  584. {
  585. StringBuffer sErrMsg;
  586. e->errorMessage(sErrMsg);
  587. e->Release();
  588. if (m_envFile.length())
  589. {
  590. char achHost[128] = "";
  591. const char* p = strstr(sErrMsg.str(), "\n\n");
  592. if (p && *(p+=2))
  593. {
  594. const char* q = strchr(p, ':');
  595. if (q)
  596. {
  597. const int len = q-p;
  598. strncpy(achHost, p, len);
  599. achHost[len] = '\0';
  600. }
  601. }
  602. //resolve hostname for this IP address
  603. unsigned int addr = inet_addr(achHost);
  604. struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
  605. if (hp)
  606. {
  607. strcpy(achHost, hp->h_name);
  608. //strlwr(achHost);
  609. }
  610. StringBuffer sMsg;
  611. sMsg.appendf("Error accessing the environment definition");
  612. if (achHost[0])
  613. sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost);
  614. else
  615. sMsg.append(":\n\n").append(sErrMsg);
  616. throw MakeStringException(0, "%s", sMsg.str());
  617. }
  618. else
  619. {
  620. StringBuffer sMsg;
  621. sMsg.append("Error locking environment. ").append(sErrMsg.str());
  622. throw MakeStringException(-1, "%s", sMsg.str());
  623. }
  624. }
  625. }
  626. else if (!stricmp(cmd, "UnlockEnvironment"))
  627. {
  628. StringBuffer xml;
  629. try
  630. {
  631. StringBuffer sbUser, sbUserIp, errMsg;
  632. context.getUserID(sbUser);
  633. sbUser.clear().append(req.getReqInfo().getUserId());
  634. context.getPeer(sbUserIp);
  635. if (!stricmp(m_userWithLock.str(), sbUser.str()) && !stricmp(sbUserIp.str(), m_userIp.str()))
  636. {
  637. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  638. IPropertyTree* pSaveEnv = pSrcTree->queryPropTree("SaveEnv[@flag='true']");
  639. StringBuffer sbErrMsg;
  640. if (pSaveEnv)
  641. {
  642. StringBuffer sb;
  643. m_skipEnvUpdateFromNotification = true;
  644. saveEnvironment(&context, &req.getReqInfo(), sb);
  645. if (sb.length())
  646. sbErrMsg.appendf("<Warning>%s</Warning>", sb.str());
  647. }
  648. unlockEnvironment(&context, &req.getReqInfo(), xmlArg, sbErrMsg, pSaveEnv != NULL);
  649. if (sbErrMsg.length())
  650. {
  651. resp.setXmlArgs(sbErrMsg.str());
  652. return true;
  653. }
  654. m_skipEnvUpdateFromNotification = false;
  655. StringBuffer tmp;
  656. m_lastSaved.getString(tmp);
  657. resp.setLastSaved(tmp.str());
  658. resp.setComponent( "WsDeploy" );
  659. resp.setCommand ( "UnlockEnvironment" );
  660. }
  661. else
  662. {
  663. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  664. resp.setComponent( "WsDeploy" );
  665. resp.setCommand ( "UnlockEnvironment" );
  666. resp.setXmlArgs( xml.str() );
  667. }
  668. }
  669. catch (IException* e)
  670. {
  671. StringBuffer sErrMsg;
  672. e->errorMessage(sErrMsg);
  673. e->Release();
  674. if (m_envFile.length() == 0)
  675. {
  676. char achHost[128] = "";
  677. const char* p = strstr(sErrMsg.str(), "\n\n");
  678. if (p && *(p+=2))
  679. {
  680. const char* q = strchr(p, ':');
  681. if (q)
  682. {
  683. const int len = q-p;
  684. strncpy(achHost, p, len);
  685. achHost[len] = '\0';
  686. }
  687. }
  688. //resolve hostname for this IP address
  689. unsigned int addr = inet_addr(achHost);
  690. struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
  691. if (hp)
  692. {
  693. strcpy(achHost, hp->h_name);
  694. }
  695. StringBuffer sMsg;
  696. sMsg.appendf("The environment definition in dali server "
  697. "could not be opened for write access");
  698. if (achHost[0])
  699. sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost);
  700. else
  701. sMsg.append(":\n\n").append(sErrMsg);
  702. throw MakeStringException(0, "%s", sMsg.str());
  703. }
  704. else
  705. {
  706. StringBuffer sMsg;
  707. sMsg.append("Error unlocking environment. ").append(sErrMsg.str());
  708. throw MakeStringException(-1, "%s", sMsg.str());
  709. }
  710. }
  711. }
  712. else if (!stricmp(cmd, "SaveEnvironment"))
  713. {
  714. StringBuffer xml;
  715. StringBuffer sbUser, sbIp, sbErrMsg;
  716. sbUser.clear().append(req.getReqInfo().getUserId());
  717. context.getPeer(sbIp);
  718. if (m_userWithLock.length() != 0 && m_userIp.length() != 0 &&
  719. !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str()) &&
  720. m_Environment != NULL)
  721. {
  722. saveEnvironment(&context, &req.getReqInfo(), sbErrMsg);
  723. if (sbErrMsg.length())
  724. resp.setXmlArgs(sbErrMsg.str());
  725. StringBuffer tmp;
  726. m_lastSaved.getString(tmp);
  727. resp.setLastSaved(tmp.str());
  728. resp.setComponent( "WsDeploy" );
  729. resp.setCommand ( "SaveEnvironment" );
  730. }
  731. else
  732. {
  733. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  734. resp.setComponent( "WsDeploy" );
  735. resp.setCommand ( "SaveEnvironment" );
  736. resp.setXmlArgs( xml.str() );
  737. }
  738. }
  739. else if (!stricmp(cmd, "SaveEnvironmentAs"))
  740. {
  741. StringBuffer xml;
  742. StringBuffer sbUser, sbIp;
  743. sbUser.clear().append(req.getReqInfo().getUserId());
  744. context.getPeer(sbIp);
  745. const char* xmlArg = req.getXmlArgs();
  746. Owned<IPropertyTree> pParamTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  747. const char* envSaveAs = pParamTree->queryProp("@envSaveAs");
  748. if (envSaveAs && *envSaveAs)
  749. {
  750. StringBuffer filePath(m_pService->getSourceDir());
  751. StringBuffer sbErrMsg;
  752. if (filePath.charAt(filePath.length() - 1) != PATHSEPCHAR)
  753. filePath.append(PATHSEPCHAR);
  754. filePath.append(envSaveAs);
  755. if (!strcmp(filePath.str(), m_envFile.str()))
  756. {
  757. if (m_userWithLock.length() != 0 && m_userIp.length() != 0 &&
  758. !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str()) &&
  759. m_Environment != NULL)
  760. {
  761. saveEnvironment(&context, &req.getReqInfo(), sbErrMsg);
  762. unlockEnvironment(&context, &req.getReqInfo(), "", sbErrMsg);
  763. if (sbErrMsg.length())
  764. {
  765. resp.setXmlArgs(sbErrMsg.str());
  766. return true;
  767. }
  768. StringBuffer tmp;
  769. m_lastSaved.getString(tmp);
  770. resp.setLastSaved(tmp.str());
  771. resp.setComponent("WsDeploy");
  772. resp.setCommand ("SaveEnvironmentAs");
  773. }
  774. else if (m_userWithLock.length() == 0 && m_userIp.length() == 0)
  775. {
  776. saveEnvironment(&context, &req.getReqInfo(), sbErrMsg, true);
  777. if (sbErrMsg.length())
  778. resp.setXmlArgs(sbErrMsg.str());
  779. StringBuffer tmp;
  780. m_lastSaved.getString(tmp);
  781. resp.setLastSaved(tmp.str());
  782. resp.setComponent("WsDeploy");
  783. resp.setCommand("SaveEnvironmentAs");
  784. }
  785. }
  786. else
  787. {
  788. CWsDeployFileInfo* fi = m_pService->getFileInfo(envSaveAs, true);
  789. StringBuffer sbUser, sbIp, sbXml;
  790. if ( fi->isLocked(sbUser, sbIp) == true)
  791. throw MakeStringException(-1, "%s is locked by another user. File not saved.", envSaveAs);
  792. if (isLocked(sbUser,sbIp) == true) // if we are in write only mode then save the working environment
  793. toXML(&m_Environment->getPTree(), sbXml);
  794. else
  795. toXML(&m_constEnvRdOnly->getPTree(), sbXml);
  796. if (fi->updateEnvironment(sbXml))
  797. fi->saveEnvironment(NULL, &req.getReqInfo(), sbErrMsg, true);
  798. else
  799. throw MakeStringException(-1, "Environment Save as operation has failed");
  800. if (m_userWithLock.length() != 0 && m_userIp.length() != 0)
  801. {
  802. if (sbErrMsg.length())
  803. {
  804. resp.setXmlArgs(sbErrMsg.str());
  805. return true;
  806. }
  807. }
  808. if (sbErrMsg.length())
  809. resp.setXmlArgs(sbErrMsg.str());
  810. StringBuffer tmp;
  811. fi->getLastSaved(tmp);
  812. resp.setLastSaved(tmp.str());
  813. resp.setComponent("WsDeploy");
  814. resp.setCommand("SaveEnvironmentAs");
  815. }
  816. }
  817. else
  818. throw MakeStringException(-1, "File name to save environment as cannot be empty");
  819. }
  820. else if (!stricmp(cmd, "ValidateEnvironment"))
  821. {
  822. StringBuffer xml;
  823. StringBuffer sbUser, sbIp;
  824. sbUser.clear().append(req.getReqInfo().getUserId());
  825. context.getPeer(sbIp);
  826. if (m_userWithLock.length() != 0 && m_userIp.length() != 0 &&
  827. !strcmp(m_userWithLock.str(), sbUser.str()) && !strcmp(m_userIp.str(), sbIp.str()) &&
  828. m_Environment != NULL)
  829. {
  830. if (m_envFile.length())
  831. validateEnv((IConstEnvironment*)m_Environment, false);
  832. resp.setComponent( "WsDeploy" );
  833. resp.setCommand ( "ValidateEnvironment" );
  834. }
  835. else
  836. {
  837. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  838. resp.setComponent( "WsDeploy" );
  839. resp.setCommand ( "SaveEnvironment" );
  840. resp.setXmlArgs( xml.str() );
  841. }
  842. }
  843. else
  844. {
  845. StringBuffer url;
  846. url.append("/WsDeploy/").append(cmd).append("?form");
  847. resp.setRedirectUrl(url.str());
  848. }
  849. return true;
  850. }//onNavMenuEvent
  851. bool CWsDeployFileInfo::isAlphaNumeric(const char *pstr) const
  852. {
  853. RegExpr expr("[A-Za-z0-9-_]+");
  854. return (expr.find(pstr) && expr.findlen(0) == strlen(pstr));
  855. }
  856. bool CWsDeployFileInfo::saveSetting(IEspContext &context, IEspSaveSettingRequest &req, IEspSaveSettingResponse &resp)
  857. {
  858. synchronized block(m_mutex);
  859. checkForRefresh(context, &req.getReqInfo(), true);
  860. const char* xmlArg = req.getXmlArgs();
  861. bool bUpdateFilesBasedn = req.getBUpdateFilesBasedn();
  862. Owned<IPropertyTree> pEnvRoot = &m_Environment->getPTree();
  863. IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree(XML_TAG_SOFTWARE);
  864. IPropertyTree* pEnvHardware = pEnvRoot->queryPropTree(XML_TAG_HARDWARE);
  865. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  866. IPropertyTree* pSoftwareFolder = pSrcTree->queryPropTree("Setting[@category='Software']");
  867. IPropertyTree* pTopologyFolder = pSrcTree->queryPropTree("Setting[@category='Topology']");
  868. IPropertyTree* pHardwareFolder = pSrcTree->queryPropTree("Setting[@category='Hardware']");
  869. IPropertyTree* pEnvFolder = pSrcTree->queryPropTree("Setting[@category='Environment']");
  870. if (pSoftwareFolder)
  871. {
  872. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements("Setting[@category='Software']");
  873. ForEach (*iter)
  874. {
  875. IPropertyTree* pSetting = &iter->query();
  876. StringBuffer decodedParams( pSetting->queryProp("@params") );
  877. decodedParams.replaceString("::", "\n");
  878. Owned<IProperties> pParams = createProperties();
  879. pParams->loadProps(decodedParams.str());
  880. const char* pszCompType = pParams->queryProp("pcType");
  881. const char* pszCompName = pParams->queryProp("pcName");
  882. const char* pszSubType = pParams->queryProp("subType");
  883. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  884. const char* pszAttrName = pSetting->queryProp("@attrName");
  885. const char* rowIndex = pSetting->queryProp("@rowIndex");
  886. const char* pszOldValue = pSetting->queryProp("@oldValue");
  887. const char* pszNewValue = pSetting->queryProp("@newValue");
  888. const char* pszOnChange = pSetting->queryProp("@onChange");
  889. const char* pszViewType = pSetting->queryProp("@viewType");
  890. StringBuffer xpath;
  891. xpath.clear().appendf("%s[@name='%s']", pszCompType, pszCompName);
  892. if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0)
  893. {
  894. if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']')
  895. xpath.appendf("/%s%s", pszSubType, pszSubTypeKey);
  896. else
  897. xpath.appendf("/%s[@name='%s']", pszSubType, pszSubTypeKey);
  898. }
  899. else if (!strcmp(pszCompType, "Topology"))
  900. xpath.appendf("[@name='%s']", pszSubTypeKey);
  901. else if (pszSubType && strlen(rowIndex) > 0)
  902. xpath.appendf("/%s[%s]", pszSubType, rowIndex);
  903. IPropertyTree* pComp = pEnvSoftware->queryPropTree(xpath.str());
  904. if (!pComp)
  905. {
  906. //read any updates to rows that have not been posted to the tree
  907. const char* pszUpdate = NULL;
  908. const char* key = NULL;
  909. int idx = 1;
  910. StringBuffer sbUpdate;
  911. StringBuffer xpath2;
  912. while (true)
  913. {
  914. sbUpdate.clear().appendf("Update%dKey", idx);
  915. key = pParams->queryProp(sbUpdate.str());
  916. if (!key)
  917. break;
  918. else
  919. {
  920. sbUpdate.clear().appendf("Update%dValue", idx);
  921. pszUpdate = pParams->queryProp(sbUpdate.str());
  922. break;
  923. }
  924. idx++;
  925. }
  926. xpath2.clear().appendf("*[@name='%s']", pszCompName);
  927. Owned<IPropertyTreeIterator> iter = pEnvSoftware->getElements(xpath2);
  928. ForEach (*iter)
  929. {
  930. IPropertyTree* pTmpComp = &iter->query();
  931. const char* pProcessName = pTmpComp->queryName();
  932. if (pProcessName && !strcmp(pProcessName, pszCompType))
  933. {
  934. if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0)
  935. {
  936. if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']')
  937. xpath2.clear().appendf("%s%s", pszSubType, pszSubTypeKey);
  938. else
  939. xpath2.clear().appendf("%s[@name='%s']", pszSubType, pszSubTypeKey);
  940. pComp = pTmpComp->queryPropTree(xpath2.str());
  941. if (!pComp)
  942. {
  943. if (pszUpdate && pszSubType && key)
  944. xpath2.clear().appendf("%s[@%s='%s']", pszSubType, key, pszUpdate);
  945. pComp = pTmpComp->queryPropTree(xpath2.str());
  946. }
  947. }
  948. else if (pszSubType)
  949. {
  950. StringBuffer tmppath;
  951. tmppath.clear().appendf("%s", pszSubType);
  952. pComp = pTmpComp->queryPropTree(tmppath.str());
  953. if (!pComp)
  954. {
  955. if (pszUpdate && key)
  956. {
  957. StringBuffer sbtmp(pszSubType);
  958. StringBuffer sb;
  959. const char* psz = strrchr(pszSubType, '/');
  960. const char* ptmp = pszSubType;
  961. if (psz)
  962. sbtmp.clear().append(psz + 1);
  963. psz = sbtmp.str();
  964. if (strchr(pszSubType, '[') && strchr(pszSubType, ']'))
  965. {
  966. char ch;
  967. bool copy = true;
  968. bool flag = false;
  969. while ((ch = *ptmp++) != '\0')
  970. {
  971. if (ch == '/')
  972. {
  973. flag = true;
  974. break;
  975. }
  976. else if (ch == '[')
  977. copy = false;
  978. else if (ch == ']')
  979. copy = true;
  980. else if (copy)
  981. sb.append(ch);
  982. }
  983. sb.appendf("[@%s='%s']/%s", key, pszUpdate, psz);
  984. }
  985. xpath2.clear().append(sb);
  986. }
  987. pComp = pTmpComp->queryPropTree(xpath2.str());
  988. }
  989. if (!pComp)
  990. {
  991. if (!strcmp(pszCompName, "Directories"))
  992. tmppath.clear().append(pszCompName);
  993. else
  994. tmppath.clear().appendf("%s[@name='%s']", pszCompType, pszCompName);
  995. IPropertyTree* pTmpComp = pEnvSoftware->queryPropTree(tmppath.str());
  996. if (!pTmpComp)
  997. continue;
  998. if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS))
  999. tmppath.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pTmpComp->queryProp(XML_ATTR_BUILDSET));
  1000. else
  1001. tmppath.clear().appendf("./Programs/Build/BuildSet[@processName=\"%s\"]", pszCompType);
  1002. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(tmppath.str());
  1003. buildSetIter->first();
  1004. IPropertyTree* pBuildSet;
  1005. if (buildSetIter->isValid())
  1006. pBuildSet = &buildSetIter->query();
  1007. else if (!strcmp(pszCompType, "Directories"))
  1008. {
  1009. pBuildSet = createPTree(XML_TAG_BUILDSET);
  1010. pBuildSet->addProp(XML_ATTR_NAME, pszCompName);
  1011. pBuildSet->addProp(XML_ATTR_SCHEMA, "directories.xsd");
  1012. pBuildSet->addProp(XML_ATTR_PROCESS_NAME, "Directories");
  1013. }
  1014. const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  1015. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  1016. StringBuffer buildSetPath;
  1017. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  1018. Owned<IPropertyTree> pNewCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName());
  1019. StringBuffer sbtmp(pszSubType);
  1020. StringBuffer sb;
  1021. const char* psz = strrchr(pszSubType, '/');
  1022. if (psz)
  1023. sbtmp.clear().append(psz + 1);
  1024. psz = sbtmp.str();
  1025. if (strchr(psz, '[') && strchr(psz, ']'))
  1026. {
  1027. char ch;
  1028. while ((ch = *psz++) != '\0')
  1029. {
  1030. if (ch != '[')
  1031. sb.append(ch);
  1032. else
  1033. break;
  1034. }
  1035. while ((ch = *psz++) != '\0')
  1036. {
  1037. if (ch == ']')
  1038. break;
  1039. }
  1040. sb.append(psz);
  1041. sbtmp.clear().append(sb);
  1042. }
  1043. Owned<IPropertyTreeIterator> iterElems = pNewCompTree->getElements(sbtmp.str());
  1044. ForEach (*iterElems)
  1045. {
  1046. IPropertyTree* pElem = &iterElems->query();
  1047. if (pElem)
  1048. pComp = pTmpComp->addPropTree(pszSubType, createPTreeFromIPT(pElem));
  1049. else
  1050. pComp = pTmpComp->addPropTree(pszSubType, createPTree());
  1051. break;
  1052. }
  1053. if (!pComp)
  1054. pComp = pTmpComp->addPropTree(pszSubType, createPTree());
  1055. if (pComp && !strcmp(pszAttrName, "name"))
  1056. pComp->setProp(XML_ATTR_NAME, pszNewValue);
  1057. }
  1058. }
  1059. else
  1060. pComp = &iter->query();
  1061. break;
  1062. }
  1063. const char* pBuildSet = pTmpComp->queryProp(XML_ATTR_BUILDSET);
  1064. if (pBuildSet && !strcmp(pBuildSet, pszCompType))
  1065. {
  1066. if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0)
  1067. {
  1068. if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']')
  1069. xpath2.clear().appendf("%s%s", pszSubType, pszSubTypeKey);
  1070. else
  1071. xpath2.clear().appendf("%s[@name='%s']", pszSubType, pszSubTypeKey);
  1072. pComp = pTmpComp->queryPropTree(xpath2.str());
  1073. if (!pComp)
  1074. {
  1075. if (pszUpdate && pszSubType && key)
  1076. xpath2.clear().appendf("%s[@%s='%s']", pszSubType, key, pszUpdate);
  1077. pComp = pTmpComp->queryPropTree(xpath2.str());
  1078. }
  1079. }
  1080. else if (pszSubType && strlen(rowIndex) > 0)
  1081. {
  1082. xpath2.clear().appendf("%s[%s]", pszSubType, rowIndex);
  1083. pComp = pTmpComp->queryPropTree(xpath2.str());
  1084. }
  1085. else if (pszSubType)
  1086. {
  1087. xpath2.clear().appendf("%s", pszSubType);
  1088. pComp = pTmpComp->queryPropTree(xpath2.str());
  1089. }
  1090. else
  1091. pComp = &iter->query();
  1092. break;
  1093. }
  1094. }
  1095. }
  1096. if (bUpdateFilesBasedn == true && strcmp(pszAttrName, TAG_LDAPSERVER) == 0 && strcmp(pszCompType, XML_TAG_DALISERVERPROCESS) == 0 && pComp != NULL)
  1097. {
  1098. Owned<IPropertyTree> pActiveEnvRoot = getEnvTree(context, &req.getReqInfo());
  1099. StringBuffer ldapXPath;
  1100. StringBuffer strFilesBasedn;
  1101. if (pszNewValue && *pszNewValue)
  1102. {
  1103. ldapXPath.appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, XML_TAG_LDAPSERVERPROCESS, XML_ATTR_NAME, pszNewValue);
  1104. strFilesBasedn.appendf("%s",pActiveEnvRoot->queryPropTree(ldapXPath.str())->queryProp(XML_ATTR_FILESBASEDN));
  1105. }
  1106. pComp->setProp(XML_ATTR_FILESBASEDN,strFilesBasedn);
  1107. }
  1108. else if (bUpdateFilesBasedn == true && pComp != NULL && strcmp(pszCompType, XML_TAG_ESPPROCESS) == 0 && strcmp(pszAttrName, TAG_SERVICE) == 0 && pszNewValue && *pszNewValue)
  1109. {
  1110. Owned<IPropertyTree> pActiveEnvRoot = getEnvTree(context, &req.getReqInfo());
  1111. StringBuffer ldapXPath;
  1112. StringBuffer espServiceXPath;
  1113. StringBuffer espProcessXPath;
  1114. StringBuffer strFilesBasedn;
  1115. espServiceXPath.appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, XML_TAG_ESPSERVICE, XML_ATTR_NAME, pszNewValue);
  1116. espProcessXPath.appendf("./%s/%s/[%s=\"%s\"]/%s", XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS, XML_ATTR_NAME, pszCompName, XML_TAG_AUTHENTICATION);
  1117. StringBuffer strLDAPName(pActiveEnvRoot->queryPropTree(espProcessXPath.str())->queryProp(XML_ATTR_LDAPSERVER));
  1118. if (strLDAPName.length() > 0)
  1119. {
  1120. ldapXPath.appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, XML_TAG_LDAPSERVERPROCESS, XML_ATTR_NAME, strLDAPName.str());
  1121. strFilesBasedn.appendf("%s", pActiveEnvRoot->queryPropTree(ldapXPath.str())->queryProp(XML_ATTR_FILESBASEDN));
  1122. }
  1123. pActiveEnvRoot->queryPropTree(espServiceXPath.str())->setProp(XML_ATTR_FILESBASEDN, strFilesBasedn);
  1124. }
  1125. else if (bUpdateFilesBasedn == true && strcmp(pszAttrName, TAG_LDAPSERVER) == 0 && strcmp(pszCompType, XML_TAG_ESPPROCESS) == 0 && pComp != NULL)
  1126. {
  1127. Owned<IPropertyTree> pActiveEnvRoot = getEnvTree(context, &req.getReqInfo());
  1128. StringBuffer ldapXPath;
  1129. StringBuffer espBindingXPath;
  1130. StringBuffer espProcessXPath;
  1131. StringBuffer strFilesBasedn;
  1132. if (pszNewValue != NULL && *pszNewValue != 0)
  1133. {
  1134. ldapXPath.appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, XML_TAG_LDAPSERVERPROCESS, XML_ATTR_NAME, pszNewValue);
  1135. strFilesBasedn.appendf("%s",pActiveEnvRoot->queryPropTree(ldapXPath.str())->queryProp(XML_ATTR_FILESBASEDN));
  1136. }
  1137. espBindingXPath.appendf("./%s/%s[%s=\"%s\"]/%s", XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS, XML_ATTR_NAME, pszCompName, XML_TAG_ESPBINDING);
  1138. Owned<IPropertyTreeIterator> iterItems = pActiveEnvRoot->getElements(espBindingXPath.str());
  1139. ForEach(*iterItems)
  1140. {
  1141. IPropertyTree *pItem = &iterItems->query();
  1142. const char* service_name = pItem->queryProp(XML_ATTR_SERVICE);
  1143. espProcessXPath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, XML_TAG_ESPSERVICE, XML_ATTR_NAME, service_name);
  1144. const char* service_type = pActiveEnvRoot->queryPropTree(espProcessXPath.str())->queryProp(XML_ATTR_BUILDSET);
  1145. if (service_type && *service_type && !strcmp(service_type, "espsmc"))
  1146. pActiveEnvRoot->queryPropTree(espProcessXPath.str())->setProp(XML_ATTR_FILESBASEDN, strFilesBasedn);
  1147. }
  1148. }
  1149. // Update of LDAP component filesBasedn
  1150. else if (bUpdateFilesBasedn == true && strcmp(pszAttrName, TAG_FILESBASEDN) == 0 && strcmp(pszCompType, XML_TAG_LDAPSERVERPROCESS) == 0 && pszCompName != NULL && pszNewValue != NULL)
  1151. {
  1152. // update dali
  1153. StringBuffer daliProcessXPath;
  1154. daliProcessXPath.appendf("./%s/%s", XML_TAG_SOFTWARE, XML_TAG_DALISERVERPROCESS);
  1155. Owned<IPropertyTree> pActiveEnvRoot = getEnvTree(context, &req.getReqInfo());
  1156. Owned<IPropertyTreeIterator> iterItems = pActiveEnvRoot->getElements(daliProcessXPath.str());
  1157. ForEach(*iterItems)
  1158. {
  1159. IPropertyTree *pItem = &iterItems->query();
  1160. const char* ldap_server = pItem->queryProp(XML_ATTR_LDAPSERVER);
  1161. // check if dali has this ldap server assigned before changing filesBasedn
  1162. if (ldap_server != NULL && strcmp(ldap_server, pszCompName) == 0)
  1163. pItem->setProp(XML_ATTR_FILESBASEDN, pszNewValue);
  1164. }
  1165. //update esp services
  1166. StringBuffer espProcessXPath;
  1167. StringBuffer espBindingXPath;
  1168. StringBuffer espServiceXPath;
  1169. espProcessXPath.appendf("./%s/%s", XML_TAG_SOFTWARE, XML_TAG_ESPPROCESS);
  1170. Owned<IPropertyTreeIterator> iterItems2 = pActiveEnvRoot->getElements(espProcessXPath.str());
  1171. ForEach(*iterItems2)
  1172. {
  1173. IPropertyTree *pItem = &iterItems2->query();
  1174. const char* ldap_server = pItem->queryPropTree(XML_TAG_AUTHENTICATION)->queryProp(XML_ATTR_LDAPSERVER);
  1175. if (ldap_server != NULL && strcmp(ldap_server, pszCompName) == 0)
  1176. {
  1177. espBindingXPath.clear().appendf("%s[%s=\"%s\"]/%s", espProcessXPath.str(), XML_ATTR_NAME, pItem->queryProp(XML_ATTR_NAME), XML_TAG_ESPBINDING);
  1178. Owned<IPropertyTreeIterator> iterItems3 = pActiveEnvRoot->getElements(espBindingXPath.str());
  1179. ForEach(*iterItems3)
  1180. {
  1181. IPropertyTree *pItem = &iterItems3->query();
  1182. const char* service_name = pItem->queryProp(XML_ATTR_SERVICE);
  1183. espServiceXPath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, XML_TAG_ESPSERVICE, XML_ATTR_NAME, service_name);
  1184. const char* service_type = pActiveEnvRoot->queryPropTree(espServiceXPath.str())->queryProp(XML_ATTR_BUILDSET);
  1185. if (service_type && *service_type && !strcmp(service_type, "espsmc"))
  1186. pActiveEnvRoot->queryPropTree(espServiceXPath.str())->setProp(XML_ATTR_FILESBASEDN, pszNewValue);
  1187. }
  1188. }
  1189. }
  1190. }
  1191. if (!pComp)
  1192. throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", pszCompType, pszCompName);
  1193. else
  1194. {
  1195. if (pszOnChange && !strcmp(pszOnChange, "2"))
  1196. {
  1197. StringBuffer xpathBSet;
  1198. //get the onChange xslt and apply it.
  1199. if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS))
  1200. xpathBSet.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pComp->queryProp(XML_ATTR_BUILDSET));
  1201. else
  1202. xpathBSet.clear().appendf("./Programs/Build/BuildSet[@processName=\"%s\"]", pszCompType);
  1203. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpathBSet.str());
  1204. buildSetIter->first();
  1205. IPropertyTree* pBuildSet;
  1206. if (!buildSetIter->isValid())
  1207. {
  1208. xpathBSet.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pszCompType);
  1209. buildSetIter.setown(pEnvRoot->getElements(xpathBSet.str()));
  1210. buildSetIter->first();
  1211. }
  1212. if (buildSetIter->isValid())
  1213. {
  1214. pBuildSet = &buildSetIter->query();
  1215. const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  1216. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  1217. StringBuffer buildSetPath;
  1218. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  1219. StringBuffer xpathOnChg;
  1220. xpathOnChg.append(".//xs:attribute[@name=\"").append(pszAttrName).append("\"]//onchange");
  1221. IPropertyTree* pAttr = pSchema->queryPropTree(xpathOnChg.str());
  1222. xpathOnChg.clear().append(".//onchange");
  1223. IPropertyTree* pOnChange = pAttr? pAttr->queryPropTree(xpathOnChg.str()) : NULL;
  1224. if (pAttr)
  1225. {
  1226. const char* onChangeXslt = pAttr->queryProp("xslt");
  1227. if (onChangeXslt && *onChangeXslt)
  1228. {
  1229. StringBuffer sbAttrName("@");
  1230. sbAttrName.append(pszAttrName);
  1231. pComp->setProp(sbAttrName.str(), pszNewValue);
  1232. if (onChangeAttribute(pEnvRoot, m_Environment, pszAttrName, pAttr, pComp, pComp /*TBD Calc parent nodeGetParentNode()*/, 0, pszNewValue, pszOldValue, pszCompType))
  1233. {
  1234. bool bRefresh = pAttr->getPropBool("refresh", true);
  1235. if (bRefresh)
  1236. {
  1237. resp.setRefresh("true");
  1238. resp.setUpdateValue(pszNewValue);
  1239. return true;
  1240. }
  1241. }
  1242. else
  1243. {
  1244. pComp->setProp(sbAttrName.str(), pszOldValue);
  1245. resp.setUpdateValue(pszOldValue);
  1246. return true;
  1247. }
  1248. }
  1249. }
  1250. }
  1251. }
  1252. //perform checks
  1253. if (!strcmp(pszAttrName, "name"))
  1254. {
  1255. ensureUniqueName(pEnvRoot, pComp, pszNewValue);
  1256. if (isAlphaNumeric(pszNewValue) == false)
  1257. {
  1258. throw MakeStringException(-1, "Invalid Character in name '%s'.", pszNewValue);
  1259. }
  1260. }
  1261. //Store prev settings for use further down for esp service bindings
  1262. const char* sPrevDefaultPort = NULL;
  1263. const char* sPrevPort = NULL;
  1264. const char* sPrevResBasedn = NULL;
  1265. const char* sPrevDefaultSecurePort = NULL;
  1266. const char* sPrevDefaultResBasedn = NULL;
  1267. if (pszSubType && !strcmp(pszSubType, XML_TAG_ESPBINDING) &&
  1268. (!strcmp(pszAttrName, "service") || !strcmp(pszAttrName, "protocol")))
  1269. {
  1270. const char* szServiceName = xpath.clear().append("Software/EspService[@name=\"");
  1271. xpath.append(pComp->queryProp(XML_ATTR_SERVICE));
  1272. xpath.append("\"]/Properties");
  1273. IPropertyTree* pPrevSvcProps = pEnvRoot->queryPropTree(xpath);
  1274. if (pPrevSvcProps)
  1275. {
  1276. sPrevDefaultPort = pPrevSvcProps->queryProp("@defaultPort");
  1277. sPrevDefaultSecurePort= pPrevSvcProps->queryProp("@defaultSecurePort");
  1278. sPrevDefaultResBasedn = pPrevSvcProps->queryProp("@defaultResourcesBasedn");
  1279. }
  1280. sPrevPort = pComp->queryProp("@port");
  1281. sPrevResBasedn = pComp->queryProp("@resourcesBasedn");
  1282. }
  1283. bool isSet = false;
  1284. if (pszSubType && strstr(pszSubType, "Notes") == pszSubType && !strcmp(pszAttrName, "Note"))
  1285. {
  1286. pComp->setProp(".", pszNewValue);
  1287. isSet = true;
  1288. }
  1289. else if (pszCompType && !strcmp(pszCompType, XML_TAG_ESPPROCESS))
  1290. {
  1291. String strXPath(xpath);
  1292. if (strXPath.indexOf("CSR") != -1 || strXPath.indexOf("Certificate") != -1 || strXPath.indexOf("PrivateKey") != -1)
  1293. {
  1294. StringBuffer sbNewVal(pszNewValue);
  1295. pEnvSoftware->setProp(xpath, sbNewVal.str());
  1296. isSet = true;
  1297. }
  1298. }
  1299. StringBuffer encryptedText;
  1300. if (!isSet)
  1301. {
  1302. xpath.clear().appendf("@%s", pszAttrName);
  1303. if (pszViewType && *pszViewType && !strcmp(pszViewType, "password"))
  1304. {
  1305. encrypt(encryptedText, pszNewValue);
  1306. pszNewValue = encryptedText.str();
  1307. }
  1308. pComp->setProp(xpath, pszNewValue);
  1309. }
  1310. resp.setUpdateValue(pszNewValue);
  1311. if (!strcmp(pszAttrName, "name"))
  1312. {
  1313. if (!pszSubType || !*pszSubType)
  1314. {
  1315. StringBuffer rundir;
  1316. if (!getConfigurationDirectory(pEnvRoot->queryPropTree("Software/Directories"), "run", pszCompType, pszNewValue, rundir))
  1317. rundir.clear().appendf(RUNTIME_DIR"/%s", pszNewValue);
  1318. Owned<IPropertyTreeIterator> iterInsts = pComp->getElements(XML_TAG_INSTANCE);
  1319. ForEach (*iterInsts)
  1320. iterInsts->query().setProp(XML_ATTR_DIRECTORY, rundir.str());
  1321. if (!strcmp(pszCompType, XML_TAG_ROXIECLUSTER))
  1322. pComp->setProp(XML_ATTR_DIRECTORY, rundir);
  1323. }
  1324. StringBuffer sbold, sbnew, sbMsg;
  1325. bool ret = false;
  1326. if (pszSubType && !strcmp(pszSubType, "EspBinding"))
  1327. {
  1328. sbold.append(pszCompName).append('/').append(pszOldValue);
  1329. sbnew.append(pszCompName).append('/').append(pszNewValue);
  1330. ret = checkComponentReferences(pEnvRoot, pComp, sbold.str(), sbMsg, sbnew.str());
  1331. }
  1332. else
  1333. ret = checkComponentReferences(pEnvRoot, pComp, pszOldValue, sbMsg, pszNewValue);
  1334. if (ret)
  1335. resp.setRefresh("true");
  1336. }
  1337. if (pszCompType && *pszCompType && pszSubType && *pszSubType &&
  1338. !strcmp(pszCompType, XML_TAG_ROXIECLUSTER) && !strcmp(pszSubType, XML_TAG_ROXIE_FARM)
  1339. && pszAttrName && *pszAttrName)
  1340. {
  1341. Owned<IPropertyTreeIterator> iter = pComp->getElements(XML_TAG_ROXIE_SERVER);
  1342. ForEach (*iter)
  1343. {
  1344. IPropertyTree* pSrv = &iter->query();
  1345. const char* pszName = pSrv->queryProp(XML_ATTR_NAME);
  1346. xpath.clear().appendf(XML_TAG_ROXIECLUSTER"[@name='%s']/"XML_TAG_ROXIE_SERVER"[@name='%s']/", pszCompName, pszName);
  1347. IPropertyTree* pServer = pEnvSoftware->queryPropTree(xpath.str());
  1348. if (pServer)
  1349. {
  1350. StringBuffer sbattr("@");
  1351. sbattr.append(pszAttrName);
  1352. pServer->setProp(sbattr.str(), pszNewValue);
  1353. }
  1354. }
  1355. }
  1356. //if dataDirectory for a roxie farm is being changed, also change baseDataDir for roxie
  1357. if(!strcmp(pszCompType, "Directories") && !strcmp(pszSubType, "Category"))
  1358. {
  1359. StringBuffer sbNewValue;
  1360. bool bdata = strstr(pszSubTypeKey, "[@name='data']") || strstr(pszSubTypeKey, "[@name=\"data\"]");\
  1361. bool bdata2 = strstr(pszSubTypeKey, "[@name='data2']") || strstr(pszSubTypeKey, "[@name=\"data2\"]");
  1362. bool bdata3 = strstr(pszSubTypeKey, "[@name='data3']") || strstr(pszSubTypeKey, "[@name=\"data3\"]");
  1363. if (bdata || bdata2 || bdata3)
  1364. {
  1365. Owned<IPropertyTreeIterator> iterRoxies = pEnvSoftware->getElements("RoxieCluster");
  1366. ForEach (*iterRoxies)
  1367. {
  1368. IPropertyTree* pRoxie = &iterRoxies->query();
  1369. if (bdata)
  1370. {
  1371. getCommonDir(pEnvRoot, "data", "roxie", pRoxie->queryProp(XML_ATTR_NAME), sbNewValue.clear());
  1372. pRoxie->setProp("@baseDataDir", sbNewValue.str());
  1373. //change all farms
  1374. Owned<IPropertyTreeIterator> iterFarms = pRoxie->getElements(XML_TAG_ROXIE_FARM);
  1375. ForEach (*iterFarms)
  1376. {
  1377. IPropertyTree* pTmpComp = &iterFarms->query();
  1378. if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sbNewValue.str()))
  1379. pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
  1380. }
  1381. //change all legacy Roxie servers
  1382. Owned<IPropertyTreeIterator> iterRoxieServers = pRoxie->getElements(XML_TAG_ROXIE_SERVER);
  1383. ForEach (*iterRoxieServers)
  1384. {
  1385. IPropertyTree* pTmpComp = &iterRoxieServers->query();
  1386. if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sbNewValue.str()))
  1387. pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
  1388. }
  1389. //also change roxie slave primary data directory for all RoxieSlave and RoxieSlaveProcess
  1390. Owned<IPropertyTreeIterator> iterSlvs = pRoxie->getElements(XML_TAG_ROXIE_ONLY_SLAVE);
  1391. ForEach (*iterSlvs)
  1392. {
  1393. IPropertyTree* pTmpComp = &iterSlvs->query();
  1394. const char* pRoxieComputer = pTmpComp->queryProp(XML_ATTR_COMPUTER);
  1395. IPropertyTree* pChannel = pTmpComp->queryPropTree(XML_TAG_ROXIE_CHANNEL"[1]");
  1396. if (pChannel)
  1397. {
  1398. pChannel->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
  1399. const char* number = pChannel->queryProp("@number");
  1400. xpath.clear().appendf(XML_TAG_ROXIE_SLAVE"[@channel='%s'][@computer='%s']", number, pRoxieComputer);
  1401. IPropertyTree* pSlvProc = pRoxie->queryPropTree(xpath.str());
  1402. if (pSlvProc)
  1403. pSlvProc->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
  1404. }
  1405. }
  1406. }
  1407. else if (bdata2 || bdata3)
  1408. {
  1409. getCommonDir(pEnvRoot, bdata2 ? "data2" : "data3" , "roxie", pRoxie->queryProp(XML_ATTR_NAME), sbNewValue.clear());
  1410. Owned<IPropertyTreeIterator> iterSlvs = pRoxie->getElements(XML_TAG_ROXIE_ONLY_SLAVE);
  1411. StringBuffer sb(XML_TAG_ROXIE_CHANNEL);
  1412. sb.appendf("%s", bdata2?"[2]":"[3]");
  1413. ForEach (*iterSlvs)
  1414. {
  1415. IPropertyTree* pTmpComp = &iterSlvs->query();
  1416. const char* pRoxieComputer = pTmpComp->queryProp(XML_ATTR_COMPUTER);
  1417. IPropertyTree* pChannel = pTmpComp->queryPropTree(sb.str());
  1418. if (pChannel)
  1419. {
  1420. pChannel->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
  1421. const char* number = pChannel->queryProp("@number");
  1422. xpath.clear().appendf(XML_TAG_ROXIE_SLAVE"[@channel='%s'][@computer='%s']", number, pRoxieComputer);
  1423. IPropertyTree* pSlvProc = pRoxie->queryPropTree(xpath.str());
  1424. if (pSlvProc)
  1425. pSlvProc->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
  1426. }
  1427. }
  1428. }
  1429. }
  1430. }
  1431. }
  1432. //if we are changing the eclServer field of wsattributes, set the following
  1433. //extra params from that eclserver. dbPassword, dbUser, mySQL, repository
  1434. if (!strcmp(pszCompType, "WsAttributes") && !strcmp(pszAttrName, "eclServer"))
  1435. {
  1436. xpath.clear().appendf("Software/EclServerProcess[@name='%s']", pszNewValue);
  1437. IPropertyTree* pEclServer = pEnvRoot->queryPropTree(xpath.str());
  1438. if (pEclServer)
  1439. {
  1440. pComp->setProp("@dbPassword", pEclServer->queryProp("@dbPassword"));
  1441. pComp->setProp("@dbUser", pEclServer->queryProp("@dbUser"));
  1442. pComp->setProp("@mySQL", pEclServer->queryProp("@MySQL"));
  1443. pComp->setProp("@repository", pEclServer->queryProp("@repository"));
  1444. }
  1445. }
  1446. else if (!strcmp(pszCompType, "EclServerProcess") && (!strcmp(pszAttrName, "dbPassword") ||
  1447. !strcmp(pszAttrName, "dbUser") || !strcmp(pszAttrName, "MySQL") ||
  1448. !strcmp(pszAttrName, "repository")))
  1449. {
  1450. xpath.clear().append("Software/EspService[@buildSet='WsAttributes']");
  1451. Owned<IPropertyTreeIterator> pWsAttrsIter = pEnvRoot->getElements(xpath.str());
  1452. ForEach(*pWsAttrsIter)
  1453. {
  1454. IPropertyTree* wsAttr = &pWsAttrsIter->query();
  1455. if (!strcmp(wsAttr->queryProp("@eclServer"), pszCompName))
  1456. {
  1457. wsAttr->setProp("@dbPassword", pComp->queryProp("@dbPassword"));
  1458. wsAttr->setProp("@dbUser", pComp->queryProp("@dbUser"));
  1459. wsAttr->setProp("@mySQL", pComp->queryProp("@MySQL"));
  1460. wsAttr->setProp("@repository", pComp->queryProp("@repository"));
  1461. }
  1462. }
  1463. }
  1464. if (pszSubType && !strcmp(pszSubType, XML_TAG_INSTANCE) && !strcmp(pszAttrName, TAG_COMPUTER))
  1465. {
  1466. xpath.clear().appendf("Hardware/Computer[@name='%s']", pszNewValue);
  1467. IPropertyTree* pEnvComputer = pEnvRoot->queryPropTree(xpath);
  1468. if (pEnvComputer)
  1469. {
  1470. const char* pszNetAddr = pEnvComputer->queryProp(XML_ATTR_NETADDRESS);
  1471. if (pszNetAddr)
  1472. {
  1473. StringBuffer prevValue;
  1474. pComp->getProp(XML_ATTR_NETADDRESS, prevValue);
  1475. resp.setPrevValue(prevValue.str());
  1476. pComp->setProp(XML_ATTR_NETADDRESS, pszNetAddr);
  1477. resp.setUpdateValue(pszNetAddr);
  1478. resp.setUpdateAttr("netAddress");
  1479. }
  1480. const char* name = pComp->queryProp(XML_ATTR_NAME);
  1481. if (!name || !*name)
  1482. {
  1483. pComp->setProp(XML_ATTR_NAME, "s1");
  1484. StringBuffer sb;
  1485. StringBuffer rundir;
  1486. if (!getConfigurationDirectory(pEnvRoot->queryPropTree("Software/Directories"), "run", pszCompType, pszCompName, rundir))
  1487. sb.clear().appendf(RUNTIME_DIR"/%s", pszCompName);
  1488. else
  1489. sb.clear().append(rundir);
  1490. pComp->setProp(XML_ATTR_DIRECTORY, sb.str());
  1491. }
  1492. }
  1493. }
  1494. if (pszSubType && !strcmp(pszSubType, XML_TAG_ESPBINDING) &&
  1495. (!strcmp(pszAttrName, "service") || !strcmp(pszAttrName, "protocol")))
  1496. {
  1497. bool bEspServiceChanged = !strcmp(pszAttrName, "service");
  1498. const char* szSrvName = pComp->queryProp(XML_ATTR_SERVICE);
  1499. xpath.clear().append("Software/EspService[@name=\"");
  1500. xpath.append(bEspServiceChanged ? pszNewValue : szSrvName ? szSrvName : "");
  1501. xpath.append("\"]/Properties");
  1502. IPropertyTree* pSvcProps = pEnvRoot->queryPropTree(xpath.str());
  1503. if (bEspServiceChanged)
  1504. {
  1505. IPropertyTree* pChild;
  1506. while ((pChild = pComp->queryPropTree("Authenticate[1]")) != NULL)
  1507. if (pChild)
  1508. pComp->removeTree( pChild );
  1509. while ((pChild = pComp->queryPropTree("AuthenticateFeature[1]")) != NULL)
  1510. if (pChild)
  1511. pComp->removeTree( pChild );
  1512. while ((pChild = pComp->queryPropTree("AuthenticateSetting[1]")) != NULL)
  1513. if (pChild)
  1514. pComp->removeTree( pChild );
  1515. }
  1516. if (pSvcProps)
  1517. {
  1518. if (bEspServiceChanged)
  1519. {
  1520. xpath.clear().append("./Programs/Build/BuildSet[@processName=\"EspProcess\"]");
  1521. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpath.str());
  1522. buildSetIter->first();
  1523. IPropertyTree* pBuildSet = &buildSetIter->query();
  1524. const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  1525. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  1526. StringBuffer buildSetPath;
  1527. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  1528. Owned<IPropertyTree> pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName());
  1529. Owned<IPropertyTreeIterator> i = pSvcProps->getElements("Authenticate");
  1530. ForEach(*i)
  1531. {
  1532. IPropertyTree* pAuthCopy = createPTreeFromIPT(&i->query());
  1533. mergeAttributes(pAuthCopy, pCompTree->queryPropTree("Authenticate"));
  1534. IPropertyTree* pNewNode = pComp->addPropTree("Authenticate", pAuthCopy);
  1535. }
  1536. i.setown( pSvcProps->getElements("AuthenticateFeature") );
  1537. ForEach(*i)
  1538. {
  1539. IPropertyTree* pAuthCopy = createPTreeFromIPT(&i->query());
  1540. mergeAttributes(pAuthCopy, pCompTree->queryPropTree("AuthenticateFeature"));
  1541. IPropertyTree* pNewNode = pComp->addPropTree("AuthenticateFeature", pAuthCopy);
  1542. }
  1543. i.setown( pSvcProps->getElements("AuthenticateSetting") );
  1544. ForEach(*i)
  1545. {
  1546. IPropertyTree* pAuthCopy = createPTreeFromIPT(&i->query());
  1547. mergeAttributes(pAuthCopy, pCompTree->queryPropTree("AuthenticateSetting"));
  1548. IPropertyTree* pNewNode = pComp->addPropTree("AuthenticateSetting", pAuthCopy);
  1549. }
  1550. }
  1551. const char* szProtocol = pComp->queryProp("@protocol");
  1552. bool bHttps = szProtocol && !strcmp(szProtocol, "https");
  1553. const char* szDefaultPort = pSvcProps->queryProp(bHttps ? "@defaultSecurePort" : "@defaultPort");
  1554. if (!bEspServiceChanged)//@protocol was just changed so use last one
  1555. bHttps = !bHttps;
  1556. const char* szPrevDefaultPort = bHttps ? sPrevDefaultSecurePort : sPrevDefaultPort;
  1557. if (szDefaultPort &&
  1558. ((!sPrevPort || (sPrevPort && !*sPrevPort)) || (szPrevDefaultPort && !strcmp(sPrevPort, szPrevDefaultPort))))
  1559. pComp->setProp(XML_ATTR_PORT, szDefaultPort);
  1560. if (bEspServiceChanged)
  1561. {
  1562. const char* szDefault = pSvcProps->queryProp("@defaultResourcesBasedn");
  1563. if (szDefault &&
  1564. ((!sPrevResBasedn || (sPrevResBasedn && !*sPrevResBasedn )) || (sPrevDefaultResBasedn && !strcmp(sPrevResBasedn, sPrevDefaultResBasedn))))
  1565. pComp->setProp("@resourcesBasedn", szDefault);
  1566. }
  1567. }
  1568. resp.setRefresh("true");
  1569. }
  1570. }
  1571. resp.setIsSaved("true");
  1572. }
  1573. }
  1574. else if (pTopologyFolder)
  1575. {
  1576. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements("Setting[@category='Topology']");
  1577. ForEach (*iter)
  1578. {
  1579. IPropertyTree* pSetting = &iter->query();
  1580. StringBuffer decodedParams( pSetting->queryProp("@params") );
  1581. decodedParams.replaceString("::", "\n");
  1582. Owned<IProperties> pParams = createProperties();
  1583. pParams->loadProps(decodedParams.str());
  1584. const char* pszCompType = pParams->queryProp("pcType");
  1585. const char* pszCompName = pParams->queryProp("pcName");
  1586. const char* pszSubType = pParams->queryProp("subType");
  1587. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  1588. const char* pszAttrName = pSetting->queryProp("@attrName");
  1589. const char* rowIndex = pSetting->queryProp("@rowIndex");
  1590. const char* pszOldValue = pSetting->queryProp("@oldValue");
  1591. const char* pszNewValue = pSetting->queryProp("@newValue");
  1592. StringBuffer xpath_key;
  1593. if (strcmp(pszAttrName,TAG_NAME) == 0)
  1594. {
  1595. xpath_key.appendf("%s/%s/%s[%s='%s']", XML_TAG_SOFTWARE, XML_TAG_TOPOLOGY, XML_TAG_CLUSTER, XML_ATTR_NAME, pszNewValue);
  1596. //Check to see if the cluster name is already in use
  1597. IPropertyTree* pEnvCluster = pEnvRoot->queryPropTree(xpath_key);
  1598. if (pEnvCluster != NULL)
  1599. throw MakeStringException(-1, "Cluster - %s is already in use. Please enter a unique name for the Cluster.", pszNewValue);
  1600. }
  1601. StringBuffer buf("Topology");
  1602. for (int i = 3; i >= 0; i--)
  1603. {
  1604. StringBuffer sb;
  1605. sb.appendf("inner%d_name", i);
  1606. const char* sbName = pParams->queryProp(sb.str());
  1607. if (sbName)
  1608. {
  1609. if (strstr(sbName, "EclCCServerProcess") == sbName ||
  1610. strstr(sbName, "EclServerProcess") == sbName ||
  1611. strstr(sbName, "EclAgentProcess") == sbName ||
  1612. strstr(sbName, "EclSchedulerProcess") == sbName)
  1613. {
  1614. StringBuffer sbEcl(sbName);
  1615. if (strstr(sbName, " - "))
  1616. sbEcl.replaceString(" - ", "[@process='").append("']");
  1617. else if (strstr(sbName, " -"))
  1618. sbEcl.replaceString(" -", "[@process='").append("']");
  1619. buf.append("/").append(sbEcl);
  1620. }
  1621. else if (strstr(sbName, "Cluster") == sbName)
  1622. {
  1623. StringBuffer sbCl(sbName);
  1624. if (strstr(sbName, " - "))
  1625. sbCl.replaceString(" - ", "[@name='").append("']");
  1626. else if (strstr(sbName, " -"))
  1627. sbCl.replaceString(" -", "[@name='").append("']");
  1628. buf.append("/").append(sbCl);
  1629. }
  1630. else if (strstr(sbName, XML_TAG_THORCLUSTER) == sbName)
  1631. buf.append("/ThorCluster");
  1632. else if (strstr(sbName, XML_TAG_ROXIECLUSTER) == sbName)
  1633. buf.append("/RoxieCluster");
  1634. else if (buf.str()[buf.length() - 1] != ']')
  1635. buf.appendf("[@%s='%s']", sbName, pParams->queryProp(sb.replaceString("_name", "_value").str()));
  1636. }
  1637. }
  1638. StringBuffer xpath;
  1639. xpath.appendf("%s[@name='%s']", pszCompType, pszCompName);
  1640. IPropertyTree* pComp = pEnvSoftware->queryPropTree(buf.str());
  1641. if (!pComp)
  1642. {
  1643. xpath.clear().appendf("*[@name='%s']", pszCompName);
  1644. Owned<IPropertyTreeIterator> iter = pEnvSoftware->getElements(xpath);
  1645. ForEach (*iter)
  1646. {
  1647. IPropertyTree* pTmpComp = &iter->query();
  1648. const char* pBldSet = pTmpComp->queryProp(XML_ATTR_BUILDSET);
  1649. if (pBldSet && !strcmp(pBldSet, pszCompType))
  1650. {
  1651. pComp = &iter->query();
  1652. break;
  1653. }
  1654. }
  1655. }
  1656. if (!pComp)
  1657. throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", pszCompType, pszCompName);
  1658. else
  1659. {
  1660. xpath.clear().appendf("@%s", pszAttrName);
  1661. pComp->setProp(xpath, pszNewValue);
  1662. resp.setUpdateValue(pszNewValue);
  1663. if (pszSubType && !strcmp(pszSubType, XML_TAG_INSTANCE) && !strcmp(pszAttrName, TAG_COMPUTER))
  1664. {
  1665. xpath.clear().appendf("Hardware/Computer[@name='%s']", pszNewValue);
  1666. IPropertyTree* pEnvComputer = pEnvRoot->queryPropTree(xpath);
  1667. if (pEnvComputer)
  1668. {
  1669. const char* pszNetAddr = pEnvComputer->queryProp(XML_ATTR_NETADDRESS);
  1670. if (pszNetAddr)
  1671. pComp->setProp(XML_ATTR_NETADDRESS, pszNetAddr);
  1672. }
  1673. }
  1674. }
  1675. resp.setIsSaved("true");
  1676. }
  1677. }
  1678. else if (pHardwareFolder)
  1679. {
  1680. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements("Setting[@category='Hardware']");
  1681. ForEach (*iter)
  1682. {
  1683. IPropertyTree* pSetting = &iter->query();
  1684. StringBuffer decodedParams( pSetting->queryProp("@params") );
  1685. decodedParams.replaceString("::", "\n");
  1686. Owned<IProperties> pParams = createProperties();
  1687. pParams->loadProps(decodedParams.str());
  1688. const char* pszCompType = pParams->queryProp("pcType");
  1689. const char* pszCompName = pParams->queryProp("pcName");
  1690. const char* pszSubType = pParams->queryProp("subType");
  1691. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  1692. const char* pszAttrName = pSetting->queryProp("@attrName");
  1693. const char* rowIndex = pSetting->queryProp("@rowIndex");
  1694. const char* pszOldValue = pSetting->queryProp("@oldValue");
  1695. const char* pszNewValue = pSetting->queryProp("@newValue");
  1696. //read anyupdates to rows that have not been updated
  1697. const char* pszUpdate = NULL;
  1698. int idx = 1;
  1699. StringBuffer sbUpdate;
  1700. while (true)
  1701. {
  1702. sbUpdate.clear().appendf("Update%dKey", idx);
  1703. const char* key = pParams->queryProp(sbUpdate.str());
  1704. if (!key)
  1705. break;
  1706. else if (!strcmp(key, "name") || !strcmp(key, "Name"))
  1707. {
  1708. sbUpdate.clear().appendf("Update%dValue", idx);
  1709. pszUpdate = pParams->queryProp(sbUpdate.str());
  1710. break;
  1711. }
  1712. idx++;
  1713. }
  1714. StringBuffer xpath;
  1715. if (pszSubType && pszSubTypeKey && strlen(pszSubTypeKey) > 0/* && !strcmp(pszSubType, "Instance")*/)
  1716. {
  1717. if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']')
  1718. xpath.appendf("%s%s", pszSubType, pszSubTypeKey);
  1719. else
  1720. xpath.clear().appendf("%s[@name='%s']", pszSubType, pszSubTypeKey);
  1721. }
  1722. else if (pszSubType && strlen(rowIndex) > 0/* && !strcmp(pszSubType, "Instance")*/)
  1723. xpath.clear().appendf("%s[%s]", pszSubType, rowIndex);
  1724. IPropertyTree* pComp = pEnvHardware->queryPropTree(xpath.str());
  1725. if (!pComp)
  1726. {
  1727. //check for any updates first
  1728. if (pszUpdate && pszSubType)
  1729. xpath.clear().appendf("%s[@name='%s']", pszSubType, pszUpdate);
  1730. pComp = pEnvHardware->queryPropTree(xpath.str());
  1731. if (!pComp)
  1732. {
  1733. xpath.clear().appendf("*[@name='%s']", pszCompName);
  1734. Owned<IPropertyTreeIterator> iter = pEnvHardware->getElements(xpath);
  1735. ForEach (*iter)
  1736. {
  1737. IPropertyTree* pTmpComp = &iter->query();
  1738. const char* pBldSet = pTmpComp->queryProp(XML_ATTR_BUILDSET);
  1739. if (pBldSet && !strcmp(pBldSet, pszCompType))
  1740. {
  1741. pComp = &iter->query();
  1742. break;
  1743. }
  1744. }
  1745. }
  1746. }
  1747. if (!pComp)
  1748. throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", pszCompType, pszCompName);
  1749. else
  1750. {
  1751. if (!strcmp(pszAttrName, "name"))
  1752. {
  1753. xpath.clear().appendf("%s["XML_ATTR_NAME"='%s']", pszSubType, pszNewValue);
  1754. if (pEnvHardware->queryPropTree(xpath.str()))
  1755. throw MakeStringException(-1, "Another item exists with the same name '%s'! Please specify a unique name.", pszNewValue);
  1756. }
  1757. xpath.clear().appendf("@%s", pszAttrName);
  1758. String strAttrName(pszAttrName);
  1759. StringBuffer encryptedText;
  1760. if (strAttrName.toLowerCase()->endsWith("password"))
  1761. {
  1762. encrypt(encryptedText, pszNewValue);
  1763. pszNewValue = encryptedText.str();
  1764. }
  1765. if (m_bCloud && !strcmp(pszAttrName, "netAddress"))
  1766. {
  1767. StringBuffer sb, sbMsg;
  1768. {
  1769. sb.clear().appendf("<Computers><Computer netAddress='%s'/></Computers>", pszNewValue);
  1770. Owned<IPropertyTree> pComputer = createPTreeFromXMLString(sb.str());
  1771. CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", pComputer);
  1772. bool ret = lockCloud.start(sbMsg.clear());
  1773. if (!ret || sbMsg.length())
  1774. throw MakeStringException(-1, "Cannot set netAddress as environment lock could not be obtained. Reason(s):\n%s", sbMsg.str());
  1775. }
  1776. if (pszOldValue && *pszOldValue)
  1777. {
  1778. sb.clear().appendf("<Computers><Computer netAddress='%s'/></Computers>", pszOldValue);
  1779. Owned<IPropertyTree> pComputer = createPTreeFromXMLString(sb.str());
  1780. CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", pComputer);
  1781. bool ret = unlockCloud.start(sbMsg.clear());
  1782. if (!ret || sbMsg.length())
  1783. {
  1784. //Unlock the new node.
  1785. {
  1786. sb.clear().appendf("<Computers><Computer netAddress='%s'/></Computers>", pszNewValue);
  1787. Owned<IPropertyTree> pComputer = createPTreeFromXMLString(sb.str());
  1788. CCloudActionHandler unlockPrevCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", pComputer);
  1789. ret = unlockPrevCloud.start(sbMsg.clear());
  1790. }
  1791. throw MakeStringException(-1, "Cannot set netAddress as some targets could not be unlocked. Reason(s):\n%s", sbMsg.str());
  1792. }
  1793. }
  1794. }
  1795. pComp->setProp(xpath, pszNewValue);
  1796. resp.setUpdateValue(pszNewValue);
  1797. //update references
  1798. if (!strcmp(pszAttrName, "name"))
  1799. {
  1800. if (!strcmp(pszSubType, XML_TAG_COMPUTER))
  1801. {
  1802. UpdateRefAttributes(pEnvRoot, XML_TAG_SOFTWARE"//*", XML_ATTR_COMPUTER, pszOldValue, pszNewValue);
  1803. UpdateRefAttributes(pEnvRoot, XML_TAG_SOFTWARE"/"XML_TAG_DALISERVERPROCESS, XML_ATTR_BACKUPCOMPUTER, pszOldValue, pszNewValue);
  1804. }
  1805. else if (!strcmp(pszSubType, XML_TAG_DOMAIN))
  1806. UpdateRefAttributes(pEnvRoot, XML_TAG_HARDWARE"/"XML_TAG_COMPUTER, XML_ATTR_DOMAIN, pszOldValue, pszNewValue);
  1807. else if (!strcmp(pszSubType, XML_TAG_SWITCH))
  1808. UpdateRefAttributes(pEnvRoot, XML_TAG_HARDWARE"/"XML_TAG_COMPUTER, XML_ATTR_SWITCH, pszOldValue, pszNewValue);
  1809. else if (!strcmp(pszSubType, XML_TAG_COMPUTERTYPE))
  1810. UpdateRefAttributes(pEnvRoot, XML_TAG_HARDWARE"/"XML_TAG_COMPUTER, XML_ATTR_COMPUTERTYPE, pszOldValue, pszNewValue);
  1811. }
  1812. else if (!strcmp(pszAttrName, "netAddress"))
  1813. {
  1814. Owned<IPropertyTreeIterator> iter = pEnvRoot->getElements(XML_TAG_SOFTWARE"//*");
  1815. for (iter->first(); iter->isValid(); iter->next())
  1816. {
  1817. IPropertyTree& node = iter->query();
  1818. const char* szVal = node.queryProp(XML_ATTR_COMPUTER);
  1819. const char* szComputer = pComp->queryProp(XML_ATTR_NAME);
  1820. if (szVal && strcmp(szVal, szComputer)==0)
  1821. {
  1822. if (node.hasProp(XML_ATTR_NETADDRESS))
  1823. node.setProp(XML_ATTR_NETADDRESS, pszNewValue);
  1824. }
  1825. }
  1826. }
  1827. if (pszSubType && !strcmp(pszSubType, XML_TAG_INSTANCE) && !strcmp(pszAttrName, TAG_COMPUTER))
  1828. {
  1829. xpath.clear().appendf("Hardware/Computer[@name='%s']", pszNewValue);
  1830. IPropertyTree* pEnvComputer = pEnvRoot->queryPropTree(xpath);
  1831. if (pEnvComputer)
  1832. {
  1833. const char* pszNetAddr = pEnvComputer->queryProp(XML_ATTR_NETADDRESS);
  1834. if (pszNetAddr)
  1835. pComp->setProp(XML_ATTR_NETADDRESS, pszNetAddr);
  1836. }
  1837. }
  1838. }
  1839. resp.setIsSaved("true");
  1840. }
  1841. }
  1842. else if (pEnvFolder)
  1843. {
  1844. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements("Setting[@category='Environment']");
  1845. ForEach (*iter)
  1846. {
  1847. IPropertyTree* pSetting = &iter->query();
  1848. StringBuffer decodedParams( pSetting->queryProp("@params") );
  1849. decodedParams.replaceString("::", "\n");
  1850. Owned<IProperties> pParams = createProperties();
  1851. pParams->loadProps(decodedParams.str());
  1852. const char* pszAttrName = pSetting->queryProp("@attrName");
  1853. const char* pszOldValue = pSetting->queryProp("@oldValue");
  1854. const char* pszNewValue = pSetting->queryProp("@newValue");
  1855. StringBuffer xpath;
  1856. const char* pszUpdate = NULL;
  1857. int idx = 1;
  1858. StringBuffer sbUpdate;
  1859. while (true)
  1860. {
  1861. sbUpdate.clear().appendf("Update%dKey", idx);
  1862. const char* key = pParams->queryProp(sbUpdate.str());
  1863. if (!key)
  1864. break;
  1865. else if (!strcmp(key, "name") || !strcmp(key, "Name"))
  1866. {
  1867. sbUpdate.clear().appendf("Update%dValue", idx);
  1868. pszUpdate = pParams->queryProp(sbUpdate.str());
  1869. break;
  1870. }
  1871. idx++;
  1872. }
  1873. const char* pszParams = NULL;
  1874. idx = 2;
  1875. StringBuffer sbParams;
  1876. StringBuffer sb;
  1877. bool flag = false;
  1878. const char* isAttr = pParams->queryProp("isAttr");
  1879. while (true)
  1880. {
  1881. sbParams.clear().appendf("parentParams%d", idx);
  1882. const char* val = pParams->queryProp(sbParams.str());
  1883. if (!val || !*val)
  1884. {
  1885. if (!flag)
  1886. flag = true;
  1887. else
  1888. {
  1889. if (pszUpdate)
  1890. {
  1891. sbParams.clear().appendf("parentParams%d", idx-2);
  1892. const char* val = pParams->queryProp(sbParams.str());
  1893. String st(val);
  1894. if (st.indexOf("pcName=") != -1)
  1895. sbParams.clear().append("[@name='").append(*st.substring(st.indexOf("pcName=") + 7)).append("']");
  1896. String str(xpath.str());
  1897. sb.clear().append(*str.substring(0, str.indexOf(sbParams.str())));
  1898. sb.appendf("[@name='%s']", pszUpdate);
  1899. xpath.clear().append(sb.str());
  1900. }
  1901. break;
  1902. }
  1903. idx++;
  1904. continue;
  1905. }
  1906. else
  1907. {
  1908. flag = false;
  1909. sb.clear();
  1910. StringBuffer params(val);
  1911. params.replaceString(":", "\n");
  1912. Owned<IProperties> pSubParams = createProperties();
  1913. pSubParams->loadProps(params.str());
  1914. sb.append(pSubParams->queryProp("pcType"));
  1915. if (sb.length())
  1916. xpath.append(xpath.length()?"/":"").append(sb.str());
  1917. sb.clear().append(pSubParams->queryProp("pcName"));
  1918. if (sb.length())
  1919. xpath.appendf("[@name='%s']", sb.str());
  1920. }
  1921. idx++;
  1922. }
  1923. IPropertyTree* pComp = pEnvRoot->queryPropTree(xpath.str());
  1924. if (pComp)
  1925. {
  1926. sb.clear();
  1927. if (!isAttr)
  1928. sb.append("@");
  1929. sb.append(pszAttrName);
  1930. pComp->setProp(sb.str(), pszNewValue);
  1931. resp.setUpdateValue(pszNewValue);
  1932. }
  1933. else
  1934. throw MakeStringException(-1, "Cannot find component/attribute in environment: '%s'.", pszAttrName);
  1935. }
  1936. }
  1937. return true;
  1938. }
  1939. bool CWsDeployFileInfo::getNavTreeDefn(IEspContext &context, IEspGetNavTreeDefnRequest &req, IEspGetNavTreeDefnResponse &resp)
  1940. {
  1941. synchronized block(m_mutex);
  1942. const char* xmlArg = req.getXmlArgs();
  1943. StringBuffer sbDefn, sb;
  1944. resp.setReadOnly("false");
  1945. bool doreload = true;
  1946. StringBuffer decodedParams(xmlArg);
  1947. decodedParams.replaceString("::", "\n");
  1948. Owned<IProperties> pParams = createProperties();
  1949. pParams->loadProps(decodedParams.str());
  1950. const char* reload = pParams->queryProp("reloadEnv");
  1951. StringBuffer sbName, sbUserIp;
  1952. sbName.clear().append(req.getReqInfo().getUserId());
  1953. context.getPeer(sbUserIp);
  1954. if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()) && reload && !strcmp(reload, "true"))
  1955. throw MakeStringException(-1, "Another browser window already has write access on machine '%s'. Please use that window.", sbUserIp.str());
  1956. if (m_pNavTree.get() == NULL)
  1957. m_pNavTree.setown(getEnvTree(context, &req.getReqInfo()));
  1958. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  1959. generateHeadersFromEnv(pEnvRoot, sbDefn);
  1960. resp.setCompDefn(sbDefn.str());
  1961. m_lastSaved.getString(sb.clear());
  1962. resp.setLastSaved(sb.str());
  1963. m_pService->getLastStarted(sb.clear());
  1964. resp.setLastStarted(sb.str());
  1965. return true;
  1966. }
  1967. bool CWsDeployFileInfo::lockEnvironmentForCloud(IEspContext &context, IEspLockEnvironmentForCloudRequest &req, IEspLockEnvironmentForCloudResponse &resp)
  1968. {
  1969. synchronized block(m_mutex);
  1970. const char* user = req.getUserName();
  1971. const char* ip = req.getIp();
  1972. if (!user || !*user || !ip || !*ip)
  1973. {
  1974. resp.setReturnCode(0);
  1975. resp.setMsg("User name or ip cannot be empty");
  1976. }
  1977. StringBuffer xml;
  1978. try
  1979. {
  1980. if (m_userWithLock.length() == 0)
  1981. {
  1982. StringBuffer sb;
  1983. StringBuffer sbUserIp;
  1984. context.getPeer(sbUserIp);
  1985. m_userWithLock.clear().append(user);
  1986. m_userIp.clear().append(sbUserIp);
  1987. Owned<IPropertyTree> pEnvRoot = &m_constEnvRdOnly->getPTree();
  1988. unsigned timeout = 60;
  1989. if (pEnvRoot)
  1990. timeout = pEnvRoot->getPropInt(XML_TAG_ENVSETTINGS"/brokenconntimeout", 60);
  1991. if (m_cloudLockerAliveThread && m_cloudLockerAliveThread.get() != NULL)
  1992. m_cloudLockerAliveThread.clear();
  1993. m_cloudLockerAliveThread.setown(new CLockerAliveThread(this, timeout * 60 * 1000, user, sbUserIp.str()));
  1994. m_cloudLockerAliveThread->init();
  1995. resp.setReturnCode(1);
  1996. resp.setMsg("");
  1997. }
  1998. else
  1999. {
  2000. xml.appendf("Write access to the Environment cannot be provided as it is currently being used on machine %s.", m_userIp.str());
  2001. resp.setMsg(xml.str());
  2002. resp.setReturnCode(0);
  2003. }
  2004. }
  2005. catch (IException* e)
  2006. {
  2007. StringBuffer sErrMsg;
  2008. e->errorMessage(sErrMsg);
  2009. e->Release();
  2010. char achHost[128] = "";
  2011. const char* p = strstr(sErrMsg.str(), "\n\n");
  2012. if (p && *(p+=2))
  2013. {
  2014. const char* q = strchr(p, ':');
  2015. if (q)
  2016. {
  2017. const int len = q-p;
  2018. strncpy(achHost, p, len);
  2019. achHost[len] = '\0';
  2020. }
  2021. }
  2022. unsigned int addr = inet_addr(achHost);
  2023. struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
  2024. if (hp)
  2025. strcpy(achHost, hp->h_name);
  2026. StringBuffer sMsg;
  2027. sMsg.appendf("Error accessing the environment definition");
  2028. if (achHost[0])
  2029. sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost);
  2030. else
  2031. sMsg.append(":\n\n").append(sErrMsg);
  2032. //throw MakeStringException(0, sMsg);
  2033. resp.setMsg(sMsg.str());
  2034. resp.setReturnCode(0);
  2035. }
  2036. return true;
  2037. }
  2038. bool CWsDeployFileInfo::unlockEnvironmentForCloud(IEspContext &context, IEspUnlockEnvironmentForCloudRequest &req, IEspUnlockEnvironmentForCloudResponse &resp)
  2039. {
  2040. synchronized block(m_mutex);
  2041. const char* user = req.getUserName();
  2042. const char* ip = req.getIp();
  2043. const char* newEnv = req.getNewEnvXml();
  2044. if (!user || !*user || !ip || !*ip)
  2045. {
  2046. resp.setReturnCode(0);
  2047. resp.setMsg("User name or ip cannot be empty");
  2048. }
  2049. StringBuffer xml, sbMsg;
  2050. int ret = 0;
  2051. try
  2052. {
  2053. if (!stricmp(m_userWithLock.str(), user) && !stricmp(m_userIp.str(), ip))
  2054. {
  2055. m_Environment.clear();
  2056. m_userWithLock.clear();
  2057. m_userIp.clear();
  2058. if (m_cloudLockerAliveThread)
  2059. {
  2060. m_cloudLockerAliveThread->signal();
  2061. m_cloudLockerAliveThread.clear();
  2062. }
  2063. Owned<IPropertyTree> pNavTree(getEnvTree(context, &req.getReqInfo()));
  2064. if (!areMatchingPTrees(pNavTree, m_pNavTree))
  2065. {
  2066. m_pEnvXml.clear();
  2067. m_pGraphXml.clear();
  2068. m_pNavTree.clear();
  2069. m_pNavTree.setown(getEnvTree(context, &req.getReqInfo()));
  2070. }
  2071. resp.setReturnCode(1);
  2072. resp.setMsg("");
  2073. }
  2074. else
  2075. {
  2076. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  2077. resp.setReturnCode(0);
  2078. resp.setMsg(xml.str());
  2079. }
  2080. }
  2081. catch (IException* e)
  2082. {
  2083. StringBuffer sErrMsg;
  2084. e->errorMessage(sErrMsg);
  2085. e->Release();
  2086. char achHost[128] = "";
  2087. const char* p = strstr(sErrMsg.str(), "\n\n");
  2088. if (p && *(p+=2))
  2089. {
  2090. const char* q = strchr(p, ':');
  2091. if (q)
  2092. {
  2093. const int len = q-p;
  2094. strncpy(achHost, p, len);
  2095. achHost[len] = '\0';
  2096. }
  2097. }
  2098. unsigned int addr = inet_addr(achHost);
  2099. struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
  2100. if (hp)
  2101. strcpy(achHost, hp->h_name);
  2102. StringBuffer sMsg;
  2103. sMsg.appendf("The environment definition in dali server "
  2104. "could not be opened for write access");
  2105. if (achHost[0])
  2106. sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost);
  2107. else
  2108. sMsg.append(":\n\n").append(sErrMsg);
  2109. resp.setReturnCode(0);
  2110. resp.setMsg(sMsg.str());
  2111. }
  2112. return true;
  2113. }
  2114. bool CWsDeployFileInfo::saveEnvironmentForCloud(IEspContext &context, IEspSaveEnvironmentForCloudRequest &req, IEspSaveEnvironmentForCloudResponse &resp)
  2115. {
  2116. synchronized block(m_mutex);
  2117. const char* user = req.getUserName();
  2118. const char* ip = req.getIp();
  2119. if (!user || !*user || !ip || !*ip)
  2120. {
  2121. resp.setReturnCode(0);
  2122. resp.setMsg("User name or ip cannot be empty");
  2123. }
  2124. StringBuffer xml;
  2125. try
  2126. {
  2127. if (m_userWithLock.length() == 0)
  2128. {
  2129. xml.appendf("Environment cannot be saved as it is not locked.");
  2130. resp.setMsg(xml.str());
  2131. resp.setReturnCode(0);
  2132. return false;
  2133. }
  2134. else if (stricmp(m_userWithLock.str(), user) || stricmp(m_userIp.str(), ip))
  2135. {
  2136. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  2137. resp.setReturnCode(0);
  2138. resp.setMsg(xml.str());
  2139. return false;
  2140. }
  2141. else
  2142. {
  2143. const char* newEnv = req.getNewEnv();
  2144. const char* newEnvId = req.getId();
  2145. m_cloudEnvId.clear().append(newEnvId);
  2146. if (!newEnv || !*newEnv)
  2147. {
  2148. resp.setReturnCode(0);
  2149. resp.setMsg("Input xml cannot be empty");
  2150. return false;
  2151. }
  2152. StringBuffer sbBackup;
  2153. setEnvironment(context, &req.getReqInfo(), newEnv, "SaveEnvironmentForCloud", sbBackup, false, false);
  2154. m_cloudEnvBkupFileName.clear().append(sbBackup);
  2155. resp.setReturnCode(1);
  2156. resp.setMsg("");
  2157. }
  2158. }
  2159. catch (IException* e)
  2160. {
  2161. StringBuffer sErrMsg;
  2162. e->errorMessage(sErrMsg);
  2163. e->Release();
  2164. resp.setMsg(sErrMsg.str());
  2165. resp.setReturnCode(0);
  2166. }
  2167. return true;
  2168. }
  2169. bool CWsDeployFileInfo::rollbackEnvironmentForCloud(IEspContext &context, IEspRollbackEnvironmentForCloudRequest &req, IEspRollbackEnvironmentForCloudResponse &resp)
  2170. {
  2171. synchronized block(m_mutex);
  2172. const char* user = req.getUserName();
  2173. const char* ip = req.getIp();
  2174. if (!user || !*user || !ip || !*ip)
  2175. {
  2176. resp.setReturnCode(0);
  2177. resp.setMsg("User name or ip cannot be empty");
  2178. }
  2179. StringBuffer xml;
  2180. try
  2181. {
  2182. if (m_userWithLock.length() == 0)
  2183. {
  2184. xml.appendf("Cannot rollback environment as it is not locked.");
  2185. resp.setMsg(xml.str());
  2186. resp.setReturnCode(0);
  2187. return false;
  2188. }
  2189. else if (stricmp(m_userWithLock.str(), user) || stricmp(m_userIp.str(), ip))
  2190. {
  2191. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  2192. resp.setReturnCode(0);
  2193. resp.setMsg(xml.str());
  2194. return false;
  2195. }
  2196. else
  2197. {
  2198. const char* newEnvId = req.getId();
  2199. if (newEnvId && *newEnvId && !strcmp(newEnvId, m_cloudEnvId.str()))
  2200. {
  2201. StringBuffer sbBackup;
  2202. Owned<IFile> pFile = createIFile(m_cloudEnvBkupFileName.str());
  2203. Owned<IFileIO> pFileIO = pFile->open(IFOreadwrite);
  2204. StringBuffer sbxml;
  2205. {
  2206. Owned <IPropertyTree> pTree = createPTree(*pFileIO);
  2207. toXML(pTree, sbxml);
  2208. setEnvironment(context, &req.getReqInfo(), sbxml, "RollbackEnvironmentForCloud", sbBackup);
  2209. }
  2210. resp.setReturnCode(1);
  2211. resp.setMsg("");
  2212. }
  2213. else
  2214. {
  2215. resp.setReturnCode(0);
  2216. resp.setMsg("Cannot rollback Environment as rollback id does not match");
  2217. return false;
  2218. }
  2219. }
  2220. }
  2221. catch (IException* e)
  2222. {
  2223. StringBuffer sErrMsg;
  2224. e->errorMessage(sErrMsg);
  2225. e->Release();
  2226. resp.setMsg(sErrMsg.str());
  2227. resp.setReturnCode(0);
  2228. }
  2229. return true;
  2230. }
  2231. bool CWsDeployFileInfo::notifyInitSystemSaveEnvForCloud(IEspContext &context, IEspNotifyInitSystemSaveEnvForCloudRequest &req, IEspNotifyInitSystemSaveEnvForCloudResponse &resp)
  2232. {
  2233. synchronized block(m_mutex);
  2234. const char* user = req.getUserName();
  2235. const char* ip = req.getIp();
  2236. if (!user || !*user || !ip || !*ip)
  2237. {
  2238. resp.setReturnCode(0);
  2239. resp.setMsg("User name or ip cannot be empty");
  2240. }
  2241. StringBuffer xml;
  2242. try
  2243. {
  2244. if (m_userWithLock.length() == 0)
  2245. {
  2246. xml.appendf("Cannot notify init system as the environment as it is not locked.");
  2247. resp.setMsg(xml.str());
  2248. resp.setReturnCode(0);
  2249. return false;
  2250. }
  2251. else if (stricmp(m_userWithLock.str(), user) || stricmp(m_userIp.str(), ip))
  2252. {
  2253. xml.appendf("The environment has been locked on machine '%s'", m_userIp.str());
  2254. resp.setReturnCode(0);
  2255. resp.setMsg(xml.str());
  2256. return false;
  2257. }
  2258. else
  2259. {
  2260. StringBuffer xpath;
  2261. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalConfFile", m_pService->getName());
  2262. const char* pConfFile = m_pService->getCfg()->queryProp(xpath.str());
  2263. if( pConfFile && *pConfFile)
  2264. {
  2265. Owned<IProperties> pParams = createProperties(pConfFile);
  2266. Owned<IPropertyIterator> iter = pParams->getIterator();
  2267. StringBuffer prop, out, err;
  2268. pParams->getProp("initSystemNotifyScript", prop);
  2269. if(prop.length())
  2270. runScript(out, err, prop.str());
  2271. resp.setMsg("");
  2272. resp.setReturnCode(1);
  2273. }
  2274. }
  2275. }
  2276. catch(IException* e)
  2277. {
  2278. throw e;
  2279. }
  2280. return true;
  2281. }
  2282. bool CWsDeployFileInfo::getValue(IEspContext &context, IEspGetValueRequest &req, IEspGetValueResponse &resp)
  2283. {
  2284. synchronized block(m_mutex);
  2285. StringBuffer decodedParams(req.getParams());
  2286. decodedParams.replaceString("::", "\n");
  2287. Owned<IProperties> pParams = createProperties();
  2288. pParams->loadProps(decodedParams.str());
  2289. const char* pszCategory = pParams->queryProp("category");
  2290. const char* pszBldSet = pParams->queryProp(TAG_BUILDSET);
  2291. const char* pszCompName = pParams->queryProp("compName");
  2292. const char* pszSubType = pParams->queryProp("subType");
  2293. const char* pszSubTypeName = pParams->queryProp("subTypeName");
  2294. const char* pszAttrName = pParams->queryProp("attrName");
  2295. const char* pszQueryType = pParams->queryProp("queryType");
  2296. const char* pszExcludePath = pParams->queryProp("excludePath");
  2297. const char* pszExcludeAttr = pParams->queryProp("excludeAttr");
  2298. const char* pszXpath = pParams->queryProp("xpath");
  2299. const char* pszparams = pParams->queryProp("params");
  2300. const char* pszAttrValue = pParams->queryProp("attrValue");
  2301. if (!pszCompName)
  2302. pszCompName = pParams->queryProp("pcName");
  2303. if (!pszBldSet)
  2304. pszBldSet = pParams->queryProp("pcType");
  2305. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  2306. StringBuffer xpath;
  2307. const char* pszValue;
  2308. StringBuffer sbMultiple;
  2309. if (pszQueryType && !strcmp(pszQueryType, "multiple"))
  2310. {
  2311. StringBuffer excludes;
  2312. //prepare exclude list
  2313. if (pszExcludePath && *pszExcludePath && pszExcludeAttr && *pszExcludeAttr)
  2314. {
  2315. if (pszCategory)
  2316. xpath.clear().append(pszCategory).append("/");
  2317. xpath.append(pszExcludePath);
  2318. Owned<IPropertyTreeIterator> pExcludes = pEnvRoot->getElements(xpath.str());
  2319. ForEach(*pExcludes)
  2320. {
  2321. IPropertyTree* pExclude = &pExcludes->query();
  2322. excludes.append(":").append(pExclude->queryProp(pszExcludeAttr)).append(":");
  2323. }
  2324. }
  2325. xpath.clear().append(pszCategory).append("/*");
  2326. if (pszBldSet)
  2327. xpath.appendf("[@buildSet='%s']", pszBldSet);
  2328. if (pszCompName)
  2329. xpath.appendf("[@name='%s']", pszCompName);
  2330. if (pszSubType)
  2331. xpath.appendf("/%s", pszSubType);
  2332. Owned<IPropertyTreeIterator> pComps = pEnvRoot->getElements(xpath.str());
  2333. xpath.clear().appendf("@%s", pszAttrName);
  2334. ForEach(*pComps)
  2335. {
  2336. IPropertyTree* pComp = &pComps->query();
  2337. String excl(excludes.str());
  2338. StringBuffer sb(":");
  2339. sb.append(pComp->queryProp(xpath.str())).append(":");
  2340. if (excl.indexOf(sb.str()) == -1)
  2341. sbMultiple.append(pComp->queryProp(xpath.str())).append(",");
  2342. }
  2343. if (sbMultiple.length())
  2344. sbMultiple.setLength(sbMultiple.length() - 1);
  2345. pszValue = sbMultiple.str();
  2346. }
  2347. else if (pszQueryType && !strcmp(pszQueryType, "xpathType") && pszXpath && *pszXpath)
  2348. {
  2349. StringBuffer sb;
  2350. sbMultiple.clear().append("");
  2351. xpath.clear().appendf("./Software/%s[@name=\"%s\"]", pszBldSet, pszCompName);
  2352. IPropertyTree* pNode = pEnvRoot->queryPropTree(xpath.str());
  2353. if (!pNode)
  2354. {
  2355. xpath.clear().appendf("./Software/*[@buildSet=\"%s\"][@name=\"%s\"]", pszBldSet, pszCompName);
  2356. pNode = pEnvRoot->queryPropTree(xpath.str());
  2357. }
  2358. if (pNode)
  2359. {
  2360. substituteParameters(pEnvRoot, pszXpath, pNode, sb);
  2361. const char* szPath = sb.str();
  2362. const char* buildSet = NULL;
  2363. if (!strncmp(szPath, "$process", 8))
  2364. {
  2365. if (!pNode)
  2366. return false;
  2367. szPath += strlen("$process");
  2368. if (*szPath == '\0')
  2369. {
  2370. const char* szName = pNode->queryProp("@name");
  2371. if (szName && *szName)
  2372. sbMultiple.append(",").append(szName);
  2373. pszValue = sbMultiple.str();
  2374. return true;
  2375. }
  2376. szPath++; //skip over '/'
  2377. }
  2378. else
  2379. {
  2380. if (pNode && !strcmp(szPath, "Programs/Build"))
  2381. buildSet = pNode->queryProp("@buildSet");
  2382. if (!pNode)
  2383. pNode = pEnvRoot;
  2384. }
  2385. String str(szPath);
  2386. Owned<IPropertyTreeIterator> iter;
  2387. if (str.startsWith(XML_TAG_SOFTWARE) ||
  2388. str.startsWith(XML_TAG_HARDWARE) ||
  2389. str.startsWith(XML_TAG_PROGRAMS))
  2390. iter.setown(pEnvRoot->getElements(szPath));
  2391. else
  2392. iter.setown(pNode->getElements(szPath));
  2393. ForEach(*iter)
  2394. {
  2395. IPropertyTree* pChildNode = &iter->query();
  2396. const char* szName = pChildNode->queryProp(XML_ATTR_NAME);
  2397. if (szName)
  2398. {
  2399. bool bAdd;
  2400. if (buildSet)
  2401. {
  2402. StringBuffer xpath;
  2403. xpath.appendf("BuildSet[@name='%s']", buildSet);
  2404. bAdd = pChildNode->queryPropTree(xpath.str()) != NULL;
  2405. }
  2406. else
  2407. bAdd = true;
  2408. if (bAdd)
  2409. sbMultiple.append(",").append(szName);
  2410. }
  2411. }
  2412. }
  2413. pszValue = sbMultiple.str();
  2414. }
  2415. else if(pszQueryType && !strcmp(pszQueryType, "customType"))
  2416. {
  2417. sbMultiple.clear();
  2418. if(pszparams && *pszparams)
  2419. {
  2420. StringArray sArray;
  2421. sArray.appendList(pszparams, ",");
  2422. for(unsigned i = 0; i < sArray.ordinality() ; i++)
  2423. {
  2424. if(!strcmp(sArray.item(i), "checklock"))
  2425. {
  2426. StringBuffer sbName, sbUserIp, msg;
  2427. sbName.clear().append(req.getReqInfo().getUserId());
  2428. context.getPeer(sbUserIp);
  2429. if(m_userWithLock.length())
  2430. {
  2431. if (strcmp(sbName.str(), m_userWithLock.str()) || strcmp(sbUserIp.str(), m_userIp.str()))
  2432. sbMultiple.append(sArray.item(i)).append("=").append("Cannot get access to Wizard mode as Environment is currently being configured in wizard mode on machine ").append(m_userIp.str());
  2433. else if(!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(),m_userIp.str()))
  2434. sbMultiple.append(sArray.item(i)).append("=").append("Another browser window already has write access on machine ").append(m_userIp.str()).append(".Please use that window.");
  2435. else
  2436. sbMultiple.append(sArray.item(i)).append("=''");
  2437. if(sbMultiple.length())
  2438. sbMultiple.append(",");
  2439. }
  2440. }
  2441. else if(!strcmp(sArray.item(i), "lastsaved"))
  2442. {
  2443. StringBuffer lastSaved;
  2444. m_lastSaved.getString(lastSaved);
  2445. if(lastSaved.length())
  2446. sbMultiple.append(sArray.item(i)).append("=").append(lastSaved);
  2447. else
  2448. sbMultiple.append(sArray.item(i)).append("=''");
  2449. if(sbMultiple.length())
  2450. sbMultiple.append(",");
  2451. }
  2452. }
  2453. }
  2454. pszValue = sbMultiple.str();
  2455. }
  2456. else if(pszQueryType && !strcmp(pszQueryType, "DomainsAndComputerTypes"))
  2457. {
  2458. xpath.clear().append(XML_TAG_HARDWARE"/"XML_TAG_DOMAIN);
  2459. sbMultiple.append("<Domains>");
  2460. bool flag = false;
  2461. Owned<IPropertyTreeIterator> pDomains = pEnvRoot->getElements(xpath.str());
  2462. ForEach(*pDomains)
  2463. {
  2464. IPropertyTree* pDomain = &pDomains->query();
  2465. sbMultiple.append(pDomain->queryProp(XML_ATTR_NAME)).append(",");
  2466. flag = true;
  2467. }
  2468. if (flag)
  2469. sbMultiple.setLength(sbMultiple.length() - 1);
  2470. sbMultiple.append("</Domains>");
  2471. flag = false;
  2472. xpath.clear().append(XML_TAG_HARDWARE"/"XML_TAG_COMPUTERTYPE);
  2473. sbMultiple.append("<ComputerTypes>");
  2474. Owned<IPropertyTreeIterator> pCTypes = pEnvRoot->getElements(xpath.str());
  2475. ForEach(*pCTypes)
  2476. {
  2477. IPropertyTree* pCType = &pCTypes->query();
  2478. sbMultiple.append(pCType->queryProp(XML_ATTR_NAME)).append(",");
  2479. flag = true;
  2480. }
  2481. if (flag)
  2482. sbMultiple.setLength(sbMultiple.length() - 1);
  2483. sbMultiple.append("</ComputerTypes>");
  2484. pszValue = sbMultiple.str();
  2485. }
  2486. else
  2487. {
  2488. if (pszCategory)
  2489. xpath.append(pszCategory);
  2490. if (pszBldSet)
  2491. xpath.append("/").append(pszBldSet);
  2492. if (pszCompName)
  2493. xpath.appendf("["XML_ATTR_NAME"='%s']", pszCompName);
  2494. if (pszSubType)
  2495. xpath.append("/").append(pszSubType);
  2496. if (pszSubTypeName)
  2497. xpath.appendf("["XML_ATTR_NAME"='%s']", pszSubTypeName);
  2498. if (pszAttrName)
  2499. xpath.appendf("/@%s", pszAttrName);
  2500. pszValue = pEnvRoot->queryProp(xpath.str());
  2501. }
  2502. resp.setReqValue(pszValue);
  2503. resp.setStatus("true");
  2504. return true;
  2505. }
  2506. bool CWsDeployFileInfo::unlockUser(IEspContext &context, IEspUnlockUserRequest &req, IEspUnlockUserResponse &resp)
  2507. {
  2508. synchronized block(m_mutex);
  2509. resp.setStatus("false");
  2510. StringBuffer sbName, sbUserIp;
  2511. sbName.clear().append(req.getReqInfo().getUserId());
  2512. context.getPeer(sbUserIp);
  2513. if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()))
  2514. {
  2515. m_userWithLock.clear();
  2516. m_userIp.clear();
  2517. resp.setStatus("true");
  2518. }
  2519. else
  2520. return false;
  2521. return true;
  2522. }
  2523. bool CWsDeployFileInfo::clientAlive(IEspContext &context, IEspClientAliveRequest &req, IEspClientAliveResponse &resp)
  2524. {
  2525. StringBuffer sbName, sbUserIp;
  2526. sbName.clear().append(req.getReqInfo().getUserId());
  2527. context.getPeer(sbUserIp);
  2528. StringBuffer sb(sbName);
  2529. sb.append(sbUserIp);
  2530. if (getConfigChanged() == true)
  2531. {
  2532. updateConfigFromFile();
  2533. setConfigChanged(false);
  2534. }
  2535. if (!strcmp(sbName.str(), m_userWithLock.str()) && !strcmp(sbUserIp.str(), m_userIp.str()))
  2536. {
  2537. CClientAliveThread* pClientAliveThread = m_keepAliveHTable.getValue(sb.str());
  2538. if (pClientAliveThread)
  2539. pClientAliveThread->signal();
  2540. }
  2541. m_lastSaved.getString(sb.clear());
  2542. resp.setLastSaved(sb.str());
  2543. m_pService->getLastStarted(sb.clear());
  2544. resp.setLastStarted(sb.str());
  2545. return true;
  2546. }
  2547. bool CWsDeployFileInfo::getEnvironment(IEspContext &context, IEspGetEnvironmentRequest &req, IEspGetEnvironmentResponse &resp)
  2548. {
  2549. synchronized block(m_mutex);
  2550. StringBuffer sb;
  2551. if (m_pFileIO.get())
  2552. {
  2553. Owned <IPropertyTree> pTree = createPTree(*m_pFileIO);
  2554. toXML(pTree, sb);
  2555. resp.setEnvXml(sb.str());
  2556. }
  2557. return true;
  2558. }
  2559. bool CWsDeployFileInfo::setEnvironment(IEspContext &context, IEspSetEnvironmentRequest &req, IEspSetEnvironmentResponse &resp)
  2560. {
  2561. synchronized block(m_mutex);
  2562. const char* pszEnv = req.getEnvXml();
  2563. if (!pszEnv || !*pszEnv)
  2564. {
  2565. resp.setReturnCode(1);
  2566. resp.setErrorMsg("Input xml cannot be empty");
  2567. return false;
  2568. }
  2569. try
  2570. {
  2571. StringBuffer sbBackup;
  2572. setEnvironment(context, NULL, pszEnv, "SetEnvironment", sbBackup);
  2573. }
  2574. catch(IException* e)
  2575. {
  2576. resp.setReturnCode(2);
  2577. StringBuffer sb;
  2578. e->errorMessage(sb);
  2579. resp.setErrorMsg(sb.str());
  2580. throw e;
  2581. }
  2582. resp.setReturnCode(0);
  2583. return true;
  2584. }
  2585. void CWsDeployFileInfo::setEnvironment(IEspContext &context, IConstWsDeployReqInfo *reqInfo, const char* pszEnv, const char* fnName, StringBuffer& sbBackupName, bool validate, bool updateDali)
  2586. {
  2587. if (!pszEnv)
  2588. return;
  2589. try
  2590. {
  2591. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  2592. Owned<IConstEnvironment> constEnv = factory->loadLocalEnvironment(pszEnv);
  2593. Owned<IPropertyTree> pEnvRoot = createPTreeFromXMLString(pszEnv);
  2594. Owned<IPropertyTreeIterator> dalis = pEnvRoot->getElements("Software/DaliServerProcess/Instance");
  2595. if (validate)
  2596. validateEnv(constEnv);
  2597. if (updateDali && dalis && dalis->first())
  2598. updateDaliEnv(pEnvRoot);
  2599. //save and write to backup
  2600. StringBuffer sXML;
  2601. StringBuffer tmp;
  2602. StringBuffer dtStr;
  2603. CDateTime dt;
  2604. try
  2605. {
  2606. if (m_pFile.get())
  2607. {
  2608. StringBuffer sb;
  2609. if (!checkDirExists(m_pService->getBackupDir()))
  2610. recursiveCreateDirectory(m_pService->getBackupDir());
  2611. while(true)
  2612. {
  2613. String strEnvFile(m_envFile);
  2614. int idx = strEnvFile.lastIndexOf('/');
  2615. if (idx <= 0)
  2616. idx = strEnvFile.lastIndexOf('\\');
  2617. String* tmpstr = strEnvFile.substring(idx+1);
  2618. sb.clear().append(m_pService->getBackupDir()).append(PATHSEPCHAR).append(*tmpstr);
  2619. delete tmpstr;
  2620. dt.setNow();
  2621. tmp.clear();
  2622. dtStr.clear();
  2623. dt.getDateString(tmp, true);
  2624. tmp.append("_");
  2625. dt.getTimeString(tmp, true);
  2626. dtStr.append(".").append(tmp);
  2627. dtStr.replaceString("-","_");
  2628. dtStr.replaceString(":","_");
  2629. String ext(sb);
  2630. idx = ext.lastIndexOf(PATHSEPCHAR);
  2631. if(ext.indexOf('.', idx > 0 ? idx : 0) != -1)
  2632. sb.insert(ext.lastIndexOf('.'), dtStr.str());
  2633. else
  2634. sb.append(dtStr.str());
  2635. if (checkFileExists(sb))
  2636. continue;
  2637. else
  2638. {
  2639. Owned<IFile> pFile(createIFile(sb.str()));
  2640. copyFile(pFile, m_pFile, 0x100000);
  2641. sbBackupName.clear().append(sb);
  2642. break;
  2643. }
  2644. }
  2645. }
  2646. }
  2647. catch(IException* e)
  2648. {
  2649. //ignore any attempts to create the backup
  2650. e->Release();
  2651. }
  2652. if (!m_pFile.get())
  2653. m_pFile.setown(createIFile(m_envFile));
  2654. m_pFileIO.clear();
  2655. m_pFileIO.setown(m_pFile->open(IFOcreaterw));
  2656. dt.setNow();
  2657. dt.getString(tmp.clear());
  2658. StringBuffer sbUserWithLock, sbUserIp;
  2659. if (reqInfo)
  2660. sbUserWithLock.clear().append(reqInfo->getUserId());
  2661. context.getPeer(sbUserIp);
  2662. sXML.appendf("<"XML_HEADER">\n<!-- Set via %s call by %s from ip %s on %s -->\n", fnName, sbUserWithLock.str(), sbUserIp.str(), tmp.str());
  2663. toXML(pEnvRoot, sXML, 0, XML_SortTags | XML_Format);
  2664. m_pFileIO->write(0, sXML.length(), sXML.str());
  2665. m_lastSaved.clear();
  2666. m_lastSaved.setNow();
  2667. m_lastSaved.getString(tmp.clear());
  2668. initFileInfo(false);
  2669. m_pNavTree.setown(getEnvTree(context, reqInfo));
  2670. //reset the readonly tree
  2671. m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sXML.str()));
  2672. }
  2673. catch(IException* e)
  2674. {
  2675. throw e;
  2676. }
  2677. }
  2678. bool CWsDeployFileInfo::displaySettings(IEspContext &context, IEspDisplaySettingsRequest &req, IEspDisplaySettingsResponse &resp)
  2679. {
  2680. synchronized block(m_mutex);
  2681. if (m_pNavTree.get() == NULL)
  2682. {
  2683. resp.setComponent("Refresh");
  2684. resp.setXmlArgs("<Refresh flag=\"true\"/>");
  2685. return false;
  2686. }
  2687. const char* cmd = req.getCmd();
  2688. const char* xmlArg = req.getXmlArgs();
  2689. StringBuffer sbDefn, sbViewChildNodes, sbMultiRowNodes;
  2690. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  2691. Owned<IPropertyTree> pSettings = createPTree("Settings");
  2692. Owned<IPropertyTree> pParamTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  2693. IPropertyTree* pSoftwareFolder = pParamTree->queryPropTree("Component[@parent='Software']");
  2694. IPropertyTree* pBuildFolder = pParamTree->queryPropTree("Component[@name='Programs']");
  2695. IPropertyTree* pHardwareFolder = pParamTree->queryPropTree("Component[@name='Hardware']");
  2696. IPropertyTree* pBuildSet = pParamTree->queryPropTree(XML_TAG_BUILDSET);
  2697. IPropertyTree* pEnvSettings = pParamTree->queryPropTree("Component[@name='EnvSettings']");
  2698. IPropertyTree* pEnvironment = pParamTree->queryPropTree("Component[@name='Environment']");
  2699. if (pSoftwareFolder)
  2700. {
  2701. IPropertyTree* pEnvSoftware = pEnvRoot->queryPropTree(XML_TAG_SOFTWARE);
  2702. Owned<IPropertyTreeIterator> iter = pParamTree->getElements("Component[@parent='Software']", iptiter_sort);
  2703. ForEach (*iter)
  2704. {
  2705. IPropertyTree* pFolder = &iter->query();
  2706. const char* pszCompType = pFolder->queryProp("@compType");
  2707. const char* pszCompName = pFolder->queryProp(XML_ATTR_NAME);
  2708. StringBuffer xpath;
  2709. if (!strcmp(pszCompName, "Directories"))
  2710. xpath.append(pszCompName);
  2711. else
  2712. xpath.appendf("%s[@name='%s']", pszCompType, pszCompName);
  2713. IPropertyTree* pComp = pEnvSoftware->queryPropTree(xpath.str());
  2714. if (!pComp)
  2715. continue;
  2716. if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS))
  2717. xpath.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", pComp->queryProp(XML_ATTR_BUILDSET));
  2718. else
  2719. xpath.clear().appendf("./Programs/Build/BuildSet[@processName=\"%s\"]", pszCompType);
  2720. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpath.str());
  2721. buildSetIter->first();
  2722. IPropertyTree* pBuildSet = NULL;
  2723. if (buildSetIter->isValid())
  2724. pBuildSet = &buildSetIter->query();
  2725. else if (!strcmp(pszCompName, "Directories"))
  2726. {
  2727. pBuildSet = createPTree(XML_TAG_BUILDSET);
  2728. pBuildSet->addProp(XML_ATTR_NAME, pszCompName);
  2729. pBuildSet->addProp(XML_ATTR_SCHEMA, "directories.xsd");
  2730. pBuildSet->addProp(XML_ATTR_PROCESS_NAME, "Directories");
  2731. }
  2732. if (!pBuildSet)
  2733. throw MakeStringException(-1, "Cannot determine buildset for component in environment: '%s' named '%s'.", pszCompType, pszCompName);
  2734. const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  2735. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  2736. if ( m_pService->m_configHelper.isInBuildSet(pszCompType,buildSetName) == false )
  2737. {
  2738. throw MakeStringException(-1, "Component '%s' named '%s' not in build set. Component may be incompatible with the current version.", pszCompType, pszCompName);
  2739. }
  2740. StringBuffer buildSetPath;
  2741. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  2742. if (!strcmp(processName, XML_TAG_ESPSERVICE) || !strcmp(processName, XML_TAG_PLUGINPROCESS))
  2743. getDefnString(pEnvRoot, pSchema, pComp->queryProp(XML_ATTR_BUILDSET), sbDefn, sbViewChildNodes, sbMultiRowNodes);
  2744. else if (!strcmp(processName, XML_TAG_TOPOLOGY))
  2745. generateHeaderForTopology(pEnvRoot, sbDefn);
  2746. else
  2747. getDefnString(pEnvRoot, pSchema, processName, sbDefn, sbViewChildNodes, sbMultiRowNodes);
  2748. resp.setCompDefn(sbDefn.str());
  2749. resp.setViewChildNodes(sbViewChildNodes.str());
  2750. resp.setMultiRowNodes(sbMultiRowNodes.str());
  2751. StringBuffer xml;
  2752. toXML(pComp, xml, false);
  2753. xml.replaceString("\\","\\\\");
  2754. //add any missing parameters
  2755. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xml);
  2756. Owned<IPropertyTree> pNewCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName(), true, false, 0, true);
  2757. if (pNewCompTree)
  2758. {
  2759. StringBuffer sbxml;
  2760. toXML(pNewCompTree, sbxml);
  2761. Owned<IAttributeIterator> iAttr = pNewCompTree->getAttributes();
  2762. ForEach(*iAttr)
  2763. {
  2764. const char* attrName = iAttr->queryName();
  2765. if (!pSrcTree->hasProp(attrName))
  2766. {
  2767. pSrcTree->addProp(attrName, iAttr->queryValue());
  2768. const char* prop = "@_notInEnv";
  2769. StringBuffer sbVal;
  2770. if (pSrcTree->hasProp(prop))
  2771. sbVal.append(pSrcTree->queryProp(prop));
  2772. pSrcTree->setProp(prop, sbVal.append(";").append(attrName).append(";").str());
  2773. }
  2774. }
  2775. //Add subelements that occur only once
  2776. Owned<IPropertyTreeIterator> iterElems = pNewCompTree->getElements("*");
  2777. ForEach (*iterElems)
  2778. {
  2779. IPropertyTree* pElem = &iterElems->query();
  2780. Owned<IPropertyTreeIterator> srcElems = pSrcTree->getElements(pElem->queryName());
  2781. IPropertyTree* pSrcElem = NULL;
  2782. ForEach(*srcElems)
  2783. {
  2784. pSrcElem = &srcElems->query();
  2785. Owned<IAttributeIterator> iAttrElem = pElem->getAttributes();
  2786. ForEach(*iAttrElem)
  2787. {
  2788. const char* attrName = iAttrElem->queryName();
  2789. if (!pSrcElem->hasProp(attrName))
  2790. {
  2791. pSrcElem->addProp(attrName, iAttrElem->queryValue());
  2792. const char* prop = "@_notInEnv";
  2793. StringBuffer sbVal;
  2794. if (pSrcElem->hasProp(prop))
  2795. sbVal.append(pSrcElem->queryProp(prop));
  2796. pSrcElem->setProp(prop, sbVal.append(";").append(attrName).append(";").str());
  2797. }
  2798. }
  2799. Owned<IPropertyTreeIterator> iterSubElems = pElem->getElements("*");
  2800. ForEach (*iterSubElems)
  2801. {
  2802. IPropertyTree* pSubElem = &iterSubElems->query();
  2803. Owned<IPropertyTreeIterator> srcSubElems = pSrcElem->getElements(pSubElem->queryName());
  2804. IPropertyTree* pSrcSubElem = NULL;
  2805. ForEach(*srcSubElems)
  2806. {
  2807. pSrcSubElem = &srcSubElems->query();
  2808. Owned<IAttributeIterator> iAttrElem = pSubElem->getAttributes();
  2809. ForEach(*iAttrElem)
  2810. {
  2811. const char* attrName = iAttrElem->queryName();
  2812. if (!pSrcSubElem->hasProp(attrName))
  2813. pSrcSubElem->addProp(attrName, iAttrElem->queryValue());
  2814. }
  2815. }
  2816. if (!pSrcSubElem)
  2817. pSrcSubElem = pSrcElem->addPropTree(pSubElem->queryName(), createPTreeFromIPT(pSubElem));
  2818. }
  2819. }
  2820. }
  2821. Owned<IPropertyTreeIterator> iterNotes = pSrcTree->getElements("Notes");
  2822. ForEach (*iterNotes)
  2823. {
  2824. IPropertyTree* pNotes = &iterNotes->query();
  2825. Owned<IPropertyTreeIterator> iterNote = pNotes->getElements("Note");
  2826. ForEach (*iterNote)
  2827. {
  2828. IPropertyTree* pNote = &iterNote->query();
  2829. StringBuffer sbVal(pNotes->queryProp(pNote->queryName()));
  2830. sbVal.replaceString("\r\n", "&#13;&#10;");
  2831. pNotes->setProp(pNote->queryName(), sbVal.str());
  2832. }
  2833. }
  2834. xml.clear();
  2835. toXML(pSrcTree, xml, false);
  2836. }
  2837. if (!strcmp(pszCompType, "Directories"))
  2838. {
  2839. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xml);
  2840. Owned<IPropertyTreeIterator> iterCats = pSrcTree->getElements("Category");
  2841. ForEach (*iterCats)
  2842. {
  2843. IPropertyTree* pCat = &iterCats->query();
  2844. const char* pszName = pCat->queryProp(XML_ATTR_NAME);
  2845. if (!strcmp(pszName, "lock") || !strcmp(pszName, "run") || !strcmp(pszName, "conf"))
  2846. {
  2847. pSrcTree->removeTree(pCat);
  2848. (*iterCats).first();
  2849. }
  2850. else
  2851. {
  2852. IPropertyTree* pOver = pCat->queryPropTree("Override[1]");
  2853. if (!pOver)
  2854. pOver = pCat->addPropTree("Override", createPTree());
  2855. if (!pOver->queryProp("@component"))
  2856. pOver->addProp("@component", "");
  2857. if (!pOver->queryProp("@dir"))
  2858. pOver->addProp("@dir", "");
  2859. if (!pOver->queryProp("@instance"))
  2860. pOver->addProp("@instance", "");
  2861. }
  2862. }
  2863. xml.clear();
  2864. toXML(pSrcTree, xml, false);
  2865. }
  2866. else if (!strcmp(pszCompType, XML_TAG_THORCLUSTER))
  2867. {
  2868. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xml);
  2869. IPropertyTree* pTopoNode = pSrcTree->queryPropTree(XML_TAG_TOPOLOGY);
  2870. if (!pTopoNode)
  2871. {
  2872. pTopoNode = pSrcTree->addPropTree(XML_TAG_TOPOLOGY, createPTree());
  2873. IPropertyTree* pMaster = pSrcTree->queryPropTree(XML_TAG_THORMASTERPROCESS);
  2874. if (pMaster)
  2875. {
  2876. IPropertyTree* pMasterNode = createPTree(XML_TAG_NODE);
  2877. pMasterNode->addProp(XML_ATTR_PROCESS, pMaster->queryProp(XML_ATTR_NAME));
  2878. pTopoNode->addPropTree(XML_TAG_NODE, pMasterNode);
  2879. Owned<IPropertyTreeIterator> iterSlaves = pSrcTree->getElements(XML_TAG_THORSLAVEPROCESS);
  2880. ForEach (*iterSlaves)
  2881. {
  2882. IPropertyTree* pSlave = &iterSlaves->query();
  2883. IPropertyTree* pNode = createPTree(XML_TAG_NODE);
  2884. pNode->addProp(XML_ATTR_PROCESS, pSlave->queryProp(XML_ATTR_NAME));
  2885. pMasterNode->addPropTree(XML_TAG_NODE, pNode);
  2886. }
  2887. }
  2888. Owned<IPropertyTreeIterator> iterSpares = pSrcTree->getElements(XML_TAG_THORSPAREPROCESS);
  2889. ForEach (*iterSpares)
  2890. {
  2891. IPropertyTree* pSpare = &iterSpares->query();
  2892. IPropertyTree* pNode = createPTree(XML_TAG_NODE);
  2893. pNode->addProp(XML_ATTR_PROCESS, pSpare->queryProp(XML_ATTR_NAME));
  2894. pTopoNode->addPropTree(XML_TAG_NODE, pNode);
  2895. }
  2896. }
  2897. xpath.clear().append("Topology/Node");
  2898. Owned<IPropertyTreeIterator> iterMNodes = pSrcTree->getElements(xpath.str());
  2899. ForEach (*iterMNodes)
  2900. {
  2901. IPropertyTree* pMasterNode = &iterMNodes->query();
  2902. const char* pszMName = pMasterNode->queryProp(XML_ATTR_PROCESS);
  2903. pMasterNode->addProp("@_processId", pszMName);
  2904. if (pszMName)
  2905. {
  2906. xpath.clear().appendf(XML_TAG_THORMASTERPROCESS"/[@name='%s']", pszMName);
  2907. IPropertyTree* pMasterNodeTree = pComp->queryPropTree(xpath);
  2908. //if not master, then spare
  2909. if (!pMasterNodeTree)
  2910. {
  2911. xpath.clear().appendf(XML_TAG_THORSPAREPROCESS"/[@name='%s']", pszMName);
  2912. IPropertyTree* pSpareNodeTree = pComp->queryPropTree(xpath);
  2913. const char* pszComputer = pSpareNodeTree->queryProp(XML_ATTR_COMPUTER);
  2914. if (pszComputer)
  2915. {
  2916. xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer);
  2917. IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str());
  2918. const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS);
  2919. if (pszNetAddr)
  2920. pMasterNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr);
  2921. pMasterNode->addProp(XML_ATTR_NAME, pszComputer);
  2922. pMasterNode->addProp(XML_ATTR_PROCESS, "Spare");
  2923. }
  2924. }
  2925. else
  2926. {
  2927. const char* pszComputer = pMasterNodeTree->queryProp(XML_ATTR_COMPUTER);
  2928. if (pszComputer)
  2929. {
  2930. xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer);
  2931. IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str());
  2932. if (pComputer == NULL)
  2933. throw MakeStringException(-1, "XPATH: %s is invalid. (Did you add the Hardware?)",xpath.str());
  2934. const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS);
  2935. if (pszNetAddr)
  2936. pMasterNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr);
  2937. pMasterNode->addProp(XML_ATTR_NAME, pszComputer);
  2938. pMasterNode->addProp(XML_ATTR_PROCESS, "Master");
  2939. }
  2940. xpath.clear().appendf("Node");
  2941. Owned<IPropertyTreeIterator> iterSNodes = pMasterNode->getElements(xpath);
  2942. ForEach (*iterSNodes)
  2943. {
  2944. IPropertyTree* pSlaveNode = &iterSNodes->query();
  2945. const char* pszSName = pSlaveNode->queryProp(XML_ATTR_PROCESS);
  2946. pSlaveNode->addProp("@_processId", pszSName);
  2947. if (pszMName)
  2948. {
  2949. xpath.clear().appendf("ThorSlaveProcess/[@name='%s']", pszSName);
  2950. IPropertyTree* pSlaveNodeTree = pSrcTree->queryPropTree(xpath);
  2951. const char* pszComputer = pSlaveNodeTree->queryProp(XML_ATTR_COMPUTER);
  2952. if (pszComputer)
  2953. {
  2954. xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer);
  2955. IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str());
  2956. const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS);
  2957. if (pszNetAddr)
  2958. pSlaveNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr);
  2959. pSlaveNode->addProp(XML_ATTR_NAME, pszComputer);
  2960. pSlaveNode->addProp(XML_ATTR_PROCESS, "Slave");
  2961. }
  2962. }
  2963. }
  2964. }
  2965. }
  2966. }
  2967. xml.clear();
  2968. toXML(pSrcTree, xml, false);
  2969. }
  2970. else if (!strcmp(pszCompType, "RoxieCluster"))
  2971. {
  2972. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xml);
  2973. pNewCompTree.setown(generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName()));
  2974. if (!strcmp(pszCompType, "RoxieCluster"))
  2975. {
  2976. xpath.clear().append("RoxieFarmProcess/RoxieServerProcess");
  2977. Owned<IPropertyTreeIterator> iterRoxieServers = pSrcTree->getElements(xpath.str());
  2978. ForEach (*iterRoxieServers )
  2979. {
  2980. IPropertyTree* pRoxieServer = &iterRoxieServers->query();
  2981. const char* pszComputer = pRoxieServer->queryProp(XML_ATTR_COMPUTER);
  2982. if (pszComputer)
  2983. {
  2984. xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer);
  2985. IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str());
  2986. const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS);
  2987. if (pszNetAddr)
  2988. pRoxieServer->addProp(XML_ATTR_NETADDRESS, pszNetAddr);
  2989. }
  2990. }
  2991. xpath.clear().append(XML_TAG_ROXIE_ONLY_SLAVE);
  2992. Owned<IPropertyTreeIterator> iterSlaves = pSrcTree->getElements(xpath.str());
  2993. ForEach (*iterSlaves)
  2994. {
  2995. IPropertyTree* pRoxieSlave = &iterSlaves->query();
  2996. const char* pszComputer = pRoxieSlave->queryProp(XML_ATTR_COMPUTER);
  2997. if (pszComputer)
  2998. {
  2999. xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer);
  3000. IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str());
  3001. const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS);
  3002. if (pszNetAddr)
  3003. pRoxieSlave->addProp(XML_ATTR_NETADDRESS, pszNetAddr);
  3004. }
  3005. }
  3006. }
  3007. if (pSrcTree->hasProp("ACL"))
  3008. {
  3009. Owned<IPropertyTreeIterator> iterACL = pSrcTree->getElements("ACL");
  3010. ForEach (*iterACL)
  3011. {
  3012. IPropertyTree* pAcl = &iterACL->query();
  3013. if (!pAcl->queryPropTree("Access") && pNewCompTree->queryPropTree("Access"))
  3014. {
  3015. IPropertyTree* pAccess = pAcl->addPropTree("Access", createPTreeFromIPT(pNewCompTree->queryPropTree("Access")));
  3016. Owned<IAttributeIterator> iAttrElem = pNewCompTree->queryPropTree("Access")->getAttributes();
  3017. ForEach(*iAttrElem)
  3018. {
  3019. const char* attrName = iAttrElem->queryName();
  3020. pAccess->setProp(attrName, "");
  3021. }
  3022. }
  3023. if (!pAcl->queryPropTree("BaseList") && pNewCompTree->queryPropTree("BaseList"))
  3024. {
  3025. IPropertyTree* pBaseList = pAcl->addPropTree("BaseList", createPTreeFromIPT(pNewCompTree->queryPropTree("BaseList")));
  3026. Owned<IAttributeIterator> iAttrElem = pNewCompTree->queryPropTree("BaseList")->getAttributes();
  3027. ForEach(*iAttrElem)
  3028. {
  3029. const char* attrName = iAttrElem->queryName();
  3030. pBaseList->setProp(attrName, "");
  3031. }
  3032. }
  3033. }
  3034. }
  3035. xml.clear();
  3036. toXML(pSrcTree, xml, false);
  3037. xml.replaceString("<RoxieFarmProcess ", "<RoxieFarmProcess process=\"Farm\" ");
  3038. xml.replaceString("<RoxieServerProcess ", "<RoxieServerProcess process=\"Server\" ");
  3039. xml.replaceString("<RoxieSlave ", "<RoxieSlave itemType=\"Roxie Agent\" ");
  3040. xml.replaceString("<RoxieChannel ", "<RoxieChannel itemType=\"Channel\" ");
  3041. }
  3042. else if (!strcmp(pszCompType, XML_TAG_ESPPROCESS))
  3043. {
  3044. Owned<IPropertyTree> pTree = createPTreeFromXMLString(xml);
  3045. Owned<IPropertyTreeIterator> iterBindings = pTree->getElements(XML_TAG_ESPBINDING);
  3046. ForEach (*iterBindings)
  3047. {
  3048. IPropertyTree* pBinding = &iterBindings->query();
  3049. bool flag = false;
  3050. Owned<IPropertyTreeIterator> iterUrl = pBinding->getElements("AuthenticateFeature");
  3051. ForEach (*iterUrl)
  3052. {
  3053. flag = true;
  3054. break;
  3055. }
  3056. if (!flag)
  3057. {
  3058. IPropertyTree* pAuthFeature = pBinding->addPropTree( "AuthenticateFeature", createPTree() );
  3059. pAuthFeature->addProp("@authenticate", "");
  3060. pAuthFeature->addProp("@description", "");
  3061. pAuthFeature->addProp("@path", "");
  3062. pAuthFeature->addProp("@resource", "");
  3063. pAuthFeature->addProp("@service", "");
  3064. }
  3065. flag = false;
  3066. Owned<IPropertyTreeIterator> iterFeature = pBinding->getElements("Authenticate");
  3067. ForEach (*iterFeature)
  3068. {
  3069. flag = true;
  3070. break;
  3071. }
  3072. if (!flag)
  3073. {
  3074. IPropertyTree* pAuth = pBinding->addPropTree( "Authenticate", createPTree() );
  3075. pAuth->addProp("@access", "");
  3076. pAuth->addProp("@description", "");
  3077. pAuth->addProp("@method", "");
  3078. pAuth->addProp("@path", "");
  3079. pAuth->addProp("@resource", "");
  3080. }
  3081. }
  3082. Owned<IPropertyTreeIterator> iterInst = pTree->getElements(XML_TAG_INSTANCE);
  3083. ForEach (*iterInst)
  3084. {
  3085. IPropertyTree* pInst = &iterInst->query();
  3086. Owned<IPropertyTreeIterator> iterNode = pInst->getElements("*");
  3087. if (iterNode->first() && iterNode->isValid())
  3088. {
  3089. ForEach (*iterNode)
  3090. {
  3091. IPropertyTree* pNode = &iterNode->query();
  3092. if (!strcmp(pNode->queryName(), "CSR") || !strcmp(pNode->queryName(), "Certificate") || !strcmp(pNode->queryName(), "PrivateKey"))
  3093. {
  3094. StringBuffer sbVal(pInst->queryProp(pNode->queryName()));
  3095. sbVal.replaceString("\r\n", "&#13;&#10;");
  3096. pInst->setProp(pNode->queryName(), sbVal.str());
  3097. }
  3098. }
  3099. }
  3100. if (!pInst->hasProp("CSR"))
  3101. pInst->addPropTree("CSR", createPTree());
  3102. if (!pInst->hasProp("Certificate"))
  3103. pInst->addPropTree("Certificate", createPTree());
  3104. if (!pInst->hasProp("PrivateKey"))
  3105. pInst->addPropTree("PrivateKey", createPTree());
  3106. }
  3107. xml.clear();
  3108. toXML(pTree, xml, false);
  3109. }
  3110. const char* pszBldSet = pComp->queryProp(XML_ATTR_BUILDSET);
  3111. if (strcmp(pszCompName, "Directories") && !pszBldSet)
  3112. throw MakeStringException(-1, "Cannot determine buildset for component in environment: '%s' named '%s'.", pszCompType, pszCompName);
  3113. if (!strcmp(pszCompType, XML_TAG_ESPSERVICE) || !strcmp(pszCompType, XML_TAG_PLUGINPROCESS))
  3114. resp.setComponent(pszBldSet);
  3115. else
  3116. resp.setComponent(pszCompType);
  3117. resp.setXmlArgs( xml.str() );
  3118. }
  3119. }
  3120. else if (pHardwareFolder)
  3121. {
  3122. IPropertyTree* pEnvHardware = pEnvRoot->queryPropTree(XML_TAG_HARDWARE);
  3123. generateHardwareHeaders(pEnvRoot, sbDefn);
  3124. resp.setCompDefn(sbDefn.str());
  3125. StringBuffer sb;
  3126. Owned<IPropertyTree> multiRowNodes = createPTree("multiRowNodes");
  3127. multiRowNodes->addProp("Node", "ComputerType");
  3128. multiRowNodes->addProp("Node", "Domain");
  3129. multiRowNodes->addProp("Node", "Computer");
  3130. multiRowNodes->addProp("Node", "Switch");
  3131. toXML(multiRowNodes, sb);
  3132. resp.setMultiRowNodes(sb.str());
  3133. StringBuffer xml;
  3134. toXML(pEnvHardware, xml, false);
  3135. xml.replaceString("switch=","Switch=");
  3136. //add any missing parameters
  3137. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xml);
  3138. StringBuffer sbTemp;
  3139. Owned<IPropertyTree> pNewCompTree = createPTree(XML_TAG_HARDWARE);
  3140. generateHardwareHeaders(pEnvRoot, sbTemp, false, pNewCompTree);
  3141. const char* pElemNames[] = {XML_TAG_COMPUTER};
  3142. bool modified = false;
  3143. for (int i = 0; i < sizeof(pElemNames)/sizeof(char*); i++)
  3144. {
  3145. IPropertyTree* pSrcElem = pNewCompTree->queryPropTree(pElemNames[i]);
  3146. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements(pElemNames[i]);
  3147. ForEach (*iter)
  3148. {
  3149. IPropertyTree* pElem = &iter->query();
  3150. Owned<IAttributeIterator> iAttr = pSrcElem->getAttributes();
  3151. ForEach(*iAttr)
  3152. {
  3153. const char* attrName = iAttr->queryName();
  3154. if (strcmp(attrName, "@state") && strcmp(attrName, "@switch") &&!pElem->hasProp(attrName))
  3155. {
  3156. pElem->addProp(attrName, iAttr->queryValue());
  3157. modified = true;
  3158. }
  3159. }
  3160. }
  3161. }
  3162. if (modified)
  3163. {
  3164. xml.clear();
  3165. toXML(pSrcTree, xml, false);
  3166. }
  3167. resp.setComponent(XML_TAG_HARDWARE);
  3168. resp.setXmlArgs( xml.str() );
  3169. }
  3170. else if (pBuildFolder)
  3171. {
  3172. IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS);
  3173. generateBuildHeaders(pEnvRoot, true, sbDefn, false);
  3174. resp.setCompDefn(sbDefn.str());
  3175. StringBuffer xml;
  3176. toXML(pEnvPrograms, xml, false);
  3177. xml.replaceString(" url="," path=");
  3178. resp.setComponent(XML_TAG_PROGRAMS);
  3179. resp.setXmlArgs( xml.str() );
  3180. }
  3181. else if (pBuildSet)
  3182. {
  3183. generateBuildHeaders(pEnvRoot, false, sbDefn, false);
  3184. resp.setCompDefn(sbDefn.str());
  3185. IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS);
  3186. Owned<IPropertyTreeIterator> iter = pParamTree->getElements(XML_TAG_BUILDSET);
  3187. ForEach (*iter)
  3188. {
  3189. IPropertyTree* pFolder = &iter->query();
  3190. const char* pszBuild = pFolder->queryProp(XML_ATTR_BUILD);
  3191. const char* pszBuildPath = pFolder->queryProp("@buildpath");
  3192. const char* pszBuildSet = pFolder->queryProp(XML_ATTR_NAME);
  3193. const char* pszBuildSetPath = pFolder->queryProp("@path");
  3194. StringBuffer xpath;
  3195. xpath.appendf("Build[@name='%s']/BuildSet[@name='%s']", pszBuild, pszBuildSet);
  3196. IPropertyTree* pComp = pEnvPrograms->queryPropTree(xpath.str());
  3197. if (!pComp)
  3198. throw MakeStringException(-1, "No such build and buildset in environment: '%s' named '%s'.", pszBuild, pszBuildSet);
  3199. StringBuffer s;
  3200. s.append("./Programs/Build[@name=\"").append(pszBuild).append("\"]");
  3201. IPropertyTree *b = pEnvRoot->queryPropTree(s.str());
  3202. IPropertyTree *bs = NULL;
  3203. IPropertyTree* pParentNode = NULL;
  3204. IPropertyTree* pFiles = NULL;
  3205. if (b)
  3206. {
  3207. s.clear().append("BuildSet[@name=\"").append(pszBuildSet).append("\"]");
  3208. bs = b->queryPropTree(s.str());
  3209. StringBuffer fileName;
  3210. connectBuildSet(b, bs, fileName, m_Environment);
  3211. fileName.append(bs->queryProp("@installSet"));
  3212. pParentNode = createPTreeFromXMLFile(fileName.str());
  3213. pFiles = pParentNode->queryPropTree("File");
  3214. }
  3215. StringBuffer xml;
  3216. toXML(pFiles, xml, false);
  3217. resp.setComponent(XML_TAG_BUILDSET);
  3218. resp.setXmlArgs( xml.str() );
  3219. }
  3220. }
  3221. else if (pEnvSettings)
  3222. {
  3223. IPropertyTree* pEnvSettings = pEnvRoot->queryPropTree("EnvSettings");
  3224. generateHeadersForEnvSettings(pEnvRoot, sbDefn);
  3225. resp.setCompDefn(sbDefn.str());
  3226. StringBuffer xml;
  3227. toXML(pEnvSettings, xml, false);
  3228. resp.setComponent("EnvSettings");
  3229. resp.setXmlArgs( xml.str() );
  3230. }
  3231. else if (pEnvironment)
  3232. {
  3233. generateHeadersForEnvXmlView(pEnvRoot, sbDefn);
  3234. resp.setCompDefn(sbDefn.str());
  3235. StringBuffer xml;
  3236. toXML(pEnvRoot, xml, false);
  3237. resp.setComponent("Environment");
  3238. resp.setXmlArgs( xml.str() );
  3239. }
  3240. return true;
  3241. }
  3242. bool CWsDeployFileInfo::startDeployment(IEspContext &context, IEspStartDeploymentRequest &req, IEspStartDeploymentResponse &resp)
  3243. {
  3244. synchronized block(m_mutex);
  3245. checkForRefresh(context, &req.getReqInfo(), true);
  3246. const char* selComps = req.getSelComps();
  3247. CDeployOptions& depOptions = dynamic_cast<CDeployOptions&>(req.getOptions());
  3248. CDeployInfo depInfo("wsDeploy", "true");
  3249. StringBuffer deployResult;
  3250. CWsDeployEngine depEngine(*m_pService, &context, depInfo, selComps, 2);
  3251. depEngine.deploy(depOptions);
  3252. Owned<IPropertyTree> pDeployResult = depEngine.getDeployResult();
  3253. if (pDeployResult)
  3254. {
  3255. IPropertyTree* pComponents = pDeployResult->queryPropTree("SelectedComponents");
  3256. toXML(pComponents, deployResult, false);
  3257. }
  3258. IPropertyTree* pOptions = pDeployResult->queryPropTree("Options");
  3259. if (pOptions)
  3260. toXML(pOptions, deployResult, false);
  3261. resp.setStatus( depEngine.getDeployStatus() );
  3262. if (depEngine.GetErrorCount() == 0)
  3263. resp.setStatus(deployResult.str());
  3264. return true;
  3265. }
  3266. bool CWsDeployFileInfo::getDeployableComps(IEspContext &context, IEspGetDeployableCompsRequest &req, IEspGetDeployableCompsResponse &resp)
  3267. {
  3268. synchronized block(m_mutex);
  3269. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  3270. Owned<IPropertyTreeIterator> iter = pEnvRoot->getElements("Software/*");
  3271. Owned<IPropertyTree> pDeploy = createPTree("Deploy");
  3272. ForEach(*iter)
  3273. {
  3274. IPropertyTree* pComponent = &iter->query();
  3275. const char* type = pComponent->queryName();
  3276. if (stricmp(type, "Topology")!=0)
  3277. {
  3278. const char* name = pComponent->queryProp(XML_ATTR_NAME);
  3279. const char* build = pComponent->queryProp(XML_ATTR_BUILD);
  3280. const char* buildSet= pComponent->queryProp(XML_ATTR_BUILDSET);
  3281. StringBuffer sXPath;
  3282. sXPath.appendf("Programs/Build[@name='%s']/BuildSet[@name='%s']/@deployable", build, buildSet);
  3283. const char* szDeployable = pEnvRoot->queryProp(sXPath.str());
  3284. bool bDeployable = !szDeployable ||
  3285. (stricmp(szDeployable, "no") != 0 &&
  3286. stricmp(szDeployable, "false") != 0 &&
  3287. strcmp(szDeployable, "0") != 0);
  3288. if (name && *name && build && *build && bDeployable)
  3289. {
  3290. IPropertyTree* pCompNode = pDeploy->addPropTree( XML_TAG_COMPONENT, createPTree() );
  3291. pCompNode->addProp(XML_ATTR_NAME, name);
  3292. pCompNode->addProp(XML_ATTR_BUILD, build);
  3293. pCompNode->addProp(XML_ATTR_BUILDSET, type);
  3294. Owned<IPropertyTreeIterator> iter = pComponent->getElements("*", iptiter_sort);
  3295. ForEach(*iter)
  3296. {
  3297. IPropertyTree* pNode = &iter->query();
  3298. const char* nodeName = pNode->queryName();
  3299. const char* computer = pNode->queryProp(XML_ATTR_COMPUTER);
  3300. const char* instanceName = pNode->queryProp(XML_ATTR_NAME);
  3301. if (computer && *computer)
  3302. {
  3303. const char* instanceNodeNames[] = { XML_TAG_INSTANCE, XML_TAG_ROXIE_SERVER, XML_TAG_ROXIE_SLAVE };
  3304. for (UINT i=0; i<sizeof(instanceNodeNames) / sizeof(instanceNodeNames[0]); i++)
  3305. if (!strcmp(nodeName, instanceNodeNames[i]))
  3306. {
  3307. if (*nodeName != 'R')// || //neither RoxieServerProcess nor RoxieSlaveProcess
  3308. {
  3309. IPropertyTree* pInstanceNode = pCompNode->addPropTree(XML_TAG_INSTANCES, createPTree());
  3310. const char* directory = pNode->queryProp(*nodeName == 'R' ? XML_ATTR_DATADIRECTORY : XML_ATTR_DIRECTORY);
  3311. if (directory && *directory)
  3312. pInstanceNode->addProp(XML_ATTR_BUILD, directory);
  3313. pInstanceNode->addProp("@nodeName", computer);
  3314. pInstanceNode->addProp(XML_ATTR_BUILDSET, XML_TAG_INSTANCE);
  3315. pInstanceNode->addProp("@instanceName", instanceName);
  3316. }
  3317. }
  3318. }
  3319. }
  3320. }
  3321. }
  3322. }
  3323. StringBuffer xml, outputXml;
  3324. toXML(pDeploy, xml, false);
  3325. resp.setComponent( "Deploy" );
  3326. resp.setXmlArgs( xml.str() );
  3327. return true;
  3328. }
  3329. bool CWsDeployFileInfo::getComputersForRoxie(IEspContext &context, IEspGetComputersForRoxieRequest &req, IEspGetComputersForRoxieResponse &resp)
  3330. {
  3331. synchronized block(m_mutex);
  3332. checkForRefresh(context, &req.getReqInfo(), true);
  3333. const char* cmd = req.getCmd();
  3334. const char* xmlArg = req.getXmlArgs();
  3335. StringBuffer sbC, sbF;
  3336. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  3337. getComputersListWithUsage(pEnvRoot, sbC, sbF);
  3338. resp.setComputers(sbC.str());
  3339. resp.setFilters( sbF.str() );
  3340. return true;
  3341. }
  3342. bool CWsDeployFileInfo::handleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp)
  3343. {
  3344. synchronized block(m_mutex);
  3345. checkForRefresh(context, &req.getReqInfo(), true);
  3346. const char* cmd = req.getCmd();
  3347. const char* xmlArg = req.getXmlArgs();
  3348. StringBuffer sbC, sbF;
  3349. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  3350. bool retVal = ::handleRoxieOperation(pEnvRoot, cmd, xmlArg);
  3351. resp.setStatus(retVal? "true" : "false");
  3352. return true;
  3353. }
  3354. bool CWsDeployFileInfo::getBuildSetInfo(IEspContext &context, IEspGetBuildSetInfoRequest &req, IEspGetBuildSetInfoResponse &resp)
  3355. {
  3356. synchronized block(m_mutex);
  3357. checkForRefresh(context, &req.getReqInfo(), true);
  3358. const char* cmd = req.getCmd();
  3359. const char* xmlArg = req.getXmlArgs();
  3360. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  3361. Owned<IPropertyTree> pSettings = createPTree("Settings");
  3362. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  3363. IPropertyTree* pBuildSet = pSrcTree->queryPropTree(XML_TAG_BUILDSET);
  3364. if (pBuildSet)
  3365. {
  3366. IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS);
  3367. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements(XML_TAG_BUILDSET);
  3368. ForEach (*iter)
  3369. {
  3370. IPropertyTree* pFolder = &iter->query();
  3371. const char* pszBuild = pFolder->queryProp(XML_ATTR_BUILD);
  3372. const char* pszBuildPath = pFolder->queryProp("@buildpath");
  3373. const char* pszBuildSet = pFolder->queryProp(XML_ATTR_NAME);
  3374. const char* pszBuildSetPath = pFolder->queryProp("@path");
  3375. StringBuffer xpath;
  3376. xpath.appendf("Build[@name='%s']/BuildSet[@name='%s']", pszBuild, pszBuildSet);
  3377. IPropertyTree* pComp = pEnvPrograms->queryPropTree(xpath.str());
  3378. if (!pComp)
  3379. throw MakeStringException(-1, "No such build and buildset in environment: '%s' named '%s'.", pszBuild, pszBuildSet);
  3380. StringBuffer s;
  3381. s.append("./Programs/Build[@name=\"").append(pszBuild).append("\"]");
  3382. IPropertyTree *b = pEnvRoot->queryPropTree(s.str());
  3383. IPropertyTree *bs = NULL;
  3384. IPropertyTree* pParentNode = NULL;
  3385. IPropertyTree* pFiles = NULL;
  3386. if (b)
  3387. {
  3388. s.clear().append("BuildSet[@name=\"").append(pszBuildSet).append("\"]");
  3389. bs = b->queryPropTree(s.str());
  3390. StringBuffer fileName;
  3391. connectBuildSet(b, bs, fileName, m_Environment);
  3392. fileName.append(bs->queryProp("@installSet"));
  3393. pParentNode = createPTreeFromXMLFile(fileName.str());
  3394. pFiles = pParentNode->queryPropTree("File");
  3395. }
  3396. StringBuffer xml;
  3397. toXML(pParentNode, xml, false);
  3398. resp.setComponent(XML_TAG_BUILDSET);
  3399. resp.setXmlArgs( xml.str() );
  3400. }
  3401. }
  3402. return true;
  3403. }
  3404. bool CWsDeployFileInfo::importBuild(IEspContext &context, IEspImportBuildRequest &req, IEspImportBuildResponse &resp)
  3405. {
  3406. synchronized block(m_mutex);
  3407. checkForRefresh(context, &req.getReqInfo(), true);
  3408. const char* xmlArg = req.getBuildSets();
  3409. IPropertyTree* buildSets = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<BuildSets/>");
  3410. IPropertyTree* buildNode = createPTree(XML_TAG_BUILD);
  3411. const char* buildName = buildSets->queryProp(XML_ATTR_NAME);
  3412. const char* buildUrl = buildSets->queryProp("@path");
  3413. buildNode->setProp(XML_ATTR_NAME, buildName);
  3414. buildNode->setProp(XML_ATTR_URL, buildUrl);
  3415. Owned<IPropertyTreeIterator> iBuildSet = buildSets->getElements("*");
  3416. ForEach(*iBuildSet)
  3417. {
  3418. IPropertyTree* pBuildSet = &iBuildSet->query();
  3419. const char* bsName = pBuildSet->queryProp(XML_ATTR_NAME);
  3420. const char* bsPath = pBuildSet->queryProp("@path");
  3421. IPropertyTree* pBuildsetNode = createPTree();
  3422. pBuildsetNode->addProp(XML_ATTR_NAME, bsName);
  3423. pBuildsetNode->addProp(XML_ATTR_PATH, bsPath);
  3424. pBuildsetNode->addProp(XML_ATTR_INSTALLSET, "deploy_map.xml");
  3425. try
  3426. {
  3427. Owned<IPropertyTree> installSet = loadInstallSet(buildNode, pBuildsetNode, m_Environment);
  3428. if (strcmp(installSet->queryName(), XML_TAG_INSTALLSET) == 0)
  3429. {
  3430. pBuildsetNode->setProp(XML_ATTR_PROCESS_NAME, installSet->queryProp(XML_ATTR_PROCESS_NAME));
  3431. pBuildsetNode->setProp(XML_ATTR_SCHEMA, installSet->queryProp(XML_ATTR_SCHEMA));
  3432. if (installSet->hasProp(XML_ATTR_NAME))
  3433. pBuildsetNode->setProp(XML_ATTR_NAME, installSet->queryProp(XML_ATTR_NAME));
  3434. const char* szDeployable = installSet->queryProp("@deployable");
  3435. if (szDeployable)
  3436. pBuildsetNode->setProp("@deployable", szDeployable);
  3437. IPropertyTree* pProperties = installSet->getPropTree("Properties");
  3438. if (pProperties)
  3439. pBuildsetNode->addPropTree("Properties", pProperties);
  3440. buildNode->addPropTree(XML_TAG_BUILDSET, pBuildsetNode);
  3441. }
  3442. }
  3443. catch(...)
  3444. {
  3445. }
  3446. }
  3447. Owned<IPropertyTree> pEnvRoot = &m_Environment->getPTree();
  3448. IPropertyTree* pEnvPrograms = pEnvRoot->queryPropTree(XML_TAG_PROGRAMS);
  3449. if (!pEnvPrograms)
  3450. pEnvPrograms = pEnvRoot->addPropTree(XML_TAG_PROGRAMS, createPTree() );
  3451. pEnvPrograms->addPropTree(XML_TAG_BUILD, buildNode);
  3452. resp.setStatus("true");
  3453. return true;
  3454. }
  3455. bool CWsDeployFileInfo::getBuildServerDirs(IEspContext &context, IEspGetBuildServerDirsRequest &req, IEspGetBuildServerDirsResponse &resp)
  3456. {
  3457. synchronized block(m_mutex);
  3458. checkForRefresh(context, &req.getReqInfo(), true);
  3459. const char* cmd = req.getCmd();
  3460. const char* xmlArg = req.getXmlArgs();
  3461. StringBuffer sourceDir;
  3462. if (xmlArg && *xmlArg)
  3463. {
  3464. if (xmlArg[0] != '\\' && xmlArg[1] != '\\')
  3465. sourceDir.append("\\\\127.0.0.1\\");
  3466. sourceDir.append(xmlArg);
  3467. }
  3468. if (!strcmp(cmd, "SubDirs"))
  3469. {
  3470. Owned<IFile> inFiles = NULL;
  3471. IPropertyTree* pParentNode = createPTree("BuildServerDirs");
  3472. try
  3473. {
  3474. inFiles.setown(createIFile(sourceDir));
  3475. if(!inFiles->exists())
  3476. {
  3477. resp.setXmlArgs("Input directory %s does not exist");
  3478. return false;
  3479. }
  3480. }
  3481. catch(IException* e)
  3482. {
  3483. StringBuffer errmsg;
  3484. e->errorMessage(errmsg);
  3485. e->Release();
  3486. resp.setXmlArgs("Error when trying to access source directory.");
  3487. return false;
  3488. }
  3489. Owned<IDirectoryIterator> di = inFiles->directoryFiles(NULL, 0, true);
  3490. CIArrayOf<CDirectoryEntry> sortedfiles;
  3491. StringArray dispfiles;
  3492. bool bDirChosen = false;
  3493. sortDirectory(sortedfiles, *di, SD_bydate, true, true);
  3494. StringBuffer lastDirName;
  3495. int index = 0;
  3496. ForEachItemIn(idx, sortedfiles)
  3497. {
  3498. CDirectoryEntry *de = &sortedfiles.item(idx);
  3499. if (de->isdir)
  3500. {
  3501. StringBuffer sb;
  3502. de->modifiedTime.getString(sb);
  3503. IPropertyTree* pCompNode = pParentNode->addPropTree( "Directory", createPTree() );
  3504. pCompNode->addProp(XML_ATTR_NAME, de->name.get());
  3505. pCompNode->addProp("@modified", sb.str());
  3506. }
  3507. }
  3508. StringBuffer xml;
  3509. toXML(pParentNode, xml, false);
  3510. resp.setComponent("BuildServerDirs");
  3511. resp.setXmlArgs( xml.str() );
  3512. }
  3513. else
  3514. {
  3515. Owned<IFile> inFiles = NULL;
  3516. IPropertyTree* pParentNode = createPTree("BuildServerComps");
  3517. if (!strcmp(cmd, "Release"))
  3518. sourceDir.append(PATHSEPCHAR).append("release");
  3519. else if (!strcmp(cmd, "Debug"))
  3520. sourceDir.append(PATHSEPCHAR).append("debug");
  3521. try
  3522. {
  3523. inFiles.setown(createIFile(sourceDir));
  3524. if(!inFiles->exists())
  3525. {
  3526. resp.setXmlArgs("Input directory %s does not exist");
  3527. return false;
  3528. }
  3529. }
  3530. catch(IException* e)
  3531. {
  3532. StringBuffer errmsg;
  3533. e->errorMessage(errmsg);
  3534. e->Release();
  3535. resp.setXmlArgs("Error when trying to access source directory.");
  3536. return false;
  3537. }
  3538. if(inFiles.get() != NULL && inFiles->isDirectory())
  3539. {
  3540. Owned<IDirectoryIterator> di = inFiles->directoryFiles(NULL, 0, true);
  3541. bool bCompFound = false;
  3542. StringBuffer dirName, compName, fileName;
  3543. if(di.get())
  3544. {
  3545. ForEach(*di)
  3546. {
  3547. IFile &file = di->query();
  3548. if (!file.isFile())
  3549. {
  3550. dirName.clear();
  3551. di->getName(dirName);
  3552. compName.clear().append(dirName);
  3553. Owned<IFile> dirFiles = NULL;
  3554. StringBuffer sbPath(cmd);
  3555. sbPath.toLowerCase();
  3556. dirName.clear().append(sourceDir);
  3557. if(dirName.charAt(dirName.length() - 1) != PATHSEPCHAR)
  3558. dirName.append(PATHSEPCHAR);
  3559. dirName.append(compName);
  3560. sbPath.append(PATHSEPCHAR).append(compName);
  3561. fileName.clear().append(dirName).append(PATHSEPCHAR).append("deploy_map.xml");
  3562. Owned<IFile> depfile(createIFile(fileName));
  3563. if(depfile->exists())
  3564. {
  3565. IPropertyTree* pCompNode = pParentNode->addPropTree("Comp", createPTree() );
  3566. pCompNode->addProp(XML_ATTR_NAME, compName.str());
  3567. pCompNode->addProp("@path", sbPath.str());
  3568. }
  3569. }
  3570. }
  3571. }
  3572. StringBuffer xml;
  3573. toXML(pParentNode, xml, false);
  3574. resp.setComponent("BuildServerComps");
  3575. resp.setXmlArgs( xml.str() );
  3576. }
  3577. }
  3578. return true;
  3579. }
  3580. bool CWsDeployFileInfo::handleAttributeDelete(IEspContext &context, IEspHandleAttributeDeleteRequest &req, IEspHandleAttributeDeleteResponse &resp)
  3581. {
  3582. synchronized block(m_mutex);
  3583. const char* xmlArg = req.getXmlArgs();
  3584. if (!xmlArg || !*xmlArg)
  3585. return false;
  3586. Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg);
  3587. Owned<IPropertyTreeIterator> iter = pSrcTree->getElements("Setting[@operation='delete']");
  3588. if (iter->first() == false)
  3589. return false;
  3590. IPropertyTree* pSetting = &iter->query();
  3591. Owned<IPropertyTree> pEnvRoot = &m_Environment->getPTree();
  3592. StringBuffer xpath2 = pSetting->queryProp("@params");
  3593. IPropertyTree* pComp = pEnvRoot->queryPropTree(xpath2.str());
  3594. if (pComp == NULL)
  3595. throw MakeStringException(-1,"Bad XPath %s (Try refreshing the browser?)", xpath2.str());
  3596. StringBuffer xml;
  3597. StringBuffer attrib;
  3598. int count = xpath2.length()-2;
  3599. if (count <= 0)
  3600. throw MakeStringException(-1,"Bad XPath %s (Try refreshing the browser?)", xpath2.str());
  3601. while (xpath2[count] != '=' || xpath2[count+1] != '\'')
  3602. count--;
  3603. count--;
  3604. for (int i=count; i >= 0 && xpath2[i] != '['; i--)
  3605. attrib.insert(0,xpath2[i]);
  3606. int index = xpath2.length()-1;
  3607. while (index > 0)
  3608. {
  3609. if (xpath2[index] == '/')
  3610. break;
  3611. index--;
  3612. }
  3613. char *pRootXPath = new char[index+2];
  3614. memset(pRootXPath,0,sizeof(char) * (index+2));
  3615. xpath2.getChars(0,index+1,pRootXPath);
  3616. if (req.getBLeaf() == true)
  3617. pComp->removeProp(attrib);
  3618. else if (strlen(pRootXPath) >= 14 && strncmp(pRootXPath,"./EnvSettings/",14) == 0)
  3619. pEnvRoot->queryPropTree("./EnvSettings")->removeTree(pComp);
  3620. else
  3621. pEnvRoot->queryPropTree(pRootXPath)->removeTree(pComp);
  3622. delete[] pRootXPath;
  3623. resp.setStatus("true");
  3624. resp.setCompName(XML_TAG_SOFTWARE);
  3625. return true;
  3626. }
  3627. bool CWsDeployFileInfo::handleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp)
  3628. {
  3629. synchronized block(m_mutex);
  3630. checkForRefresh(context, &req.getReqInfo(), true);
  3631. const char* xmlArg = req.getXmlArgs();
  3632. Owned<IPropertyTree> pComponents = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<Components/>");
  3633. const char* operation = req.getOperation();
  3634. StringBuffer sbNewName;
  3635. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  3636. if (!strcmp(operation, "Add"))
  3637. {
  3638. Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
  3639. ForEach(*iterComp)
  3640. {
  3641. IPropertyTree& pComp = iterComp->query();
  3642. const char* buildSet = pComp.queryProp(XML_ATTR_BUILDSET);
  3643. StringBuffer xpath;
  3644. xpath.appendf("./Programs/Build/BuildSet[@name=\"%s\"]", buildSet);
  3645. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpath.str());
  3646. buildSetIter->first();
  3647. IPropertyTree* pBuildSet = &buildSetIter->query();
  3648. const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  3649. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  3650. StringBuffer buildSetPath;
  3651. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  3652. xpath.clear().appendf("./Software/%s[@name='%s']", processName, buildSetName);
  3653. IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName(), false);
  3654. IPropertyTree* pInstTree = pCompTree->queryPropTree(XML_TAG_INSTANCE);
  3655. if (pInstTree)
  3656. pCompTree->removeTree(pInstTree);
  3657. addComponentToEnv(pEnvRoot, buildSet, sbNewName, pCompTree);
  3658. }
  3659. resp.setCompName(sbNewName.str());
  3660. resp.setStatus("true");
  3661. }
  3662. else if (!strcmp(operation, "Delete"))
  3663. {
  3664. StringBuffer xpath;
  3665. StringBuffer xpathSoftware;
  3666. StringBuffer xpathFull;
  3667. StringBuffer errMsg;
  3668. Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
  3669. xpathSoftware.appendf("./%s", XML_TAG_SOFTWARE);
  3670. ForEach(*iterComp)
  3671. {
  3672. IPropertyTree& pComp = iterComp->query();
  3673. const char* compName = pComp.queryProp(XML_ATTR_NAME);
  3674. const char* compType = pComp.queryProp(XML_ATTR_COMPTYPE);
  3675. xpath.clear().appendf("%s/%s", xpathSoftware.str(), compType);
  3676. Owned<IPropertyTreeIterator> iterComp2 = pEnvRoot->getElements(xpath.str());
  3677. ForEach(*iterComp2)
  3678. {
  3679. xpathFull.clear().appendf("%s[%s=\"%s\"]", xpath.str(), XML_ATTR_NAME, compName);
  3680. unsigned short numElements = pEnvRoot->getCount(xpathFull.str());
  3681. if (strcmp(iterComp2->query().queryProp(XML_ATTR_NAME), compName) == 0)
  3682. {
  3683. IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpathSoftware.str());
  3684. StringBuffer sbMsg;
  3685. // only check for component dependencies if the componenet to be deleted is the last instance with the same name
  3686. if (pCompTree != NULL && (pEnvRoot->getCount(xpathFull.str()) > 1 ? true : checkComponentReferences(pEnvRoot, pEnvRoot->queryPropTree(xpathFull.str()), compName, sbMsg)))
  3687. pEnvRoot->queryPropTree(xpathSoftware.str())->removeTree(&(iterComp2->query()));
  3688. if (sbMsg.length() > 0)
  3689. errMsg.appendf("\n%s", sbMsg.str());
  3690. break;
  3691. }
  3692. }
  3693. resp.setStatus(errMsg.length() > 1 ? errMsg.str() : "true");
  3694. resp.setCompName(compName);
  3695. }
  3696. }
  3697. else if (!strcmp(operation, "Duplicate"))
  3698. {
  3699. StringBuffer sbNewName;
  3700. StringBuffer xpath;
  3701. Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
  3702. if (iterComp->first() && iterComp->isValid())
  3703. {
  3704. IPropertyTree& pComp = iterComp->query();
  3705. const char* compName = pComp.queryProp(XML_ATTR_NAME);
  3706. const char* compType = pComp.queryProp(XML_ATTR_COMPTYPE);
  3707. sbNewName = compName;
  3708. xpath = compType;
  3709. getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
  3710. xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, compType, XML_ATTR_NAME, compName);
  3711. IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str());
  3712. if (pCompTree == NULL)
  3713. throw MakeStringException(-1,"XPATH: %s is invalid.", xpath.str());
  3714. StringBuffer xml;
  3715. toXML(pCompTree, xml);
  3716. IPropertyTree *dupTree = createPTreeFromXMLString(xml.str());
  3717. dupTree->setProp(XML_ATTR_NAME, sbNewName.str());
  3718. xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, compType, XML_ATTR_NAME, sbNewName.str());
  3719. if (pEnvRoot->addPropTree(xpath, dupTree))
  3720. resp.setStatus("true");
  3721. else
  3722. resp.setStatus("false");
  3723. }
  3724. else
  3725. {
  3726. resp.setStatus("false");
  3727. }
  3728. resp.setCompName(XML_TAG_SOFTWARE);
  3729. }
  3730. else if (!strcmp(operation, "CopySW"))
  3731. {
  3732. if (handleComponentCopy(pComponents, pEnvRoot.get()) == true)
  3733. resp.setStatus("true");
  3734. else
  3735. resp.setStatus("false");
  3736. }
  3737. else if (!strcmp(operation, "CopyHW"))
  3738. {
  3739. if (handleHardwareCopy(pComponents, pEnvRoot->queryPropTree("Hardware"))== true)
  3740. resp.setStatus("true");
  3741. else
  3742. resp.setStatus("false");
  3743. }
  3744. return true;
  3745. }
  3746. bool CWsDeployFileInfo::addCopyToPropTree(IPropertyTree* pPropTree, IPropertyTree* pDupTree, const char* tag_name)
  3747. {
  3748. StringBuffer strTag;
  3749. strTag.clear().appendf("%s/%s", XML_TAG_HARDWARE, tag_name);
  3750. return pPropTree->addPropTree(strTag.str(), pDupTree) != NULL;
  3751. }
  3752. bool CWsDeployFileInfo::handleHardwareCopy(IPropertyTree *pComponents, IPropertyTree *pEnvRoot)
  3753. {
  3754. StringBuffer xpath;
  3755. StringBuffer xpath3;
  3756. StringBuffer filePath;
  3757. xpath.clear().appendf("%s", XML_TAG_HARDWARE);
  3758. Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
  3759. Owned<IPropertyTreeIterator> iter = pEnvRoot->getElements("*");
  3760. if (!iterComp->first())
  3761. return false;
  3762. CWsDeployFileInfo::setFilePath(filePath, iterComp->query().queryProp(XML_ATTR_TARGET));
  3763. Owned<CWsDeployFileInfo> fi = new CWsDeployFileInfo(m_pService, filePath, false);
  3764. fi->m_skipEnvUpdateFromNotification = false;
  3765. fi->initFileInfo(false,false);
  3766. Owned<IPropertyTree> pEnvRoot2 = &(fi->m_Environment->getPTree());
  3767. bool bWrite = false;
  3768. StringArray elems;
  3769. ForEach(*iter)
  3770. {
  3771. IPropertyTree& pComp = iter->query();
  3772. const char* name = pComp.queryProp(XML_ATTR_NAME);
  3773. const char* tag_name = pComp.queryName();
  3774. StringBuffer xpath2;
  3775. xpath2.appendf("./%s/%s[%s = \"%s\"]", XML_TAG_HARDWARE, tag_name, XML_ATTR_NAME, name);
  3776. if (pEnvRoot2->queryPropTree(xpath2.str()) != NULL) // check if target configuration has same named element
  3777. {
  3778. elems.append(name);
  3779. continue;
  3780. }
  3781. StringBuffer xml;
  3782. xml.appendf("<%s", tag_name);
  3783. Owned<IAttributeIterator> pAttribIter = pComp.getAttributes();
  3784. ForEach(*pAttribIter)
  3785. {
  3786. const char* name = &(pAttribIter->queryName()[1]);
  3787. const char* value = pAttribIter->queryValue();
  3788. xml.appendf(" %s=\"%s\" ", name, value);
  3789. }
  3790. xml.append("/>");
  3791. IPropertyTree *dupTree = NULL;
  3792. if (iterComp->query().queryProp(XML_ATTR_HWXPATH) && strlen(iterComp->query().queryProp(XML_ATTR_HWXPATH)) > 0)
  3793. {
  3794. xpath3.clear().appendf("<%s/>", iterComp->query().queryProp(XML_ATTR_HWXPATH));
  3795. dupTree = createPTreeFromXMLString((xpath3.replace('\'','\"')).str());
  3796. String strTagName(xpath3);
  3797. strTagName = *strTagName.substring(1,strTagName.indexOf(' '));
  3798. if (CWsDeployFileInfo::addCopyToPropTree(pEnvRoot2, dupTree, strTagName.toCharArray()) == false)
  3799. return false;
  3800. bWrite = true;
  3801. break;
  3802. }
  3803. else
  3804. dupTree = createPTreeFromXMLString(xml.str());
  3805. if (CWsDeployFileInfo::addCopyToPropTree(pEnvRoot2, dupTree, tag_name) == false)
  3806. return false;
  3807. bWrite = true;
  3808. }
  3809. if (bWrite == true)
  3810. {
  3811. StringBuffer err;
  3812. fi->saveEnvironment(NULL, NULL, err);
  3813. if (elems.ordinality() > 0 && !(iterComp->query().queryProp(XML_ATTR_HWXPATH) && strlen(iterComp->query().queryProp(XML_ATTR_HWXPATH)) > 0))
  3814. {
  3815. StringBuffer errMsg;
  3816. errMsg.appendf("Saved succeeded but some some element(s) could not be copied. Element(s) may already exist in the target configuration.\n[");
  3817. ForEachItemIn(i, elems)
  3818. {
  3819. errMsg.appendf("%s, ",elems.item(i));
  3820. }
  3821. errMsg.setCharAt(errMsg.length()-2 , ']');
  3822. throw MakeStringException(-1, "%s", errMsg.str());
  3823. }
  3824. }
  3825. else
  3826. {
  3827. throw MakeStringException(-1, "Copy failed. All elements may already exist in the target configuration.");
  3828. }
  3829. return true;
  3830. }
  3831. bool CWsDeployFileInfo::handleComponentCopy(IPropertyTree *pComponents, IPropertyTree *pEnvRoot)
  3832. {
  3833. Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
  3834. bool bError = false;
  3835. StringBuffer errMsg;
  3836. char targetName[255] = "";
  3837. iterComp->first();
  3838. strncpy(targetName, iterComp->query().queryProp("@target"), 255); //get the copy target configuration file name
  3839. StringBuffer filePath;
  3840. CWsDeployFileInfo::setFilePath(filePath, targetName);
  3841. Owned<CWsDeployFileInfo> fi = new CWsDeployFileInfo(m_pService, filePath, false);
  3842. fi->m_skipEnvUpdateFromNotification = false;
  3843. fi->initFileInfo(false,false);
  3844. Owned<IPropertyTree> pEnvRoot2 = &(fi->m_Environment->getPTree());
  3845. Owned<IPropertyTreeIterator> iterComp2 = pComponents->getElements("*");
  3846. StringBuffer xpath;
  3847. ForEach(*iterComp)
  3848. {
  3849. IPropertyTree& pComp = iterComp->query();
  3850. const char* compName = pComp.queryProp(XML_ATTR_NAME);
  3851. if (compName == NULL)
  3852. {
  3853. if (bError == false)
  3854. {
  3855. bError = true;
  3856. errMsg.clear().appendf("Faild to query for @name attribute, continuing...");
  3857. }
  3858. continue;
  3859. }
  3860. const char* compType = pComp.queryProp("@compType");
  3861. StringBuffer sbNewName = compName;
  3862. xpath.clear().appendf("%s", compType);
  3863. getUniqueName(pEnvRoot2, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
  3864. xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, compType, XML_ATTR_NAME, compName);
  3865. IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str());
  3866. if ( pCompTree == NULL)
  3867. throw MakeStringException(-1,"XPATH: %s is invalid in source configuration. Copy failed.", xpath.str());
  3868. xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, compType, XML_ATTR_NAME, sbNewName.str());
  3869. StringBuffer xml;
  3870. toXML(pCompTree, xml);
  3871. IPropertyTree *dupTree = createPTreeFromXMLString(xml.str());
  3872. dupTree->setProp(XML_ATTR_NAME, sbNewName.str());
  3873. if (pEnvRoot2->addPropTree(xpath, dupTree) == NULL)
  3874. throw MakeStringException(-1,"XPATH: %s is invalid in target. Copy failed.", xpath.str());
  3875. }
  3876. StringBuffer err;
  3877. fi->saveEnvironment(NULL, NULL, err);
  3878. if (bError == true)
  3879. throw MakeStringException(-1,"Save succeeded but an error was encountered with message: %s", errMsg.str());
  3880. return true;
  3881. }
  3882. bool CWsDeployFileInfo::handleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp)
  3883. {
  3884. synchronized block(m_mutex);
  3885. checkForRefresh(context, &req.getReqInfo(), true);
  3886. const char* operation = req.getOperation();
  3887. const char* xmlArg = req.getXmlArgs();
  3888. Owned<IPropertyTree> instances = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<Instances/>");
  3889. const char* buildSet = instances->queryProp(XML_ATTR_BUILDSET);
  3890. const char* compName = instances->queryProp("@compName");
  3891. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  3892. StringBuffer xpath;
  3893. xpath.appendf("./Programs/Build/BuildSet[@name=\"%s\"]", buildSet);
  3894. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpath.str());
  3895. buildSetIter->first();
  3896. IPropertyTree* pBuildSet = &buildSetIter->query();
  3897. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  3898. StringBuffer dups, reqdComps, reqdCompNames;
  3899. if (!strcmp(operation, "Add"))
  3900. {
  3901. StringBuffer buildSetPath;
  3902. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  3903. xpath.clear().appendf("./Software/%s[@name=\"%s\"]", processName, compName);
  3904. IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str());
  3905. Owned<IPropertyTreeIterator> iterInst = instances->getElements("*");
  3906. bool bAdded = false;
  3907. ForEach(*iterInst)
  3908. {
  3909. IPropertyTree& pComputer = iterInst->query();
  3910. xpath.clear().appendf("./Hardware/Computer[@name=\"%s\"]", pComputer.queryProp(XML_ATTR_NAME));
  3911. IPropertyTree* pComputerNode = pEnvRoot->queryPropTree(xpath.str());
  3912. xpath.clear().appendf("Instance[@netAddress=\"%s\"]", pComputerNode->queryProp(XML_ATTR_NETADDRESS));
  3913. if (pCompTree->queryPropTree(xpath.str()))
  3914. {
  3915. dups.appendf("\n%s", pComputerNode->queryProp(XML_ATTR_NETADDRESS));
  3916. continue;
  3917. }
  3918. IPropertyTree* pNode = pCompTree->addPropTree(XML_TAG_INSTANCE, createPTree());
  3919. if (pSchema)
  3920. {
  3921. Owned<IPropertyTreeIterator> iter = pSchema->getElements("xs:element/xs:complexType/xs:sequence/xs:element[@name=\"Instance\"]/xs:complexType/xs:attribute");
  3922. ForEach(*iter)
  3923. {
  3924. IPropertyTree &attr = iter->query();
  3925. StringBuffer attrName("@");
  3926. attrName.append(attr.queryProp(XML_ATTR_NAME));
  3927. // we try to pull @computer and @netAddress from computerNode. Others come from default values in schema (if supplied)
  3928. const char *szAttrib;
  3929. StringBuffer sb;
  3930. if (!strcmp(attrName.str(), XML_ATTR_COMPUTER))
  3931. {
  3932. szAttrib = pComputerNode->queryProp(XML_ATTR_NAME);
  3933. if (!bAdded)
  3934. {
  3935. bAdded = true;
  3936. resp.setNewName(szAttrib);
  3937. }
  3938. }
  3939. else if (!strcmp(attrName.str(), XML_ATTR_NETADDRESS))
  3940. szAttrib = pComputerNode->queryProp(XML_ATTR_NETADDRESS);
  3941. else if (!strcmp(attrName.str(), XML_ATTR_DIRECTORY))
  3942. {
  3943. StringBuffer rundir;
  3944. if (!getConfigurationDirectory(pEnvRoot->queryPropTree("Software/Directories"),"run",buildSet,compName,rundir))
  3945. sb.clear().appendf(RUNTIME_DIR"/%s", compName);
  3946. else
  3947. sb.clear().append(rundir);
  3948. szAttrib = sb.str();
  3949. }
  3950. else
  3951. szAttrib = attr.queryProp("@default");
  3952. pNode->addProp(attrName.str(), szAttrib);
  3953. }
  3954. Owned<IPropertyTree> pNewCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSet, m_pService->getCfg(), m_pService->getName(), true);
  3955. if (pNewCompTree)
  3956. {
  3957. StringBuffer sbxml;
  3958. toXML(pNewCompTree, sbxml);
  3959. Owned<IPropertyTreeIterator> iterElems = pNewCompTree->getElements("Instance/*");
  3960. ForEach (*iterElems)
  3961. {
  3962. IPropertyTree* pElem = &iterElems->query();
  3963. if (!pNode->queryProp(pElem->queryName()))
  3964. pNode->addPropTree(pElem->queryName(), createPTreeFromIPT(pElem));
  3965. }
  3966. }
  3967. }
  3968. if (!checkForRequiredComponents(pEnvRoot, pComputerNode->queryProp(XML_ATTR_NETADDRESS), reqdCompNames, buildSet))
  3969. reqdComps.appendf("\n%s", pComputerNode->queryProp(XML_ATTR_NETADDRESS));
  3970. }
  3971. resp.setReqdCompNames(reqdCompNames.str());
  3972. resp.setAddReqdComps(reqdComps.str());
  3973. resp.setDuplicates(dups.str());
  3974. }
  3975. else if (!strcmp(operation, "Delete"))
  3976. {
  3977. Owned<IPropertyTreeIterator> iterInst = instances->getElements("*");
  3978. ForEach(*iterInst)
  3979. {
  3980. IPropertyTree& pInst = iterInst->query();
  3981. StringBuffer decodedParams( pInst.queryProp("@params") );
  3982. decodedParams.replaceString("::", "\n");
  3983. Owned<IProperties> pParams = createProperties();
  3984. pParams->loadProps(decodedParams.str());
  3985. const char* pszCompType = pParams->queryProp("pcType");
  3986. const char* pszCompName = pParams->queryProp("pcName");
  3987. const char* pszSubType = pParams->queryProp("subType");
  3988. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  3989. xpath.clear().appendf("./Software/%s[@name=\"%s\"]", pszCompType, pszCompName);
  3990. IPropertyTree* pInstParent = pEnvRoot->queryPropTree(xpath.str());
  3991. if (pszSubTypeKey[0] == '[' && pszSubTypeKey[strlen(pszSubTypeKey) - 1] == ']')
  3992. xpath.clear().appendf("%s%s", pszSubType, pszSubTypeKey);
  3993. else
  3994. xpath.clear().appendf("%s[@name=\"%s\"]", pszSubType, pszSubTypeKey);
  3995. IPropertyTree* pInstTree = pInstParent->queryPropTree(xpath.str());
  3996. if (pInstParent && pInstTree)
  3997. pInstParent->removeTree(pInstTree);
  3998. }
  3999. }
  4000. //rename instance names
  4001. int nCount = 1;
  4002. xpath.clear().appendf("./Software/%s[@name=\"%s\"]/Instance", processName, compName);
  4003. Owned<IPropertyTreeIterator> iter = pEnvRoot->getElements(xpath.str());
  4004. StringBuffer sName;
  4005. ForEach(*iter)
  4006. {
  4007. sName.clear().append("s").append(nCount);
  4008. iter->query().setProp(XML_ATTR_NAME, sName.str());
  4009. nCount++;
  4010. }
  4011. resp.setStatus("true");
  4012. return true;
  4013. }
  4014. bool CWsDeployFileInfo::addReqdComps(IEspContext &context, IEspAddReqdCompsRequest &req, IEspAddReqdCompsResponse &resp)
  4015. {
  4016. synchronized block(m_mutex);
  4017. checkForRefresh(context, &req.getReqInfo(), true);
  4018. const char* xmlArg = req.getXmlArgs();
  4019. Owned<IPropertyTree> instances = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<ReqdComps/>");
  4020. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  4021. Owned<IPropertyTreeIterator> iterComp = instances->getElements("*");
  4022. bool bAdded = false;
  4023. StringBuffer reqCompNames, failed;
  4024. ForEach(*iterComp)
  4025. {
  4026. IPropertyTree& pComputer = iterComp->query();
  4027. if (!checkForRequiredComponents(pEnvRoot, pComputer.queryProp(XML_ATTR_NETADDRESS), reqCompNames, NULL, true))
  4028. failed.appendf("\n%s", pComputer.queryProp(XML_ATTR_NETADDRESS));
  4029. }
  4030. resp.setFailures(failed.str());
  4031. resp.setStatus("true");
  4032. return true;
  4033. }
  4034. bool CWsDeployFileInfo::handleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp)
  4035. {
  4036. synchronized block(m_mutex);
  4037. checkForRefresh(context, &req.getReqInfo(), true);
  4038. const char* xmlArg = req.getXmlArgs();
  4039. Owned<IPropertyTree> pBindings = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<EspServiceBindings/>");
  4040. const char* type = pBindings->queryProp(XML_ATTR_TYPE);
  4041. const char* espName = pBindings->queryProp("@compName");
  4042. const char* operation = req.getOperation();
  4043. StringBuffer sbNewName;
  4044. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  4045. StringBuffer xpath;
  4046. if (!strcmp(operation, "Add"))
  4047. {
  4048. xpath.append("./Programs/Build/BuildSet[@processName=\"EspProcess\"]");
  4049. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpath.str());
  4050. buildSetIter->first();
  4051. IPropertyTree* pBuildSet = &buildSetIter->query();
  4052. const char* buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  4053. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  4054. StringBuffer buildSetPath;
  4055. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  4056. xpath.clear().appendf("./Software/%s[@name='%s']", processName, espName);
  4057. Owned<IPropertyTreeIterator> iterItems = pBindings->getElements("Item");
  4058. bool flag = false;
  4059. ForEach (*iterItems)
  4060. {
  4061. flag = true;
  4062. IPropertyTree* pItem = &iterItems->query();
  4063. const char* bindingName = pItem->queryProp(XML_ATTR_NAME);
  4064. const char* params = pItem->queryProp("@params");
  4065. StringBuffer decodedParams(params);
  4066. decodedParams.replaceString("::", "\n");
  4067. Owned<IProperties> pParams = createProperties();
  4068. pParams->loadProps(decodedParams.str());
  4069. const char* pszCompType = pParams->queryProp("pcType");
  4070. const char* pszCompName = pParams->queryProp("pcName");
  4071. const char* pszSubType = pParams->queryProp("subType");
  4072. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  4073. if (strcmp(type, XML_TAG_ESPBINDING) && bindingName)
  4074. xpath.appendf("/EspBinding[@name='%s']", bindingName);
  4075. else if (pszSubType && *pszSubType)
  4076. {
  4077. String subType(pszSubType);
  4078. int idx = subType.lastIndexOf('/');
  4079. if (idx > 0)
  4080. {
  4081. String* tmpstr = subType.substring(0, idx);
  4082. xpath.append("/").append(*tmpstr);
  4083. delete tmpstr;
  4084. }
  4085. }
  4086. IPropertyTree* pEspService = pEnvRoot->queryPropTree(xpath.str());
  4087. IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName());
  4088. StringBuffer sb(type);
  4089. if (!strncmp(sb.str(), "_", 1))
  4090. sb.remove(0, 1);
  4091. if (!strcmp(type, XML_TAG_ESPBINDING))
  4092. {
  4093. StringBuffer sbNewName(XML_TAG_ESPBINDING);
  4094. xpath.clear().appendf("%s[@name='%s']/EspBinding", processName, espName);
  4095. getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
  4096. xpath.clear().append(sb.str()).append("/").append(XML_ATTR_NAME);
  4097. pCompTree->setProp(xpath.str(), sbNewName);
  4098. resp.setNewName(sbNewName);
  4099. }
  4100. if (pEspService && pCompTree)
  4101. pEspService->addPropTree(sb.str(), pCompTree->queryPropTree(sb.str()));
  4102. //If we are adding, just consider the first selection.
  4103. break;
  4104. }
  4105. if (!flag)
  4106. {
  4107. IPropertyTree* pEspService = pEnvRoot->queryPropTree(xpath.str());
  4108. IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName());
  4109. StringBuffer sbNewName(XML_TAG_ESPBINDING);
  4110. xpath.clear().appendf("%s[@name='%s']/EspBinding", processName, espName);
  4111. getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
  4112. xpath.clear().append(XML_TAG_ESPBINDING).append("/").append(XML_ATTR_NAME);
  4113. pCompTree->setProp(xpath.str(), sbNewName);
  4114. resp.setNewName(sbNewName);
  4115. if (pEspService && pCompTree)
  4116. pEspService->addPropTree(XML_TAG_ESPBINDING, pCompTree->queryPropTree(XML_TAG_ESPBINDING));
  4117. }
  4118. resp.setStatus("true");
  4119. }
  4120. else if (!strcmp(operation, "Delete"))
  4121. {
  4122. Owned<IPropertyTreeIterator> iterItems = pBindings->getElements("Item");
  4123. bool deleteAll = true;
  4124. IPropertyTreePtrArray bindings;
  4125. ForEach (*iterItems)
  4126. {
  4127. IPropertyTree* pItem = &iterItems->query();
  4128. const char* bindingName = pItem->queryProp(XML_ATTR_NAME);
  4129. const char* params = pItem->queryProp("@params");
  4130. StringBuffer decodedParams(params);
  4131. decodedParams.replaceString("::", "\n");
  4132. Owned<IProperties> pParams = createProperties();
  4133. pParams->loadProps(decodedParams.str());
  4134. const char* pszCompType = pParams->queryProp("pcType");
  4135. const char* pszCompName = pParams->queryProp("pcName");
  4136. const char* pszSubType = pParams->queryProp("subType");
  4137. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  4138. xpath.clear().appendf("./Software/%s[@name='%s']", XML_TAG_ESPPROCESS, espName);
  4139. if (!strcmp(type, XML_TAG_ESPBINDING))
  4140. {
  4141. if (bindingName)
  4142. xpath.appendf("/EspBinding[@name='%s']", bindingName);
  4143. IPropertyTree* pEspBinding = pEnvRoot->queryPropTree(xpath.str());
  4144. StringBuffer sbMsg;
  4145. StringBuffer sbFullName(espName);
  4146. sbFullName.append("/").append(bindingName);
  4147. bool ret = checkComponentReferences(pEnvRoot, pEspBinding, sbFullName.str(), sbMsg);
  4148. if (ret)
  4149. bindings.push_back(pEspBinding);
  4150. else
  4151. {
  4152. deleteAll = false;
  4153. resp.setStatus(sbMsg.str());
  4154. break;
  4155. }
  4156. }
  4157. else
  4158. {
  4159. if (pszSubType && *pszSubType)
  4160. xpath.append("/").append(pszSubType);
  4161. const char* resource = pItem->queryProp("@resource");
  4162. if (resource)
  4163. xpath.appendf("[@resource='%s']", resource);
  4164. IPropertyTree* pSubType = pEnvRoot->queryPropTree(xpath.str());
  4165. String subType(xpath.str());
  4166. int idx = subType.lastIndexOf('/');
  4167. if (idx > 0)
  4168. {
  4169. String* tmpstr = subType.substring(0, idx);
  4170. xpath.clear().append(*tmpstr);
  4171. delete tmpstr;
  4172. }
  4173. if (pSubType)
  4174. pEnvRoot->queryPropTree(xpath.str())->removeTree(pSubType);
  4175. }
  4176. }
  4177. if (deleteAll)
  4178. {
  4179. xpath.clear().appendf("./Software/%s[@name='%s']", XML_TAG_ESPPROCESS, espName);
  4180. IPropertyTree* pEspService = pEnvRoot->queryPropTree(xpath.str());
  4181. int nBindings = bindings.size();
  4182. for (int i=0; i < nBindings; i++)
  4183. {
  4184. IPropertyTree* pBinding = bindings[i];
  4185. pEspService->removeTree(pBinding);
  4186. }
  4187. resp.setStatus("true");
  4188. }
  4189. }
  4190. return true;
  4191. }
  4192. bool CWsDeployFileInfo::handleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp)
  4193. {
  4194. synchronized block(m_mutex);
  4195. checkForRefresh(context, &req.getReqInfo(), true);
  4196. const char* xmlArg = req.getXmlArgs();
  4197. Owned<IPropertyTree> pParams = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  4198. const char* type = pParams->queryProp(XML_ATTR_TYPE);
  4199. const char* operation = req.getOperation();
  4200. StringBuffer sbNewName;
  4201. StringBuffer xpath;
  4202. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  4203. if (!strcmp(operation, "New"))
  4204. {
  4205. StringBuffer sbTemp;
  4206. IPropertyTree* pCompTree = createPTree(XML_TAG_HARDWARE);
  4207. generateHardwareHeaders(pEnvRoot, sbTemp, false, pCompTree);
  4208. StringBuffer sbNewName(type);
  4209. xpath.clear().appendf("%s", type);
  4210. getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_HARDWARE);
  4211. xpath.clear().append(type).append("/").append(XML_ATTR_NAME);
  4212. pCompTree->setProp(xpath.str(), sbNewName);
  4213. pEnvRoot->queryPropTree(XML_TAG_HARDWARE)->addPropTree(type, pCompTree->queryPropTree(type));
  4214. resp.setCompName(sbNewName.str());
  4215. resp.setStatus("true");
  4216. }
  4217. else if (!strcmp(operation, "NewRange"))
  4218. {
  4219. const char* prefix = pParams->queryProp("@prefix");
  4220. const char* domain = pParams->queryProp(XML_ATTR_DOMAIN);
  4221. const char* cType = pParams->queryProp(XML_ATTR_COMPUTERTYPE);
  4222. const char* startIP = pParams->queryProp("@startIP");
  4223. const char* endIP = pParams->queryProp("@endIP");
  4224. IPropertyTree* pComps = getNewRange(pEnvRoot, prefix, domain, cType, startIP, endIP);
  4225. if (m_bCloud)
  4226. {
  4227. StringBuffer sbMsg;
  4228. CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_UNLOCK_ENV, m_userWithLock.str(), "8015", pComps);
  4229. bool ret = lockCloud.start(sbMsg);
  4230. if (!ret || sbMsg.length())
  4231. {
  4232. resp.setStatus("false");
  4233. throw MakeStringException(-1, "Cannot add new range of computers as environment lock could not be obtained. Reason(s):\n%s", sbMsg.str());
  4234. }
  4235. }
  4236. if (pComps)
  4237. {
  4238. mergePTree(pEnvRoot->queryPropTree(XML_TAG_HARDWARE), pComps);
  4239. resp.setCompName(pComps->queryPropTree("Computer[1]")->queryProp(XML_ATTR_NAME));
  4240. }
  4241. resp.setStatus("true");
  4242. }
  4243. else if (!strcmp(operation, "Delete"))
  4244. {
  4245. StringBuffer refs;
  4246. StringBuffer refName;
  4247. Owned<IPropertyTreeIterator> iterComputers = pParams->getElements("Item");
  4248. ForEach (*iterComputers)
  4249. {
  4250. IPropertyTree* pComp = &iterComputers->query();
  4251. const char* name = pComp->queryProp(XML_ATTR_NAME);
  4252. if (!strcmp(type, XML_TAG_COMPUTER))
  4253. xpath.clear().appendf(XML_TAG_SOFTWARE"//["XML_ATTR_COMPUTER"=\"%s\"]", name);
  4254. else if (!strcmp(type, XML_TAG_COMPUTERTYPE))
  4255. xpath.clear().appendf(XML_TAG_HARDWARE"//["XML_ATTR_COMPUTERTYPE"=\"%s\"]", name);
  4256. else if (!strcmp(type, XML_TAG_DOMAIN))
  4257. xpath.clear().appendf(XML_TAG_HARDWARE"//["XML_ATTR_DOMAIN"=\"%s\"]", name);
  4258. else if (!strcmp(type, XML_TAG_SWITCH))
  4259. xpath.clear().appendf(XML_TAG_HARDWARE"//["XML_ATTR_SWITCH"=\"%s\"]", name);
  4260. Owned<IPropertyTreeIterator> iter = pEnvRoot->getElements(xpath.str());
  4261. ForEach(*iter)
  4262. {
  4263. IPropertyTree& pComp = iter->query();
  4264. const char* compName = pComp.queryProp(XML_ATTR_NAME);
  4265. const char* parentName = pComp.queryName();
  4266. refs.append("\n").append(parentName).append(" name=").append(compName);
  4267. }
  4268. if (refs.length())
  4269. {
  4270. refName.clear().append(name);
  4271. break;
  4272. }
  4273. }
  4274. if (refs.length())
  4275. throw MakeStringException(-1, "Cannot delete %s with name %s as it is being referenced by components: %s.", type, refName.str(), refs.str());
  4276. else
  4277. {
  4278. if (m_bCloud && !strcmp(type, XML_TAG_COMPUTER))
  4279. {
  4280. StringBuffer sb, sbMsg;
  4281. sb.append("<Computers>");
  4282. ForEach (*iterComputers)
  4283. {
  4284. IPropertyTree* pComp = &iterComputers->query();
  4285. xpath.clear().appendf(XML_TAG_HARDWARE"/%s["XML_ATTR_NAME"=\"%s\"]", type, pComp->queryProp(XML_ATTR_NAME));
  4286. IPropertyTree* pTree = pEnvRoot->queryPropTree(xpath.str());
  4287. sb.appendf("<Computer netAddress='%s'/>", pTree->queryProp(XML_ATTR_NETADDRESS));
  4288. }
  4289. sb.append("</Computers>");
  4290. Owned<IPropertyTree> pComputers = createPTreeFromXMLString(sb.str());
  4291. CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_LOCK_ENV, m_userWithLock.str(), "8015", pComputers);
  4292. bool ret = unlockCloud.start(sbMsg);
  4293. if (!ret || sbMsg.length())
  4294. throw MakeStringException(-1, "Cannot delete computers as they cannot be unlocked. Reason(s):\n%s", sbMsg.str());
  4295. }
  4296. ForEach (*iterComputers)
  4297. {
  4298. IPropertyTree* pComp = &iterComputers->query();
  4299. xpath.clear().appendf(XML_TAG_HARDWARE"/%s["XML_ATTR_NAME"=\"%s\"]", type, pComp->queryProp(XML_ATTR_NAME));
  4300. IPropertyTree* pTree = pEnvRoot->queryPropTree(xpath.str());
  4301. pEnvRoot->queryPropTree(XML_TAG_HARDWARE)->removeTree(pTree);
  4302. }
  4303. resp.setStatus("true");
  4304. }
  4305. }
  4306. return true;
  4307. }
  4308. bool CWsDeployFileInfo::handleTopology(IEspContext &context, IEspHandleTopologyRequest &req, IEspHandleTopologyResponse &resp)
  4309. {
  4310. synchronized block(m_mutex);
  4311. checkForRefresh(context, &req.getReqInfo(), true);
  4312. const char* xmlArg = req.getXmlArgs();
  4313. Owned<IPropertyTree> pParams = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  4314. const char* compType = pParams->queryProp("@compType");
  4315. const char* name = pParams->queryProp(XML_ATTR_NAME);
  4316. const char* newType = pParams->queryProp("@newType");
  4317. const char* operation = req.getOperation();
  4318. StringBuffer decodedParams( pParams->queryProp("@params") );
  4319. decodedParams.replaceString("::", "\n");
  4320. Owned<IProperties> pTopParams = createProperties();
  4321. pTopParams->loadProps(decodedParams.str());
  4322. StringBuffer buf("Software/Topology");
  4323. for (int i = 3; i >= 0; i--)
  4324. {
  4325. StringBuffer sb;
  4326. sb.appendf("inner%d_name", i);
  4327. const char* sbName = pTopParams->queryProp(sb.str());
  4328. if (sbName)
  4329. {
  4330. if (strstr(sbName, "EclCCServerProcess") == sbName ||
  4331. strstr(sbName, "EclServerProcess") == sbName ||
  4332. strstr(sbName, "EclAgentProcess") == sbName ||
  4333. strstr(sbName, "EclSchedulerProcess") == sbName)
  4334. {
  4335. StringBuffer sbEcl(sbName);
  4336. if (strstr(sbName, " - "))
  4337. sbEcl.replaceString(" - ", "[@process='").append("']");
  4338. else if (strstr(sbName, " -"))
  4339. sbEcl.replaceString(" -", "[@process='").append("']");
  4340. buf.append("/").append(sbEcl);
  4341. }
  4342. else if (strstr(sbName, "Cluster") == sbName)
  4343. {
  4344. StringBuffer sbCl(sbName);
  4345. if (strstr(sbName, " - "))
  4346. sbCl.replaceString(" - ", "[@name='").append("']");
  4347. else if (strstr(sbName, " -"))
  4348. sbCl.replaceString(" -", "[@name='").append("']");
  4349. buf.append("/").append(sbCl);
  4350. }
  4351. else if (strstr(sbName, XML_TAG_THORCLUSTER) == sbName)
  4352. buf.append("/ThorCluster");
  4353. else if (strstr(sbName, XML_TAG_ROXIECLUSTER) == sbName)
  4354. buf.append("/RoxieCluster");
  4355. else if (buf.str()[buf.length() - 1] != ']')
  4356. buf.appendf("[@%s='%s']", sbName, pTopParams->queryProp(sb.replaceString("_name", "_value").str()));
  4357. }
  4358. }
  4359. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  4360. if (!strcmp(operation, "Add"))
  4361. {
  4362. StringBuffer sbNewType(newType);
  4363. if (!strcmp(newType, "EclCCServer"))
  4364. sbNewType.clear().append(XML_TAG_ECLCCSERVERPROCESS);
  4365. else if (!strcmp(newType, "EclServer"))
  4366. sbNewType.clear().append(XML_TAG_ECLSERVERPROCESS);
  4367. else if (!strcmp(newType, "EclAgent"))
  4368. sbNewType.clear().append(XML_TAG_ECLAGENTPROCESS);
  4369. else if (!strcmp(newType, "EclScheduler"))
  4370. sbNewType.clear().append(XML_TAG_ECLSCHEDULERPROCESS);
  4371. else if (!strcmp(newType, "Thor"))
  4372. sbNewType.clear().append(XML_TAG_THORCLUSTER);
  4373. else if (!strcmp(newType, "Roxie"))
  4374. sbNewType.clear().append(XML_TAG_ROXIECLUSTER);
  4375. IPropertyTree* pNode = createPTree(sbNewType.str());
  4376. if (!strcmp(sbNewType.str(), XML_TAG_ECLCCSERVERPROCESS) ||
  4377. !strcmp(sbNewType.str(), XML_TAG_ECLSERVERPROCESS) ||
  4378. !strcmp(sbNewType.str(), XML_TAG_ECLAGENTPROCESS) ||
  4379. !strcmp(sbNewType.str(), XML_TAG_ECLSCHEDULERPROCESS) ||
  4380. !strcmp(sbNewType.str(), XML_TAG_THORCLUSTER) ||
  4381. !strcmp(sbNewType.str(), XML_TAG_ROXIECLUSTER))
  4382. pNode->addProp(XML_ATTR_PROCESS, "");
  4383. else if (!strcmp(sbNewType.str(), XML_TAG_CLUSTER))
  4384. {
  4385. pNode->addProp(XML_ATTR_NAME, "");
  4386. pNode->addProp(XML_ATTR_PREFIX, "");
  4387. }
  4388. IPropertyTree* pTopology = pEnvRoot->queryPropTree(buf.str());
  4389. if (pTopology)
  4390. pTopology->addPropTree(sbNewType.str(), pNode);
  4391. resp.setStatus("true");
  4392. }
  4393. else if (!strcmp(operation, "Delete"))
  4394. {
  4395. String sParent(buf.str());
  4396. StringBuffer sbParent(XML_TAG_SOFTWARE"/"XML_TAG_TOPOLOGY);
  4397. int idx = sParent.lastIndexOf('/');
  4398. if (idx > 0)
  4399. {
  4400. String* tmpstr = sParent.substring(0, idx);
  4401. sbParent.clear().append(*tmpstr);
  4402. delete tmpstr;
  4403. }
  4404. IPropertyTree* pTopology = pEnvRoot->queryPropTree(sbParent);
  4405. IPropertyTree* pDel = pEnvRoot->queryPropTree(buf.str());
  4406. if (pTopology && pDel)
  4407. pTopology->removeTree(pDel);
  4408. resp.setStatus("true");
  4409. }
  4410. return true;
  4411. }
  4412. bool CWsDeployFileInfo::handleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp)
  4413. {
  4414. synchronized block(m_mutex);
  4415. checkForRefresh(context, &req.getReqInfo(), true);
  4416. const char* xmlArg = req.getXmlArgs();
  4417. const char* operation = req.getOperation();
  4418. StringBuffer xpath;
  4419. StringBuffer sMsg;
  4420. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  4421. bool retVal = handleThorTopologyOp(pEnvRoot, operation, xmlArg, sMsg);
  4422. resp.setStatus(retVal? "true" : sMsg.str());
  4423. return true;
  4424. }
  4425. bool CWsDeployFileInfo::handleRows(IEspContext &context, IEspHandleRowsRequest &req, IEspHandleRowsResponse &resp)
  4426. {
  4427. synchronized block(m_mutex);
  4428. checkForRefresh(context, &req.getReqInfo(), true);
  4429. const char* xmlArg = req.getXmlArgs();
  4430. Owned<IPropertyTree> pParams = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>");
  4431. const char* buildSet = pParams->queryProp(XML_ATTR_BUILDSET);
  4432. const char* name = pParams->queryProp("@compName");
  4433. const char* rowType = pParams->queryProp("@rowType");
  4434. const char* operation = req.getOperation();
  4435. StringBuffer sbNewName;
  4436. StringBuffer xpath;
  4437. Owned<IPropertyTreeIterator> buildSetIter;
  4438. IPropertyTree* pBuildSet = NULL;
  4439. const char* buildSetName = NULL;
  4440. const char* processName = NULL;
  4441. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  4442. if (strcmp(name, "Directories"))
  4443. {
  4444. xpath.appendf("./Programs/Build/BuildSet[@name=\"%s\"]", buildSet);
  4445. buildSetIter.setown(pEnvRoot->getElements(xpath.str()));
  4446. buildSetIter->first();
  4447. pBuildSet = &buildSetIter->query();
  4448. buildSetName = pBuildSet->queryProp(XML_ATTR_NAME);
  4449. processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  4450. }
  4451. StringBuffer buildSetPath;
  4452. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  4453. IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName());
  4454. if (!strcmp(operation, "Add"))
  4455. {
  4456. if (!strcmp(name, "Directories"))
  4457. {
  4458. xpath.clear().appendf("Software/Directories/Category[@name='%s']", rowType);
  4459. IPropertyTree* pCat = pEnvRoot->queryPropTree(xpath.str());
  4460. if (pCat)
  4461. {
  4462. IPropertyTree* pOver = pCat->queryPropTree("Override[@component=''][@dir=''][@instance='']");
  4463. if (!pOver)
  4464. {
  4465. pOver = pCat->addPropTree("Override", createPTree());
  4466. pOver->addProp("@component", "");
  4467. pOver->addProp("@dir", "");
  4468. pOver->addProp("@instance", "");
  4469. }
  4470. }
  4471. }
  4472. else
  4473. {
  4474. xpath.clear().appendf("./Software/%s[@name='%s']", processName, name);
  4475. Owned<IPropertyTreeIterator> rows = pParams->getElements("Row");
  4476. bool flag = false;
  4477. ForEach (*rows)
  4478. {
  4479. flag = true;
  4480. IPropertyTree* pRow = &rows->query();
  4481. const char* params = pRow->queryProp("@params");
  4482. StringBuffer decodedParams(params);
  4483. decodedParams.replaceString("::", "\n");
  4484. Owned<IProperties> pParams = createProperties();
  4485. pParams->loadProps(decodedParams.str());
  4486. const char* pszCompType = pParams->queryProp("pcType");
  4487. const char* pszCompName = pParams->queryProp("pcName");
  4488. const char* pszSubType = pParams->queryProp("subType");
  4489. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  4490. StringBuffer sbParent;
  4491. if (pszSubType && *pszSubType)
  4492. {
  4493. String subType(pszSubType);
  4494. int idx = subType.lastIndexOf('/');
  4495. if (idx > 0)
  4496. {
  4497. String* tmpstr = subType.substring(0, idx);
  4498. xpath.append("/").append(*tmpstr);
  4499. sbParent.append(*tmpstr);
  4500. delete tmpstr;
  4501. }
  4502. else
  4503. {
  4504. xpath.append("/").append(pszSubType);
  4505. sbParent.append(pszSubType);
  4506. if (pszSubTypeKey && *pszSubTypeKey)
  4507. xpath.append(pszSubTypeKey);
  4508. }
  4509. }
  4510. IPropertyTree* pComponent = pEnvRoot->queryPropTree(xpath.str());
  4511. IPropertyTree* pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, buildSetName, m_pService->getCfg(), m_pService->getName());
  4512. StringBuffer sb(rowType);
  4513. if (!strncmp(sb.str(), "_", 1))
  4514. sb.remove(0, 1);
  4515. StringBuffer s;
  4516. s.appendf("xs:element//*[@name=\"%s\"]//*[@name=\"%s\"]//xs:attribute[@name='name']", sbParent.str(), rowType);
  4517. IPropertyTree* pt = pSchema->queryPropTree(s.str());
  4518. if (pt && pt->hasProp("@type"))
  4519. {
  4520. const char* px = pt->queryProp("@type");
  4521. if (!strcmp(px, "xs:string"))
  4522. {
  4523. StringBuffer sbNewName(rowType);
  4524. xpath.clear().appendf("%s[@name='%s']/%s", processName, name, sbParent.str());
  4525. getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
  4526. pCompTree->setProp(sb.str(), sbNewName);
  4527. resp.setCompName(sbNewName);
  4528. }
  4529. }
  4530. if (pComponent && pCompTree)
  4531. pComponent->addPropTree(rowType, pCompTree->queryPropTree(rowType));
  4532. //If we are adding, just consider the first selection.
  4533. break;
  4534. }
  4535. if (!flag)
  4536. {
  4537. if (pCompTree->queryPropTree(rowType))
  4538. {
  4539. if (strcmp(rowType, "Notes"))
  4540. {
  4541. StringBuffer sbNewName(rowType);
  4542. xpath.clear().appendf("%s[@name]", rowType);
  4543. if (pCompTree->hasProp(xpath.str()))
  4544. {
  4545. xpath.clear().appendf("%s[@name='%s']/%s", processName, name, rowType);
  4546. getUniqueName(pEnvRoot, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
  4547. pCompTree->queryPropTree(rowType)->setProp(XML_ATTR_NAME, sbNewName);
  4548. resp.setCompName(sbNewName.str());
  4549. }
  4550. }
  4551. else
  4552. {
  4553. IPropertyTree* pNotes = pCompTree->queryPropTree(rowType);
  4554. if (pNotes->hasProp("@computer"))
  4555. pNotes->setProp("@computer", m_userIp.str());
  4556. if (pNotes->hasProp("@user"))
  4557. pNotes->setProp("@user", "");
  4558. if (pNotes->hasProp("@date"))
  4559. {
  4560. CDateTime dt;
  4561. StringBuffer tmp;
  4562. dt.setNow();
  4563. tmp.clear();
  4564. unsigned mo, da, yr;
  4565. dt.getDate(yr, mo, da, true);
  4566. tmp.appendf("%d/%d/%d ", mo, da, yr);
  4567. dt.getTimeString(tmp, true);
  4568. pNotes->setProp("@date", tmp.str());
  4569. resp.setCompName(tmp.str());
  4570. }
  4571. }
  4572. xpath.clear().appendf("./Software/%s[@name='%s']", processName, name);
  4573. IPropertyTree* pComponent = pEnvRoot->queryPropTree(xpath.str());
  4574. if (pComponent)
  4575. pComponent->addPropTree(rowType, pCompTree->queryPropTree(rowType));
  4576. }
  4577. }
  4578. }
  4579. resp.setStatus("true");
  4580. }
  4581. else if (!strcmp(operation, "Delete"))
  4582. {
  4583. if (!strcmp(name, "Directories"))
  4584. xpath.clear().appendf("./Software/Directories/Category[@name='%s']", rowType);
  4585. else
  4586. xpath.clear().appendf("./Software/%s[@name='%s']", processName, name);
  4587. IPropertyTree* pComponent = pEnvRoot->queryPropTree(xpath.str());
  4588. Owned<IPropertyTreeIterator> iterRows = pParams->getElements("Row");
  4589. ForEach (*iterRows)
  4590. {
  4591. IPropertyTree* pRow = &iterRows->query();
  4592. const char* rowName = pRow->queryProp("@rowName");
  4593. if (!strcmp(name, "Directories"))
  4594. {
  4595. const char* compType = pRow->queryProp("@compType");
  4596. xpath.clear().appendf("Override[@component='%s'][@instance='%s']", compType, rowName);
  4597. }
  4598. else
  4599. {
  4600. if (!strcmp(rowType, "Notes"))
  4601. {
  4602. const char* rowDate = pRow->queryProp("@rowDate");
  4603. if (!rowDate || !*rowDate)
  4604. continue;
  4605. xpath.clear().appendf("%s[@date='%s']", rowType, rowDate);
  4606. }
  4607. else if (rowName && *rowName)
  4608. xpath.clear().appendf("%s[@name='%s']", rowType, rowName);
  4609. else
  4610. {
  4611. const char* params = pRow->queryProp("@params");
  4612. StringBuffer decodedParams(params);
  4613. decodedParams.replaceString("::", "\n");
  4614. Owned<IProperties> pParams = createProperties();
  4615. pParams->loadProps(decodedParams.str());
  4616. const char* pszCompType = pParams->queryProp("pcType");
  4617. const char* pszCompName = pParams->queryProp("pcName");
  4618. const char* pszSubType = pParams->queryProp("subType");
  4619. const char* pszSubTypeKey = pParams->queryProp("subTypeKey");
  4620. StringBuffer sbParent;
  4621. if (pszSubType && *pszSubType)
  4622. {
  4623. String subType(pszSubType);
  4624. xpath.clear().append(pszSubType);
  4625. if (pszSubTypeKey && *pszSubTypeKey)
  4626. xpath.append(pszSubTypeKey);
  4627. }
  4628. }
  4629. }
  4630. if (pComponent)
  4631. pComponent->removeTree(pComponent->queryPropTree(xpath.str()));
  4632. }
  4633. resp.setCompName("");
  4634. resp.setStatus("true");
  4635. }
  4636. return true;
  4637. }
  4638. IPropertyTree* CWsDeployFileInfo::findComponentForFolder(IPropertyTree* pFolder, IPropertyTree* pEnvSoftware)
  4639. {
  4640. //Folder's @params has string of the form:
  4641. //"comp=EspProcess&name=esp&inst=s1&computer=2wd20"
  4642. //
  4643. StringBuffer decodedParams( pFolder->queryProp("@params") );
  4644. decodedParams.replace('&', '\n');
  4645. Owned<IProperties> pParams = createProperties();
  4646. pParams->loadProps(decodedParams.str());
  4647. const char* comp = pParams->queryProp("comp");
  4648. const char* name = pParams->queryProp("name");
  4649. if (!(comp && *comp && name && *name))
  4650. throw MakeStringException(-1, "Invalid parameters");
  4651. StringBuffer xpath;
  4652. xpath.appendf("%s[@name='%s']", comp, name);
  4653. IPropertyTree* pComp = pEnvSoftware->queryPropTree(xpath.str());
  4654. if (!pComp)
  4655. throw MakeStringException(-1, "No such component in environment: '%s' named '%s'.", comp, name);
  4656. return pComp;
  4657. }
  4658. void CWsDeployFileInfo::addDeployableComponentAndInstances(IPropertyTree* pEnvRoot, IPropertyTree* pComp,
  4659. IPropertyTree* pDst, IPropertyTree* pFolder,
  4660. const char* displayType)
  4661. {
  4662. const char* comp = pComp->queryName();
  4663. const char* name = pComp->queryProp(XML_ATTR_NAME);
  4664. if (!name || !*name)
  4665. throw MakeStringException(-1, "The environment has an incomplete definition for a '%s'!", comp);
  4666. const char* build= pComp->queryProp(XML_ATTR_BUILD);
  4667. const char* buildSet= pComp->queryProp(XML_ATTR_BUILDSET);
  4668. if (!build || !*build)
  4669. throw MakeStringException(-1, "%s '%s' does not have any build defined!", comp, name);
  4670. if (!buildSet || !*buildSet)
  4671. throw MakeStringException(-1, "%s '%s' does not have any build set defined!", comp, name);
  4672. StringBuffer xpath;
  4673. xpath.appendf("Programs/Build[@name='%s']/BuildSet[@name='%s']", build, buildSet);
  4674. IPropertyTree* pBuildSetNode = pEnvRoot->queryPropTree(xpath.str());
  4675. if (!pBuildSetNode)
  4676. throw MakeStringException(-1, "Build %s or build set %s is not defined!", build, buildSet);
  4677. const char* deployable = pBuildSetNode->queryProp("@deployable");
  4678. if (!deployable || (0!=strcmp(deployable, "no") && 0!=strcmp(deployable, "false")))
  4679. {
  4680. char achDisplayType[132];//long enough to hold any expanded type whatsoever
  4681. if (!displayType)
  4682. {
  4683. GetDisplayProcessName(pComp->queryName(), achDisplayType);
  4684. displayType = achDisplayType;
  4685. }
  4686. const bool bDeployAllInstances = !pFolder || pFolder->getPropBool("@selected", false);
  4687. if (bDeployAllInstances)
  4688. {
  4689. //add its instances
  4690. Owned<IPropertyTreeIterator> iInst = pComp->getElements("*");
  4691. ForEach(*iInst)
  4692. {
  4693. IPropertyTree* pInstance = &iInst->query();
  4694. const char* instType = pInstance->queryName();
  4695. if (instType && (!strcmp(instType, XML_TAG_INSTANCE) || !strcmp(instType, XML_TAG_ROXIE_SERVER)))
  4696. {
  4697. const char* instName = pInstance->queryProp(XML_ATTR_NAME);
  4698. const char* computer = pInstance->queryProp(XML_ATTR_COMPUTER);
  4699. if (instName && *instName && computer && *computer)
  4700. addInstance(pDst, comp, displayType, name, build, instType, instName, computer);
  4701. }
  4702. }//ForEach(*iInst)
  4703. }
  4704. else
  4705. {
  4706. //pFolder exists and is not selected so deploy selected instances
  4707. Owned<IPropertyTreeIterator> iLink = pFolder->getElements("*[@selected='true']");
  4708. ForEach(*iLink)
  4709. {
  4710. IPropertyTree* pLink = &iLink->query();
  4711. const char* params = pLink->queryProp("@params");
  4712. if (params)
  4713. {
  4714. // pFolder's @params has string of the form: "comp=EspProcess&amp;name=esp&amp;instType=Instance&amp;inst=s1&amp;computer=2wd20"
  4715. //
  4716. StringBuffer decodedParams( params );
  4717. decodedParams.replace('&', '\n');
  4718. Owned<IProperties> pParams = createProperties();
  4719. pParams->loadProps( decodedParams.str() );
  4720. const char* instType = pParams->queryProp("instType");
  4721. const char* instName = pParams->queryProp("inst");
  4722. const char* computer = pParams->queryProp(TAG_COMPUTER);
  4723. if (instType && *instType && instName && *instName && computer && *computer)
  4724. {
  4725. StringBuffer xpath;
  4726. xpath.appendf("%s[@name='%s']", instType, instName);
  4727. IPropertyTree* pInstNode = pComp->queryPropTree(xpath.str());
  4728. if (!pInstNode)
  4729. throw MakeStringException(-1, "%s '%s' does not have any '%s' named %s!", displayType, comp, instType, instName);
  4730. addInstance(pDst, comp, displayType, name, build, instType, instName, computer);
  4731. }
  4732. }
  4733. }
  4734. }
  4735. }
  4736. }
  4737. void CWsDeployFileInfo::addInstance(IPropertyTree* pDst, const char* comp, const char* displayType,
  4738. const char* compName, const char* build, const char* instType,
  4739. const char* instName, const char* computer)
  4740. {
  4741. IPropertyTree* pCompNode = pDst->addPropTree( XML_TAG_COMPONENT, createPTree() );
  4742. pCompNode->addProp("Type", comp);
  4743. pCompNode->addProp("DisplayType", displayType);
  4744. pCompNode->addProp("Name", compName);
  4745. pCompNode->addProp("Build", build);
  4746. pCompNode->addProp("InstanceType", instType);
  4747. pCompNode->addProp("Instance", instName);
  4748. pCompNode->addProp("Computer", computer);
  4749. }
  4750. //---------------------------------------------------------------------------
  4751. // GetDisplayProcessName
  4752. //---------------------------------------------------------------------------
  4753. const char* CWsDeployFileInfo::GetDisplayProcessName(const char* processName, char* buf) const
  4754. {
  4755. //produces "LDAPServerProcess" as "LDAP Server" and "EspService" as "Esp Service", etc.
  4756. if (!strcmp(processName, XML_TAG_ESPPROCESS))
  4757. return strcpy(buf, "ESP Server");
  4758. else
  4759. {
  4760. const char* begin = buf;
  4761. const char* end = strstr(processName, "Process");
  4762. if (!end)
  4763. end = processName + strlen(processName);
  4764. *buf++ = *processName++;
  4765. bool bLower = false;
  4766. while (processName < end)
  4767. {
  4768. char ch = *processName;
  4769. if (isupper(ch))
  4770. {
  4771. if (bLower || //last char was uppercase or the following character is lowercase?
  4772. ((processName+1 < end) && islower(*(processName+1))))
  4773. {
  4774. *buf++ = ' ';
  4775. }
  4776. bLower = false;
  4777. }
  4778. else
  4779. bLower = true;
  4780. *buf++ = *processName++;
  4781. }
  4782. *buf = '\0';
  4783. return begin;
  4784. }
  4785. }
  4786. void CWsDeployFileInfo::setFilePath(StringBuffer &filePath, const char* targetName)
  4787. {
  4788. filePath.clear().append(CONFIG_SOURCE_DIR);
  4789. if (filePath.charAt(filePath.length() - 1) != PATHSEPCHAR)
  4790. filePath.append(PATHSEPCHAR);
  4791. filePath.append(targetName);
  4792. }
  4793. void CWsDeployFileInfo::updateConfigFromFile()
  4794. {
  4795. StringBuffer sbxml;
  4796. synchronized block(m_mutex);
  4797. if (m_pFileIO.get() != NULL)
  4798. {
  4799. m_pFileIO.clear();
  4800. }
  4801. if (m_lastSaved.isNull())
  4802. {
  4803. m_lastSaved.setNow();
  4804. }
  4805. m_pFileIO.setown(m_pFile->open(IFOread));
  4806. Owned <IPropertyTree> pTree = createPTree(*m_pFileIO);
  4807. toXML(pTree, sbxml.clear());
  4808. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  4809. m_constEnvRdOnly.clear();
  4810. m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sbxml.str()));
  4811. m_lastSaved.clear();
  4812. m_lastSaved.setNow();
  4813. }
  4814. bool CWsDeployFileInfo::deploy(IEspContext &context, IEspDeployRequest& req, IEspDeployResponse& resp)
  4815. {
  4816. synchronized block(m_mutex);
  4817. checkForRefresh(context, &req.getReqInfo(), true);
  4818. resp.setComponent("WsDeploy");
  4819. resp.setCommand("Deploy");
  4820. StringBuffer deployResult;
  4821. IConstDeployInfo& depInfo = req.getDeploy();
  4822. IArrayOf<IConstComponent>& components = depInfo.getComponents();
  4823. unsigned int nComps = components.ordinality();
  4824. if (nComps == 0)
  4825. {
  4826. resp.setStatus( "Please select at least one component to deploy!" );
  4827. CDeployOptions& depOptions = dynamic_cast<CDeployOptions&>( depInfo.getOptions() );
  4828. depOptions.serializeStruct(&context,deployResult, "Options");
  4829. }
  4830. else
  4831. {
  4832. CWsDeployEngine depEngine(*m_pService, req.getDeploy(),&context);
  4833. depEngine.deploy();
  4834. Owned<IPropertyTree> pDeployResult = depEngine.getDeployResult();
  4835. IPropertyTree* pComponents = pDeployResult->queryPropTree("Components");
  4836. toXML(pComponents, deployResult, false);
  4837. IPropertyTree* pOptions = pDeployResult->queryPropTree("Options");
  4838. toXML(pOptions, deployResult, false);
  4839. resp.setStatus( depEngine.getDeployStatus() );
  4840. }
  4841. resp.setDeploy( deployResult.str() );
  4842. return true;
  4843. }
  4844. bool CWsDeployExCE::onInit(IEspContext &context, IEspEmptyRequest& req, IEspInitResponse& resp)
  4845. {
  4846. resp.setComponent("WsDeploy");
  4847. resp.setCommand("Init");
  4848. return true;
  4849. }
  4850. //the following method must be called with ownership of m_mutex
  4851. //
  4852. void CWsDeployFileInfo::generateGraph(IEspContext &context, IConstWsDeployReqInfo *reqInfo)
  4853. {
  4854. {
  4855. synchronized block(m_mutex);
  4856. checkForRefresh(context, reqInfo, true);
  4857. }
  4858. if (!m_pEnvXml)
  4859. {
  4860. Owned<IPropertyTree> pEnvTree = getEnvTree(context, reqInfo);
  4861. m_pEnvXml.set(new SCMStringBuffer());
  4862. toXML(pEnvTree, m_pEnvXml->s, false);
  4863. }
  4864. m_pGraphXml.set(new SCMStringBuffer());
  4865. xsltTransform(m_pEnvXml->str(), StringBuffer(getCFD()).append("xslt/graph_env.xslt").str(), NULL, m_pGraphXml->s);
  4866. }
  4867. //---------------------------------------------------------------------------
  4868. // onGraph
  4869. //---------------------------------------------------------------------------
  4870. bool CWsDeployFileInfo::graph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp)
  4871. {
  4872. synchronized block(m_mutex);
  4873. if (!m_pGraphXml)
  4874. generateGraph(context, NULL);
  4875. resp.setGraphContainer(m_pGraphXml->str());
  4876. return true;
  4877. }
  4878. void CWsDeployFileInfo::getNavigationData(IEspContext &context, IPropertyTree* pData)
  4879. {
  4880. try
  4881. {
  4882. synchronized block(m_mutex);
  4883. if (m_envFile.length())
  4884. {
  4885. if (!m_userWithLock.length())
  4886. {
  4887. context.getUserID(m_userWithLock);
  4888. context.getPeer(m_userIp);
  4889. }
  4890. else
  4891. {
  4892. StringBuffer sbName, sbUserIp;
  4893. context.getUserID(sbName);
  4894. context.getPeer(sbUserIp);
  4895. if (strcmp(sbName.str(), m_userWithLock.str()) || strcmp(sbUserIp.str(), m_userIp.str()))
  4896. throw MakeStringException(-1, "A user on machine %s is accessing the file. Please try again later.", m_userIp.str());
  4897. }
  4898. initFileInfo(false);
  4899. }
  4900. if (!m_pNavTree)
  4901. {
  4902. if (!m_pEnvXml)
  4903. {
  4904. Owned<IPropertyTree> pEnvTree = getEnvTree(context, NULL);
  4905. m_pEnvXml.set(new SCMStringBuffer());
  4906. toXML(pEnvTree, m_pEnvXml->s, false);
  4907. }
  4908. m_pNavTree.setown(getEnvTree(context, NULL));
  4909. }
  4910. pData->setProp("@viewType", "tree");
  4911. mergePTree(pData, m_pNavTree);
  4912. }
  4913. catch(IException*e)
  4914. {
  4915. StringBuffer sErrMsg;
  4916. e->errorMessage(sErrMsg);
  4917. e->Release();
  4918. }
  4919. catch(...)
  4920. {
  4921. }
  4922. }
  4923. void CWsDeployFileInfo::saveEnvironment(IEspContext* pContext, IConstWsDeployReqInfo *reqInfo, StringBuffer& errMsg, bool saveAs)
  4924. {
  4925. if (m_envFile.length())
  4926. {
  4927. Owned<IPropertyTree> pEnvRoot;
  4928. StringBuffer valerrs;
  4929. try
  4930. {
  4931. if (!saveAs || (saveAs && m_Environment))
  4932. {
  4933. pEnvRoot.setown(&m_Environment->getPTree());
  4934. validateEnv((IConstEnvironment*)m_Environment, false);
  4935. }
  4936. else if (saveAs)
  4937. {
  4938. setSkipNotification(true);
  4939. pEnvRoot.setown(&m_constEnvRdOnly->getPTree());
  4940. validateEnv(m_constEnvRdOnly, false);
  4941. }
  4942. }
  4943. catch(IException* e)
  4944. {
  4945. e->errorMessage(valerrs);
  4946. e->Release();
  4947. }
  4948. //save and write to backup
  4949. StringBuffer sXML;
  4950. StringBuffer tmp;
  4951. StringBuffer dtStr;
  4952. CDateTime dt;
  4953. dt.setNow();
  4954. dt.getString(tmp.clear());
  4955. sXML.appendf("<"XML_HEADER">\n<!-- Edited with ConfigMgr on ip %s on %s -->\n", m_userIp.str(), tmp.str());
  4956. toXML(pEnvRoot, sXML, 0, XML_SortTags | XML_Format);
  4957. if (m_bCloud && pContext)
  4958. {
  4959. StringBuffer sbName, sbUserIp, sbMsg;
  4960. if (reqInfo)
  4961. sbName.clear().append(reqInfo->getUserId());
  4962. pContext->getPeer(sbUserIp);
  4963. CCloudActionHandler saveCloud(this, CLOUD_SAVE_ENV, CLOUD_ROLLBACK_ENV, sbName.str(), "8015", NULL);
  4964. StringBuffer tick;
  4965. tick.appendf("%d", msTick());
  4966. saveCloud.setSaveActionParams(sXML.str(), tick.str());
  4967. bool ret = saveCloud.start(sbMsg);
  4968. if (!ret || sbMsg.length())
  4969. throw MakeStringException(0, "Environment could not be successfully saved. Reason(s):\n%s", sbMsg.str());
  4970. }
  4971. try
  4972. {
  4973. if (m_pFile.get())
  4974. {
  4975. StringBuffer sb;
  4976. if (!checkDirExists(m_pService->getBackupDir()))
  4977. recursiveCreateDirectory(m_pService->getBackupDir());
  4978. while(true)
  4979. {
  4980. String strEnvFile(m_envFile);
  4981. int idx = strEnvFile.lastIndexOf('/');
  4982. if (idx <= 0)
  4983. idx = strEnvFile.lastIndexOf('\\');
  4984. String* tmpstr = strEnvFile.substring(idx+1);
  4985. sb.clear().append(m_pService->getBackupDir()).append(PATHSEPCHAR).append(*tmpstr);
  4986. delete tmpstr;
  4987. dt.setNow();
  4988. tmp.clear();
  4989. dtStr.clear();
  4990. dt.getDateString(tmp, true);
  4991. tmp.append("_");
  4992. dt.getTimeString(tmp, true);
  4993. dtStr.append(".").append(tmp);
  4994. dtStr.replaceString("-","_");
  4995. dtStr.replaceString(":","_");
  4996. String ext(sb);
  4997. idx = ext.lastIndexOf(PATHSEPCHAR);
  4998. if(ext.indexOf('.', idx > 0 ? idx : 0) != -1)
  4999. sb.insert(ext.lastIndexOf('.'), dtStr.str());
  5000. else
  5001. sb.append(dtStr.str());
  5002. if (checkFileExists(sb))
  5003. continue;
  5004. else
  5005. {
  5006. Owned<IFile> pFile(createIFile(sb.str()));
  5007. setSkipNotification(true);
  5008. copyFile(pFile, m_pFile, 0x100000);
  5009. break;
  5010. }
  5011. }
  5012. }
  5013. }
  5014. catch(IException* e)
  5015. {
  5016. //ignore any attempts to create the backup
  5017. e->Release();
  5018. }
  5019. if (!m_pFile.get())
  5020. m_pFile.setown(createIFile(m_envFile));
  5021. m_pFileIO.clear();
  5022. m_pFileIO.setown(m_pFile->open(IFOcreaterw));
  5023. m_pFileIO->write(0, sXML.length(), sXML.str());
  5024. m_lastSaved.clear();
  5025. m_lastSaved.setNow();
  5026. //reset the readonly tree
  5027. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  5028. m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sXML.str()));
  5029. if (valerrs.length())
  5030. errMsg.appendf("CWsDeployFileInfo::saveEnvironment:Save operation was successful. However the following exceptions were raised.\n%s", valerrs.str());
  5031. }
  5032. else
  5033. {
  5034. // JAKESMITH->SMEDA - apparently this code is legacy and can be deleted, please do + clearup related code if any
  5035. try
  5036. {
  5037. m_Environment->commit();
  5038. StringBuffer response;
  5039. initClusterGroups(false, response, NULL);
  5040. if (response.length())
  5041. PROGLOG("CWsDeployFileInfo::saveEnvironment: %s", response.str());
  5042. }
  5043. catch (IException* e)
  5044. {
  5045. StringBuffer sErrMsg;
  5046. e->errorMessage(sErrMsg);
  5047. e->Release();
  5048. /*typical error message when lock fails is as follows:
  5049. SDS: Lock timeout
  5050. SDS Reply Error : SDS: Lock timeout
  5051. Failed to establish lock to NewEnvironment/
  5052. Existing lock status: Locks on path: /NewEnvironment/
  5053. Endpoint |SessionId |ConnectionId |mode
  5054. 172.16.48.175:7254 |c00000038 |c0000003b |653
  5055. */
  5056. //if we can extract IP address of computer holding the lock then
  5057. //show a customized message.
  5058. //
  5059. //Retrieve IP address of computer holding the lock...
  5060. char achHost[128] = "";
  5061. const char* p = strstr(sErrMsg.str(), "\n\n");
  5062. if (p && *(p+=2))
  5063. {
  5064. const char* q = strchr(p, ':');
  5065. if (q)
  5066. {
  5067. const int len = q-p;
  5068. strncpy(achHost, p, len);
  5069. achHost[len] = '\0';
  5070. }
  5071. }
  5072. //resolve hostname for this IP address
  5073. unsigned int addr = inet_addr(achHost);
  5074. struct hostent* hp = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
  5075. if (hp)
  5076. strcpy(achHost, hp->h_name);
  5077. StringBuffer sMsg;
  5078. sMsg.appendf("The environment definition in dali server "
  5079. "could not be opened for write access");
  5080. if (achHost[0])
  5081. sMsg.appendf(" \nbecause it is locked by computer '%s'.", achHost);
  5082. else
  5083. sMsg.append(":\n\n").append(sErrMsg);
  5084. throw MakeStringException(0, "%s", sMsg.str());
  5085. }
  5086. }
  5087. CConfigFileMonitorThread::getInstance()->addObserver(*this);
  5088. }
  5089. void CWsDeployFileInfo::unlockEnvironment(IEspContext* context, IConstWsDeployReqInfo *reqInfo, const char* xmlArg, StringBuffer& sbErrMsg, bool saveEnv)
  5090. {
  5091. if (m_bCloud)
  5092. {
  5093. StringBuffer sbMsg;
  5094. Owned<IPropertyTree> pComputers = createPTreeFromXMLString(xmlArg);
  5095. Owned<IPropertyTree> unlockComputers = createPTree("ComputerList");
  5096. Owned<IPropertyTree> lockComputers = createPTree("ComputerList");
  5097. Owned<IPropertyTreeIterator> iter;
  5098. StringBuffer xpath;
  5099. if (pComputers && pComputers->numChildren() && m_lockedNodesBeforeEnv.get() != NULL)
  5100. {
  5101. expandRange(pComputers);
  5102. iter.setown(pComputers->getElements("Computer"));
  5103. ForEach (*iter)
  5104. {
  5105. IPropertyTree* pComputer = &iter->query();
  5106. xpath.clear().appendf(XML_TAG_COMPUTER"["XML_ATTR_NETADDRESS"='%s']", pComputer->queryProp(XML_ATTR_NETADDRESS));
  5107. if (!m_lockedNodesBeforeEnv->queryPropTree(xpath.str()))
  5108. lockComputers->addPropTree(XML_TAG_COMPUTER, createPTreeFromIPT(pComputer));
  5109. }
  5110. }
  5111. if (!pComputers && m_lockedNodesBeforeEnv.get() != NULL)
  5112. unlockComputers.set(m_lockedNodesBeforeEnv);
  5113. else if (m_lockedNodesBeforeEnv.get() != NULL)
  5114. {
  5115. iter.setown(m_lockedNodesBeforeEnv->getElements("Computer"));
  5116. ForEach (*iter)
  5117. {
  5118. IPropertyTree* pComputer = &iter->query();
  5119. xpath.clear().appendf(XML_TAG_COMPUTER"["XML_ATTR_NETADDRESS"='%s']", pComputer->queryProp(XML_ATTR_NETADDRESS));
  5120. if (!pComputers->queryPropTree(xpath.str()))
  5121. unlockComputers->addPropTree(XML_TAG_COMPUTER, createPTreeFromIPT(pComputer));
  5122. }
  5123. }
  5124. CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", unlockComputers->numChildren() ? unlockComputers : NULL);
  5125. bool ret = unlockCloud.start(sbMsg);
  5126. if (!ret || sbMsg.length())
  5127. {
  5128. if (saveEnv)
  5129. sbErrMsg.append("Save operation is successful. However, ");
  5130. sbErrMsg.appendf("Write access to the Environment cannot be revoked. Reason(s):\n%s", sbMsg.str());
  5131. return;
  5132. }
  5133. else
  5134. {
  5135. Owned<IPropertyTreeIterator> iter = unlockComputers->getElements("Computer");
  5136. StringBuffer xpath;
  5137. ForEach (*iter)
  5138. {
  5139. IPropertyTree* pComputer = &iter->query();
  5140. xpath.clear().appendf(XML_TAG_COMPUTER"["XML_ATTR_NETADDRESS"='%s']", pComputer->queryProp(XML_ATTR_NETADDRESS));
  5141. IPropertyTree* pDelComputer = m_lockedNodesBeforeEnv->queryPropTree(xpath.str());
  5142. m_lockedNodesBeforeEnv->removeTree(pDelComputer);
  5143. }
  5144. }
  5145. if (lockComputers->numChildren())
  5146. {
  5147. CCloudActionHandler lockCloud(this, CLOUD_LOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", lockComputers);
  5148. ret = lockCloud.start(sbMsg.clear());
  5149. if (!ret || sbMsg.length())
  5150. {
  5151. if (saveEnv)
  5152. sbErrMsg.append("Save operation is successful. However, ");
  5153. sbErrMsg.appendf("Write access to the Environment could not be obtained. Reason(s):\n%s", sbMsg.str());
  5154. return;
  5155. }
  5156. }
  5157. }
  5158. m_Environment.clear();
  5159. StringBuffer sb(m_userWithLock);
  5160. sb.append(m_userIp);
  5161. CClientAliveThread* th = m_keepAliveHTable.getValue(sb.str());
  5162. if (th)
  5163. {
  5164. th->Release();
  5165. m_keepAliveHTable.remove(sb.str());
  5166. }
  5167. if (m_envFile.length() == 0)
  5168. {
  5169. Owned<IGroup> serverGroup = createIGroup(m_daliServer.str(), m_daliServerPort);
  5170. if (!serverGroup)
  5171. throw MakeStringException(0, "Could not instantiate IGroup");
  5172. if (!initClientProcess(serverGroup, DCR_Config, 0, NULL, NULL, 10000))
  5173. throw MakeStringException(0, "Could not initialize the client process");
  5174. m_pSubscription.clear();
  5175. m_pSubscription.setown( new CSdsSubscription(this) );
  5176. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  5177. m_constEnvRdOnly.setown(factory->openEnvironment());
  5178. }
  5179. m_constEnvRdOnly->clearCache();
  5180. m_userWithLock.clear();
  5181. m_userIp.clear();
  5182. Owned<IPropertyTree> pNavTree(getEnvTree(*context, reqInfo));
  5183. if (!areMatchingPTrees(pNavTree, m_pNavTree))
  5184. {
  5185. m_pEnvXml.clear();
  5186. m_pGraphXml.clear();
  5187. m_pNavTree.clear();
  5188. m_pNavTree.setown(getEnvTree(*context, reqInfo));
  5189. }
  5190. }
  5191. void CWsDeployFileInfo::checkForRefresh(IEspContext &context, IConstWsDeployReqInfo *reqInfo, bool checkWriteAccess)
  5192. {
  5193. StringBuffer sbUser, sbIp;
  5194. if (reqInfo)
  5195. sbUser.clear().append(reqInfo->getUserId());
  5196. context.getPeer(sbIp);
  5197. if (checkWriteAccess)
  5198. {
  5199. if (!m_Environment || m_userWithLock.length() == 0 || m_userIp.length() == 0)
  5200. throw MakeStringException(-1, "Cannot modify environment as it is currently in readonly mode");
  5201. else if (m_userWithLock.length() != 0 && m_userIp.length() != 0 && (strcmp(m_userWithLock.str(), sbUser.str()) || strcmp(m_userIp.str(), sbIp.str())))
  5202. throw MakeStringException(-1, "Cannot modify setting as environment is currently in use on machine '%s'", m_userIp.str());
  5203. }
  5204. }
  5205. IPropertyTree* CWsDeployFileInfo::queryComputersForCloud()
  5206. {
  5207. Owned<IPropertyTree> pEnvTree = m_Environment?&m_Environment->getPTree():&m_constEnvRdOnly->getPTree();
  5208. return pEnvTree->queryPropTree(XML_TAG_HARDWARE);
  5209. }
  5210. void CCloudTaskThread::main()
  5211. {
  5212. static Mutex m;
  5213. m.lock();
  5214. try
  5215. {
  5216. m_pTask->makeSoapCall();
  5217. }
  5218. catch(IException* e)
  5219. {
  5220. e->Release();
  5221. }
  5222. m.unlock();
  5223. }
  5224. CCloudTask* createCloudTask(CCloudActionHandler* pHandler, EnvAction eA, const char* ip)
  5225. {
  5226. return new CCloudTask(pHandler, eA, ip);
  5227. }
  5228. bool CWsDeployFileInfo::updateEnvironment(const char* xml)
  5229. {
  5230. if (!xml || !*xml)
  5231. return false;
  5232. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  5233. m_constEnvRdOnly.setown(factory->loadLocalEnvironment(xml));
  5234. return true;
  5235. }
  5236. bool CWsDeployFileInfo::isLocked(StringBuffer& sbUser, StringBuffer& sbIp)
  5237. {
  5238. if (m_userIp.length() != 0 && m_userWithLock.length() != 0)
  5239. {
  5240. sbUser.clear().append(m_userWithLock);
  5241. sbIp.clear().append(m_userIp);
  5242. return true;
  5243. }
  5244. return false;
  5245. }
  5246. bool CWsDeployFileInfo::buildEnvironment(IEspContext &context, IEspBuildEnvironmentRequest &req, IEspBuildEnvironmentResponse &resp)
  5247. {
  5248. synchronized block(m_mutex);
  5249. resp.setStatus("false");
  5250. const char* xml = req.getXmlArgs();
  5251. StringBuffer sbName, sbUserIp, msg, envXml;
  5252. sbName.clear().append(req.getReqInfo().getUserId());
  5253. context.getPeer(sbUserIp);
  5254. if(m_userWithLock.length() > 0)
  5255. {
  5256. if(!strcmp(sbName.str(), m_userWithLock.str()) || !strcmp(sbUserIp.str(), m_userIp.str()))
  5257. {
  5258. buildEnvFromWizard(xml, m_pService->getName(), m_pService->getCfg(), envXml);
  5259. setSkipNotification(true);
  5260. if(envXml.length())
  5261. {
  5262. resp.setStatus("true");
  5263. if(m_Environment != NULL)
  5264. {
  5265. m_Environment.clear();
  5266. }
  5267. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  5268. m_Environment.setown(factory->loadLocalEnvironment(envXml.str()));
  5269. }
  5270. else
  5271. resp.setMessage("Failed to generated the environment xml for unknown reason");
  5272. }
  5273. else{
  5274. sbName.append("Cannot generate environment, As environment is locked by ").append(m_userWithLock);
  5275. resp.setMessage(sbName.str());
  5276. }
  5277. }
  5278. else
  5279. resp.setMessage("Environment has not been locked.");
  5280. return true;
  5281. }
  5282. bool CWsDeployFileInfo::getSubnetIPAddr(IEspContext &context, IEspGetSubnetIPAddrRequest &req, IEspGetSubnetIPAddrResponse &resp)
  5283. {
  5284. synchronized block(m_mutex);
  5285. resp.setIPList("");
  5286. resp.setMessage("");
  5287. StringBuffer ipList, msg, script;
  5288. StringBuffer xpath ;
  5289. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalConfFile",m_pService->getName());
  5290. const char* pConfFile = m_pService->getCfg()->queryProp(xpath.str());
  5291. if( pConfFile && *pConfFile)
  5292. {
  5293. Owned<IProperties> pParams = createProperties(pConfFile);
  5294. Owned<IPropertyIterator> iter = pParams->getIterator();
  5295. pParams->getProp("autodetectipscript", script);
  5296. if( script.length())
  5297. {
  5298. runScript(ipList, msg, script.str());
  5299. if( ipList.length())
  5300. {
  5301. try {
  5302. ipList.replace('\n', ';');
  5303. validateIPS(ipList.str());
  5304. resp.setIPList(ipList);
  5305. }
  5306. catch(IException* e)
  5307. {
  5308. StringBuffer sb;
  5309. e->errorMessage(sb);
  5310. e->Release();
  5311. resp.setMessage(sb.str());
  5312. }
  5313. }
  5314. else if( msg.length())
  5315. {
  5316. resp.setMessage(msg);
  5317. }
  5318. }
  5319. else
  5320. resp.setMessage("Could not find the autodetectipscript entry in configmgr.conf");
  5321. }
  5322. else
  5323. resp.setMessage("Unknown Exception. Could not get the List of IPAddresses");
  5324. return true;
  5325. }
  5326. void CWsDeployFileInfo::CLockerAliveThread::main()
  5327. {
  5328. while (!m_quitThread)
  5329. {
  5330. try
  5331. {
  5332. StringBuffer sbMsg;
  5333. CCloudActionHandler checkLocker(this->m_pFileInfo, CLOUD_CHECK_LOCKER, CLOUD_NONE, m_user.str(), "8015", m_pComputers);
  5334. bool ret = checkLocker.start(sbMsg);
  5335. String str(sbMsg.str());
  5336. if (str.startsWith("SOAP Connection error"))
  5337. {
  5338. m_pFileInfo->activeUserNotResponding();
  5339. m_quitThread = true;
  5340. break;
  5341. }
  5342. m_sem.wait(m_brokenConnTimeout);
  5343. }
  5344. catch(IException* e)
  5345. {
  5346. if (m_pFileInfo && m_quitThread != true)
  5347. m_pFileInfo->activeUserNotResponding();
  5348. m_quitThread = true;
  5349. e->Release();
  5350. }
  5351. }
  5352. }
  5353. const char* getFnString(EnvAction ea)
  5354. {
  5355. const char* ret = NULL;
  5356. switch(ea)
  5357. {
  5358. case CLOUD_LOCK_ENV:
  5359. ret = "LockEnvironmentForCloud";
  5360. break;
  5361. case CLOUD_UNLOCK_ENV:
  5362. ret = "UnlockEnvironmentForCloud";
  5363. break;
  5364. case CLOUD_SAVE_ENV:
  5365. ret = "SaveEnvironmentForCloud";
  5366. break;
  5367. case CLOUD_ROLLBACK_ENV:
  5368. ret = "RollbackEnvironmentForCloud";
  5369. break;
  5370. case CLOUD_NOTIFY_INITSYSTEM:
  5371. ret = "NotifyInitSystemSaveEnvForCloud";
  5372. break;
  5373. case CLOUD_CHECK_LOCKER:
  5374. ret = "GetValue";
  5375. break;
  5376. }
  5377. return ret;
  5378. }
  5379. bool CWsDeployFileInfo::getSummary(IEspContext &context, IEspGetSummaryRequest &req, IEspGetSummaryResponse &resp)
  5380. {
  5381. synchronized block(m_mutex);
  5382. StringBuffer respXmlStr;
  5383. resp.setStatus("false");
  5384. bool link = req.getPrepareLinkFlag();
  5385. Owned<IPropertyTree> pEnvRoot = getEnvTree(context, &req.getReqInfo());
  5386. ::getSummary(pEnvRoot, respXmlStr, link);
  5387. if(respXmlStr.length())
  5388. {
  5389. resp.setStatus("true");
  5390. resp.setXmlStr(respXmlStr.str());
  5391. }
  5392. return true;
  5393. }
  5394. void CWsDeployFileInfo::initFileInfo(bool createOrOverwrite, bool bClearEnv)
  5395. {
  5396. StringBuffer xpath;
  5397. m_skipEnvUpdateFromNotification = false;
  5398. m_activeUserNotResp = false;
  5399. bool fileExists = true;
  5400. StringBuffer sbxml;
  5401. if (!checkFileExists(m_envFile) || createOrOverwrite)
  5402. {
  5403. fileExists = false;
  5404. StringBuffer s("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Environment></Environment>");
  5405. Owned<IPropertyTree> pNewTree = createPTreeFromXMLString(s);
  5406. if ( strlen(m_pService->m_configHelper.getBuildSetFilePath()) > 0 )
  5407. {
  5408. try
  5409. {
  5410. Owned<IPropertyTree> pDefBldSet = createPTreeFromXMLFile( m_pService->m_configHelper.getBuildSetFilePath() );
  5411. pNewTree->addPropTree(XML_TAG_PROGRAMS, createPTreeFromIPT(pDefBldSet->queryPropTree("./Programs")));
  5412. pNewTree->addPropTree(XML_TAG_SOFTWARE, createPTreeFromIPT(pDefBldSet->queryPropTree("./Software")));
  5413. }
  5414. catch(IException* e)
  5415. {
  5416. e->Release();
  5417. }
  5418. }
  5419. if(!pNewTree->queryPropTree(XML_TAG_SOFTWARE))
  5420. {
  5421. pNewTree->addPropTree(XML_TAG_SOFTWARE, createPTree());
  5422. pNewTree->addPropTree("./Software/Directories", createPTreeFromXMLString(DEFAULT_DIRECTORIES));
  5423. }
  5424. pNewTree->addPropTree(XML_TAG_HARDWARE, createPTree());
  5425. if (!pNewTree->queryPropTree(XML_TAG_PROGRAMS))
  5426. pNewTree->addPropTree(XML_TAG_PROGRAMS, createPTree());
  5427. toXML(pNewTree, s.clear());
  5428. sbxml.clear().append(s);
  5429. if (createOrOverwrite)
  5430. {
  5431. if (m_pFileIO.get() != NULL)
  5432. m_pFileIO.clear();
  5433. if (m_pFile.get() != NULL)
  5434. {
  5435. m_pFile->remove();
  5436. m_pFile.clear();
  5437. }
  5438. if (m_lastSaved.isNull())
  5439. m_lastSaved.setNow();
  5440. recursiveCreateDirectoryForFile(m_envFile);
  5441. Owned<IFile> f = createIFile(m_envFile);
  5442. Owned<IFileIO> fio = f->open(IFOcreaterw);
  5443. fio->write(0,s.length(),s.str());
  5444. fileExists = true;
  5445. }
  5446. }
  5447. if (fileExists)
  5448. {
  5449. if (m_pFile.get() != NULL)
  5450. m_pFile.clear();
  5451. if (m_pFileIO.get() != NULL)
  5452. m_pFileIO.clear();
  5453. if (m_lastSaved.isNull())
  5454. m_lastSaved.setNow();
  5455. m_pFile.setown(createIFile(m_envFile));
  5456. m_pFileIO.setown(m_pFile->open(IFOread));
  5457. {
  5458. Owned <IPropertyTree> pTree = createPTree(*m_pFileIO);
  5459. toXML(pTree, sbxml.clear());
  5460. }
  5461. }
  5462. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  5463. m_Environment.setown(factory->loadLocalEnvironment(sbxml.str()));
  5464. //add env
  5465. bool modified = false;
  5466. Owned<IPropertyTree> pEnvRoot = &m_Environment->getPTree();
  5467. IPropertyTree* pSettings = pEnvRoot->queryPropTree(XML_TAG_ENVSETTINGS);
  5468. if (!pSettings)
  5469. {
  5470. pSettings = pEnvRoot->addPropTree(XML_TAG_ENVSETTINGS, createPTree());
  5471. modified = true;
  5472. }
  5473. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvConfFile", m_pService->getName());
  5474. const char* tmp = m_pService->getCfg()->queryProp(xpath.str());
  5475. if (tmp && *tmp)
  5476. {
  5477. Owned<IProperties> pParams = createProperties(tmp);
  5478. Owned<IPropertyIterator> iter = pParams->getIterator();
  5479. ForEach(*iter)
  5480. {
  5481. StringBuffer prop;
  5482. pParams->getProp(iter->getPropKey(), prop);
  5483. const char* val = pSettings->queryProp(iter->getPropKey());
  5484. if (!val || strcmp(val, prop.str()))
  5485. {
  5486. pSettings->setProp(iter->getPropKey(), prop.length() ? prop.str():"");
  5487. modified = true;
  5488. }
  5489. }
  5490. if (updateDirsWithConfSettings(pEnvRoot, pParams))
  5491. modified = true;
  5492. }
  5493. try
  5494. {
  5495. StringBuffer err;
  5496. if (modified && fileExists)
  5497. saveEnvironment(NULL, NULL, err);
  5498. }
  5499. catch (IErrnoException* e)
  5500. {
  5501. //Don't ignore file access exceptions
  5502. throw e;
  5503. }
  5504. catch(IException* e)
  5505. {
  5506. //ignore any exceptions at this point like validation errors e.t.c
  5507. e->Release();
  5508. }
  5509. if (!fileExists)
  5510. toXML(pEnvRoot, sbxml.clear());
  5511. if ( bClearEnv == true )
  5512. m_Environment.clear();
  5513. if (m_constEnvRdOnly.get() == NULL)
  5514. {
  5515. if (fileExists)
  5516. {
  5517. sbxml.clear();
  5518. Owned <IPropertyTree> pTree = createPTree(*m_pFileIO);
  5519. toXML(pTree, sbxml);
  5520. }
  5521. m_constEnvRdOnly.setown(factory->loadLocalEnvironment(sbxml.str()));
  5522. }
  5523. }
  5524. void CWsDeployFileInfo::CSdsSubscription::notify(SubscriptionId id, const char *xpath, SDSNotifyFlags flags, unsigned valueLen, const void *valueData)
  5525. {
  5526. DBGLOG("Environment was updated by another client of Dali server. Invalidating cache.\n");
  5527. //if (id != sub_id)
  5528. m_pFileInfo->environmentUpdated();
  5529. }
  5530. void CWsDeployExCE::getLastStarted(StringBuffer& sb)
  5531. {
  5532. synchronized block(m_mutexSrv);
  5533. m_lastStarted.getString(sb);
  5534. }
  5535. CWsDeployFileInfo::~CWsDeployFileInfo()
  5536. {
  5537. if (m_bCloud && m_userWithLock.length() && m_userIp.length())
  5538. {
  5539. StringBuffer sbMsg;
  5540. CCloudActionHandler unlockCloud(this, CLOUD_UNLOCK_ENV, CLOUD_NONE, m_userWithLock.str(), "8015", m_lockedNodesBeforeEnv.get()? m_lockedNodesBeforeEnv.get(): NULL);
  5541. unlockCloud.start(sbMsg);
  5542. }
  5543. CWsDeployFileInfo::CConfigFileMonitorThread::getInstance()->removeObserver(*this);
  5544. m_pNavTree.clear();
  5545. m_pGraphXml.clear();
  5546. m_Environment.clear();
  5547. m_constEnvRdOnly.clear();
  5548. m_pSubscription.clear();
  5549. m_pEnvXml.clear();
  5550. m_pFile.clear();
  5551. m_pFileIO.clear();
  5552. m_lockedNodesBeforeEnv.clear();
  5553. m_pGenJSFactoryThread.clear();
  5554. m_keepAliveHTable.kill();
  5555. }
  5556. bool CWsDeployEx::onNavMenuEvent(IEspContext &context,
  5557. IEspNavMenuEventRequest &req,
  5558. IEspNavMenuEventResponse &resp)
  5559. {
  5560. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  5561. const char* cmd = req.getCmd();
  5562. if (!strcmp(cmd, "ValidateEnvironment") || !strcmp(cmd, "SaveEnvironment") || !strcmp(cmd, "SaveEnvironmentAs"))
  5563. {
  5564. synchronized block(m_mutexSrv);
  5565. return fi->navMenuEvent(context, req, resp);
  5566. }
  5567. else
  5568. return fi->navMenuEvent(context, req, resp);
  5569. }
  5570. bool CWsDeployEx::onSaveSetting(IEspContext &context, IEspSaveSettingRequest &req, IEspSaveSettingResponse &resp)
  5571. {
  5572. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  5573. return fi->saveSetting(context, req, resp);
  5574. }
  5575. bool CWsDeployEx::onGetNavTreeDefn(IEspContext &context, IEspGetNavTreeDefnRequest &req, IEspGetNavTreeDefnResponse &resp)
  5576. {
  5577. const char* xmlArg = req.getXmlArgs();
  5578. StringBuffer decodedParams(xmlArg);
  5579. decodedParams.replaceString("::", "\n");
  5580. Owned<IProperties> pParams = createProperties();
  5581. pParams->loadProps(decodedParams.str());
  5582. const char* create = pParams->queryProp("createFile");
  5583. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true, create && *create ? true : false);
  5584. return fi->getNavTreeDefn(context, req, resp);
  5585. }
  5586. bool CWsDeployEx::onLockEnvironmentForCloud(IEspContext &context, IEspLockEnvironmentForCloudRequest &req, IEspLockEnvironmentForCloudResponse &resp)
  5587. {
  5588. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5589. return fi->lockEnvironmentForCloud(context, req, resp);
  5590. }
  5591. bool CWsDeployEx::onUnlockEnvironmentForCloud(IEspContext &context, IEspUnlockEnvironmentForCloudRequest &req, IEspUnlockEnvironmentForCloudResponse &resp)
  5592. {
  5593. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5594. return fi->unlockEnvironmentForCloud(context, req, resp);
  5595. }
  5596. bool CWsDeployEx::onSaveEnvironmentForCloud(IEspContext &context, IEspSaveEnvironmentForCloudRequest &req, IEspSaveEnvironmentForCloudResponse &resp)
  5597. {
  5598. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5599. return fi->saveEnvironmentForCloud(context, req, resp);
  5600. }
  5601. bool CWsDeployEx::onRollbackEnvironmentForCloud(IEspContext &context, IEspRollbackEnvironmentForCloudRequest &req, IEspRollbackEnvironmentForCloudResponse &resp)
  5602. {
  5603. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5604. return fi->rollbackEnvironmentForCloud(context, req, resp);
  5605. }
  5606. bool CWsDeployEx::onNotifyInitSystemSaveEnvForCloud(IEspContext &context, IEspNotifyInitSystemSaveEnvForCloudRequest &req, IEspNotifyInitSystemSaveEnvForCloudResponse &resp)
  5607. {
  5608. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5609. return fi->notifyInitSystemSaveEnvForCloud(context, req, resp);
  5610. }
  5611. bool CWsDeployExCE::onGetValue(IEspContext &context, IEspGetValueRequest &req, IEspGetValueResponse &resp)
  5612. {
  5613. //Check for common properties here
  5614. StringBuffer decodedParams(req.getParams());
  5615. if (decodedParams.length() == 0)
  5616. {
  5617. resp.setReqValue("");
  5618. resp.setStatus("true");
  5619. return true;
  5620. }
  5621. decodedParams.replaceString("::", "\n");
  5622. Owned<IProperties> pParams = createProperties();
  5623. pParams->loadProps(decodedParams.str());
  5624. const char* pszQueryType = pParams->queryProp("queryType");
  5625. const char* pszparams = pParams->queryProp("params");
  5626. const char* pszAttrValue = pParams->queryProp("attrValue");
  5627. StringBuffer xpath;
  5628. const char* pszValue = NULL;
  5629. StringBuffer sbMultiple;
  5630. bool allHandled = true;
  5631. if (pszQueryType && !strcmp(pszQueryType, "customType"))
  5632. {
  5633. sbMultiple.clear();
  5634. if(pszparams && *pszparams)
  5635. {
  5636. StringArray sArray;
  5637. sArray.appendList(pszparams, ",");
  5638. for(unsigned i = 0; i < sArray.ordinality() ; i++)
  5639. {
  5640. if(!strcmp(sArray.item(i), "environment"))
  5641. {
  5642. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvFile", getName());
  5643. const char* pEnvFile = getCfg()->queryProp(xpath.str());
  5644. if (pEnvFile && *pEnvFile)
  5645. {
  5646. if (checkFileExists(pEnvFile))
  5647. sbMultiple.append(sArray.item(i)).append("=true");
  5648. else
  5649. sbMultiple.append(sArray.item(i)).append("=false");
  5650. if(sbMultiple.length())
  5651. sbMultiple.append(",");
  5652. }
  5653. }
  5654. else if(!strcmp(sArray.item(i), "username"))
  5655. {
  5656. StringBuffer sbName;
  5657. sbName.clear().append(msTick());
  5658. sbMultiple.append(sArray.item(i)).append("=").append(sbName);
  5659. if(sbMultiple.length())
  5660. sbMultiple.append(",");
  5661. }
  5662. else if(!strcmp(sArray.item(i), "defenvfile"))
  5663. {
  5664. if (strstr(m_envFile.str(), m_sourceDir.str()))
  5665. {
  5666. StringBuffer sb(m_envFile.str() + m_sourceDir.length() + 1);
  5667. sbMultiple.append(sArray.item(i)).append("=").append(sb.str());
  5668. if(sbMultiple.length())
  5669. sbMultiple.append(",");
  5670. }
  5671. }
  5672. else if(!strcmp(sArray.item(i), "checklock"))
  5673. {
  5674. //StringBuffer sb(m_sourceDir);
  5675. //if (sb.charAt[sb.length() - 1] != PATHSEPCHAR)
  5676. // sb.append(PATHSEPCHAR);
  5677. //sb.append(req.getFileName());
  5678. //if (checkFileExists(sb.str()))
  5679. allHandled = false;
  5680. }
  5681. else if(!strcmp(sArray.item(i), "encryptpassword"))
  5682. {
  5683. if(pszAttrValue && *pszAttrValue)
  5684. {
  5685. StringArray sArray;
  5686. sArray.appendList(pszAttrValue, ",");
  5687. ForEachItemIn(x, sArray)
  5688. {
  5689. StringBuffer encryptedPasswd ;
  5690. encrypt(encryptedPasswd , sArray.item(x));
  5691. sbMultiple.append(encryptedPasswd.str());
  5692. if(sbMultiple.length())
  5693. sbMultiple.append(",");
  5694. }
  5695. }
  5696. }
  5697. else if(!strcmp(sArray.item(i), "lastsaved"))
  5698. {
  5699. allHandled = false;
  5700. }
  5701. else if(!strcmp(sArray.item(i), "laststarted"))
  5702. {
  5703. StringBuffer lastStarted;
  5704. getLastStarted(lastStarted);
  5705. if(lastStarted.length())
  5706. sbMultiple.append(sArray.item(i)).append("=").append(lastStarted);
  5707. else
  5708. sbMultiple.append(sArray.item(i)).append("=''");
  5709. if(sbMultiple.length())
  5710. sbMultiple.append(",");
  5711. }
  5712. else if(!strcmp(sArray.item(i), "wizops"))
  5713. {
  5714. StringBuffer sbOps;
  5715. this->getWizOptions(sbOps);
  5716. sbMultiple.append(sArray.item(i)).append("=").append(sbOps);
  5717. if(sbMultiple.length())
  5718. sbMultiple.append(",");
  5719. }
  5720. }
  5721. }
  5722. pszValue = sbMultiple.str();
  5723. }
  5724. else if (pszQueryType && !strcmp(pszQueryType, "sourceEnvironments"))
  5725. {
  5726. sbMultiple.clear();
  5727. Owned<IFile> pDir = createIFile(getSourceDir());
  5728. StringBuffer activeConfig_md5sum, config_md5sum;
  5729. md5_filesum(STANDARD_CONFIG_STAGED_PATH, activeConfig_md5sum);
  5730. if (pDir->exists())
  5731. {
  5732. if (pDir->isDirectory())
  5733. {
  5734. Owned<IDirectoryIterator> it = pDir->directoryFiles(NULL, false, true);
  5735. ForEach(*it)
  5736. {
  5737. StringBuffer name;
  5738. it->getName(name);
  5739. String str(name.toLowerCase());
  5740. if (str.endsWith(".xml"))
  5741. {
  5742. StringBuffer sb(getSourceDir());
  5743. sb.append(PATHSEPCHAR).append(it->getName(name.clear()));
  5744. try
  5745. {
  5746. Owned<IPropertyTree> pTree = createPTreeFromXMLFile(sb.str());
  5747. StringBuffer testFile;
  5748. testFile.clear().appendf("%s/%s",getSourceDir(),it->getName(name.clear()).str());
  5749. md5_filesum(testFile.str(),config_md5sum.clear());
  5750. if (pTree && pTree->queryName() && !strcmp(XML_TAG_ENVIRONMENT, pTree->queryName()))
  5751. {
  5752. if(strcmp(config_md5sum.str(),activeConfig_md5sum.str())==0)
  5753. {
  5754. sbMultiple.append("<StagedConfiguration>").append(";");
  5755. sbMultiple.append(it->getName(name.clear())).append(";");
  5756. sbMultiple.append("</StagedConfiguration>").append(";");
  5757. }
  5758. else
  5759. {
  5760. sbMultiple.append(it->getName(name.clear())).append(";");
  5761. }
  5762. }
  5763. }
  5764. catch(IException* e)
  5765. {
  5766. e->Release();
  5767. //add any files already in use
  5768. CWsDeployFileInfo* fi = m_fileInfos.getValue(name.str());
  5769. if (fi)
  5770. sbMultiple.append(name).append(";");
  5771. }
  5772. }
  5773. }
  5774. }
  5775. }
  5776. pszValue = sbMultiple.str();
  5777. }
  5778. else if (pszQueryType && *pszQueryType)
  5779. allHandled = false;
  5780. if (allHandled)
  5781. {
  5782. resp.setReqValue(pszValue);
  5783. resp.setStatus("true");
  5784. return true;
  5785. }
  5786. else
  5787. {
  5788. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  5789. bool ret = fi->getValue(context, req, resp);
  5790. if (ret)
  5791. {
  5792. const char* val = resp.getReqValue();
  5793. StringBuffer sb;
  5794. if (pszValue)
  5795. sb.append(pszValue);
  5796. sb.append(val);
  5797. resp.setReqValue(sb.str());
  5798. resp.setStatus("true");
  5799. }
  5800. return ret;
  5801. }
  5802. }
  5803. bool CWsDeployExCE::onUnlockUser(IEspContext &context, IEspUnlockUserRequest &req, IEspUnlockUserResponse &resp)
  5804. {
  5805. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5806. return fi->unlockUser(context, req, resp);
  5807. }
  5808. bool CWsDeployExCE::onClientAlive(IEspContext &context, IEspClientAliveRequest &req, IEspClientAliveResponse &resp)
  5809. {
  5810. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  5811. return fi->clientAlive(context, req, resp);
  5812. }
  5813. bool CWsDeployExCE::onGetEnvironment(IEspContext &context, IEspGetEnvironmentRequest &req, IEspGetEnvironmentResponse &resp)
  5814. {
  5815. CWsDeployFileInfo* fi = getFileInfo(m_envFile.str());
  5816. return fi->getEnvironment(context, req, resp);
  5817. }
  5818. bool CWsDeployExCE::onSetEnvironment(IEspContext &context, IEspSetEnvironmentRequest &req, IEspSetEnvironmentResponse &resp)
  5819. {
  5820. CWsDeployFileInfo* fi = getFileInfo(m_envFile.str());
  5821. return fi->setEnvironment(context, req, resp);
  5822. }
  5823. bool CWsDeployEx::onDisplaySettings(IEspContext &context, IEspDisplaySettingsRequest &req, IEspDisplaySettingsResponse &resp)
  5824. {
  5825. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5826. return fi->displaySettings(context, req, resp);
  5827. }
  5828. bool CWsDeployEx::onStartDeployment(IEspContext &context, IEspStartDeploymentRequest &req, IEspStartDeploymentResponse &resp)
  5829. {
  5830. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5831. return fi->startDeployment(context, req, resp);
  5832. }
  5833. bool CWsDeployEx::onGetDeployableComps(IEspContext &context, IEspGetDeployableCompsRequest &req, IEspGetDeployableCompsResponse &resp)
  5834. {
  5835. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5836. return fi->getDeployableComps(context, req, resp);
  5837. }
  5838. bool CWsDeployEx::onGetComputersForRoxie(IEspContext &context, IEspGetComputersForRoxieRequest &req, IEspGetComputersForRoxieResponse &resp)
  5839. {
  5840. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5841. return fi->getComputersForRoxie(context, req, resp);
  5842. }
  5843. bool CWsDeployEx::onHandleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp)
  5844. {
  5845. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5846. return fi->handleRoxieOperation(context, req, resp);
  5847. }
  5848. bool CWsDeployEx::onGetBuildSetInfo(IEspContext &context, IEspGetBuildSetInfoRequest &req, IEspGetBuildSetInfoResponse &resp)
  5849. {
  5850. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5851. return fi->getBuildSetInfo(context, req, resp);
  5852. }
  5853. bool CWsDeployEx::onImportBuild(IEspContext &context, IEspImportBuildRequest &req, IEspImportBuildResponse &resp)
  5854. {
  5855. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5856. return fi->importBuild(context, req, resp);
  5857. }
  5858. bool CWsDeployEx::onGetBuildServerDirs(IEspContext &context, IEspGetBuildServerDirsRequest &req, IEspGetBuildServerDirsResponse &resp)
  5859. {
  5860. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5861. return fi->getBuildServerDirs(context, req, resp);
  5862. }
  5863. bool CWsDeployEx::onHandleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp)
  5864. {
  5865. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5866. return fi->handleComponent(context, req, resp);
  5867. }
  5868. bool CWsDeployEx::onHandleAttributeDelete(IEspContext &context, IEspHandleAttributeDeleteRequest &req, IEspHandleAttributeDeleteResponse &resp)
  5869. {
  5870. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5871. return fi->handleAttributeDelete(context, req, resp);
  5872. }
  5873. bool CWsDeployEx::onHandleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp)
  5874. {
  5875. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5876. return fi->handleInstance(context, req, resp);
  5877. }
  5878. bool CWsDeployEx::onHandleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp)
  5879. {
  5880. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5881. return fi->handleEspServiceBindings(context, req, resp);
  5882. }
  5883. bool CWsDeployEx::onHandleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp)
  5884. {
  5885. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5886. return fi->handleComputer(context, req, resp);
  5887. }
  5888. bool CWsDeployEx::onHandleTopology(IEspContext &context, IEspHandleTopologyRequest &req, IEspHandleTopologyResponse &resp)
  5889. {
  5890. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5891. return fi->handleTopology(context, req, resp);
  5892. }
  5893. bool CWsDeployEx::onHandleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp)
  5894. {
  5895. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5896. return fi->handleThorTopology(context, req, resp);
  5897. }
  5898. bool CWsDeployEx::onHandleRows(IEspContext &context, IEspHandleRowsRequest &req, IEspHandleRowsResponse &resp)
  5899. {
  5900. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5901. return fi->handleRows(context, req, resp);
  5902. }
  5903. bool CWsDeployEx::onGraph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp)
  5904. {
  5905. CWsDeployFileInfo* fi = getFileInfo(m_envFile.str());
  5906. return fi->graph(context, req, resp);
  5907. }
  5908. void CWsDeployExCE::getNavigationData(IEspContext &context, IPropertyTree* pData)
  5909. {
  5910. CWsDeployFileInfo* fi = getFileInfo(m_envFile.str());
  5911. return fi->getNavigationData(context, pData);
  5912. }
  5913. bool CWsDeployExCE::onBuildEnvironment(IEspContext &context, IEspBuildEnvironmentRequest &req, IEspBuildEnvironmentResponse &resp)
  5914. {
  5915. String sb(req.getReqInfo().getFileName());
  5916. StringBuffer sbnew(req.getReqInfo().getFileName());
  5917. String* tmp = sb.toLowerCase();
  5918. if (!tmp->endsWith(".xml"))
  5919. sbnew.appendf(".xml");
  5920. delete tmp;
  5921. CWsDeployFileInfo* fi = getFileInfo(sbnew.str());
  5922. return fi->buildEnvironment(context, req, resp);
  5923. }
  5924. bool CWsDeployExCE::onGetSubnetIPAddr(IEspContext &context, IEspGetSubnetIPAddrRequest &req, IEspGetSubnetIPAddrResponse &resp)
  5925. {
  5926. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5927. return fi->getSubnetIPAddr(context, req, resp);
  5928. }
  5929. bool CWsDeployExCE::onGetSummary(IEspContext &context, IEspGetSummaryRequest &req, IEspGetSummaryResponse &resp)
  5930. {
  5931. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  5932. return fi->getSummary(context, req, resp);
  5933. }
  5934. bool CWsDeployExCE::onAddReqdComps(IEspContext &context, IEspAddReqdCompsRequest &req, IEspAddReqdCompsResponse &resp)
  5935. {
  5936. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  5937. return fi->addReqdComps(context, req, resp);
  5938. }
  5939. bool CWsDeployEx::onDeploy(IEspContext &context, IEspDeployRequest& req, IEspDeployResponse& resp)
  5940. {
  5941. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName());
  5942. return fi->deploy(context, req, resp);
  5943. }
  5944. CWsDeployFileInfo* CWsDeployExCE::getFileInfo(const char* fileName, bool addIfNotFound, bool createFile)
  5945. {
  5946. synchronized block(m_mutexSrv);
  5947. if (!fileName || !*fileName)
  5948. throw MakeStringException(-1, "File name required for operation");
  5949. CWsDeployFileInfo* fi = m_fileInfos.getValue(fileName);
  5950. if (!fi)
  5951. {
  5952. if (addIfNotFound)
  5953. {
  5954. StringBuffer filePath(m_sourceDir);
  5955. if (filePath.charAt(filePath.length() - 1) != PATHSEPCHAR)
  5956. filePath.append(PATHSEPCHAR);
  5957. filePath.append(fileName);
  5958. fi = new CWsDeployFileInfo(this, filePath, m_bCloud);
  5959. const char* psz = strrchr(fileName, PATHSEPCHAR);
  5960. if (!psz)
  5961. psz = strrchr(fileName, PATHSEPCHAR == '\\' ? '/' : '\\');
  5962. StringBuffer sb;
  5963. if (!psz)
  5964. sb.append(fileName);
  5965. else
  5966. sb.append(psz + 1);
  5967. if (!sb.length())
  5968. sb.append(fileName);
  5969. try
  5970. {
  5971. fi->initFileInfo(createFile);
  5972. CWsDeployFileInfo::CConfigFileMonitorThread::getInstance()->addObserver(*fi);
  5973. }
  5974. catch (IException* e)
  5975. {
  5976. delete fi;
  5977. throw e;
  5978. }
  5979. m_fileInfos.setValue(sb.str(), fi);
  5980. }
  5981. else
  5982. throw MakeStringException(-1, "File information not found for %s", fileName);
  5983. }
  5984. else if (createFile)
  5985. {
  5986. StringBuffer sbuser, sbip;
  5987. if (fi->getUserWithLock(sbuser, sbip))
  5988. throw MakeStringException(-1, "Cannot overwrite file '%s' as it is currently locked by user '%s' on machine '%s'", fileName, sbuser.str(), sbip.str());
  5989. else
  5990. {
  5991. try
  5992. {
  5993. fi->initFileInfo(createFile);
  5994. }
  5995. catch (IException* e)
  5996. {
  5997. m_fileInfos.remove(fileName);
  5998. delete fi;
  5999. throw e;
  6000. }
  6001. }
  6002. }
  6003. return fi;
  6004. }
  6005. bool CWsDeployFileInfo::getUserWithLock(StringBuffer& sbUser, StringBuffer& sbIp)
  6006. {
  6007. if (m_userWithLock.length() && m_userIp.length())
  6008. {
  6009. sbUser.clear().append(m_userWithLock);
  6010. sbIp.clear().append(m_userIp);
  6011. return true;
  6012. }
  6013. return false;
  6014. }
  6015. bool CWsDeployExCE::onNavMenuEvent(IEspContext &context,
  6016. IEspNavMenuEventRequest &req,
  6017. IEspNavMenuEventResponse &resp)
  6018. {
  6019. CWsDeployFileInfo* fi = getFileInfo(req.getReqInfo().getFileName(), true);
  6020. const char* cmd = req.getCmd();
  6021. if (!strcmp(cmd, "LockEnvironment") || !strcmp(cmd, "UnlockEnvironment"))
  6022. return fi->navMenuEvent(context, req, resp);
  6023. else
  6024. return supportedInEEOnly();
  6025. }
  6026. bool CWsDeployExCE::onSaveSetting(IEspContext &context, IEspSaveSettingRequest &req, IEspSaveSettingResponse &resp)
  6027. {
  6028. return supportedInEEOnly();
  6029. }
  6030. bool CWsDeployExCE::onGetNavTreeDefn(IEspContext &context, IEspGetNavTreeDefnRequest &req, IEspGetNavTreeDefnResponse &resp)
  6031. {
  6032. return supportedInEEOnly();
  6033. }
  6034. bool CWsDeployExCE::onLockEnvironmentForCloud(IEspContext &context, IEspLockEnvironmentForCloudRequest &req, IEspLockEnvironmentForCloudResponse &resp)
  6035. {
  6036. return supportedInEEOnly();
  6037. }
  6038. bool CWsDeployExCE::onUnlockEnvironmentForCloud(IEspContext &context, IEspUnlockEnvironmentForCloudRequest &req, IEspUnlockEnvironmentForCloudResponse &resp)
  6039. {
  6040. return supportedInEEOnly();
  6041. }
  6042. bool CWsDeployExCE::onSaveEnvironmentForCloud(IEspContext &context, IEspSaveEnvironmentForCloudRequest &req, IEspSaveEnvironmentForCloudResponse &resp)
  6043. {
  6044. return supportedInEEOnly();
  6045. }
  6046. bool CWsDeployExCE::onRollbackEnvironmentForCloud(IEspContext &context, IEspRollbackEnvironmentForCloudRequest &req, IEspRollbackEnvironmentForCloudResponse &resp)
  6047. {
  6048. return supportedInEEOnly();
  6049. }
  6050. bool CWsDeployExCE::onNotifyInitSystemSaveEnvForCloud(IEspContext &context, IEspNotifyInitSystemSaveEnvForCloudRequest &req, IEspNotifyInitSystemSaveEnvForCloudResponse &resp)
  6051. {
  6052. return supportedInEEOnly();
  6053. }
  6054. bool CWsDeployExCE::onDisplaySettings(IEspContext &context, IEspDisplaySettingsRequest &req, IEspDisplaySettingsResponse &resp)
  6055. {
  6056. return supportedInEEOnly();
  6057. }
  6058. bool CWsDeployExCE::onStartDeployment(IEspContext &context, IEspStartDeploymentRequest &req, IEspStartDeploymentResponse &resp)
  6059. {
  6060. return supportedInEEOnly();
  6061. }
  6062. bool CWsDeployExCE::onGetDeployableComps(IEspContext &context, IEspGetDeployableCompsRequest &req, IEspGetDeployableCompsResponse &resp)
  6063. {
  6064. return supportedInEEOnly();
  6065. }
  6066. bool CWsDeployExCE::onGetBuildServerDirs(IEspContext &context, IEspGetBuildServerDirsRequest &req, IEspGetBuildServerDirsResponse &resp)
  6067. {
  6068. return supportedInEEOnly();
  6069. }
  6070. bool CWsDeployExCE::onImportBuild(IEspContext &context, IEspImportBuildRequest &req, IEspImportBuildResponse &resp)
  6071. {
  6072. return supportedInEEOnly();
  6073. }
  6074. bool CWsDeployExCE::onGetComputersForRoxie(IEspContext &context, IEspGetComputersForRoxieRequest &req, IEspGetComputersForRoxieResponse &resp)
  6075. {
  6076. return supportedInEEOnly();
  6077. }
  6078. bool CWsDeployExCE::onHandleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp)
  6079. {
  6080. return supportedInEEOnly();
  6081. }
  6082. bool CWsDeployExCE::onHandleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp)
  6083. {
  6084. return supportedInEEOnly();
  6085. }
  6086. bool CWsDeployExCE::onHandleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp)
  6087. {
  6088. return supportedInEEOnly();
  6089. }
  6090. bool CWsDeployExCE::onHandleAttributeDelete(IEspContext &context, IEspHandleAttributeDeleteRequest &req, IEspHandleAttributeDeleteResponse &resp)
  6091. {
  6092. return supportedInEEOnly();
  6093. }
  6094. bool CWsDeployExCE::onHandleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp)
  6095. {
  6096. return supportedInEEOnly();
  6097. }
  6098. bool CWsDeployExCE::onHandleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp)
  6099. {
  6100. return supportedInEEOnly();
  6101. }
  6102. bool CWsDeployExCE::onHandleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp)
  6103. {
  6104. return supportedInEEOnly();
  6105. }
  6106. bool CWsDeployExCE::onHandleTopology(IEspContext &context, IEspHandleTopologyRequest &req, IEspHandleTopologyResponse &resp)
  6107. {
  6108. return supportedInEEOnly();
  6109. }
  6110. bool CWsDeployExCE::onHandleRows(IEspContext &context, IEspHandleRowsRequest &req, IEspHandleRowsResponse &resp)
  6111. {
  6112. return supportedInEEOnly();
  6113. }
  6114. bool CWsDeployExCE::onGraph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp)
  6115. {
  6116. return supportedInEEOnly();
  6117. }
  6118. bool CWsDeployExCE::onDeploy(IEspContext &context, IEspDeployRequest& req, IEspDeployResponse& resp)
  6119. {
  6120. return supportedInEEOnly();
  6121. }
  6122. bool CWsDeployExCE::onGetBuildSetInfo(IEspContext &context, IEspGetBuildSetInfoRequest &req, IEspGetBuildSetInfoResponse &resp)
  6123. {
  6124. return supportedInEEOnly();
  6125. }
  6126. bool CWsDeployEx::onGetValue(IEspContext &context, IEspGetValueRequest &req, IEspGetValueResponse &resp)
  6127. {
  6128. //Check for common properties here
  6129. StringBuffer decodedParams(req.getParams());
  6130. if (decodedParams.length() == 0)
  6131. {
  6132. resp.setReqValue("");
  6133. resp.setStatus("true");
  6134. return true;
  6135. }
  6136. decodedParams.replaceString("::", "\n");
  6137. Owned<IProperties> pParams = createProperties();
  6138. pParams->loadProps(decodedParams.str());
  6139. const char* pszQueryType = pParams->queryProp("queryType");
  6140. const char* pszparams = pParams->queryProp("params");
  6141. const char* pszAttrValue = pParams->queryProp("attrValue");
  6142. StringBuffer xpath;
  6143. const char* pszValue = NULL;
  6144. StringBuffer sbMultiple;
  6145. bool allHandled = true;
  6146. if (pszQueryType && !strcmp(pszQueryType, "customType"))
  6147. {
  6148. sbMultiple.clear();
  6149. if(pszparams && *pszparams)
  6150. {
  6151. StringArray sArray;
  6152. sArray.appendList(pszparams, ",");
  6153. for(unsigned i = 0; i < sArray.ordinality() ; i++)
  6154. {
  6155. if(!strcmp(sArray.item(i), "wizops"))
  6156. {
  6157. StringBuffer sbOps;
  6158. this->getWizOptions(sbOps);
  6159. sbMultiple.append(sArray.item(i)).append("=").append(sbOps);
  6160. if(sbMultiple.length())
  6161. sbMultiple.append(",");
  6162. }
  6163. else
  6164. allHandled = false;
  6165. }
  6166. }
  6167. pszValue = sbMultiple.str();
  6168. }
  6169. else if (pszQueryType && *pszQueryType)
  6170. allHandled = false;
  6171. if (allHandled)
  6172. {
  6173. resp.setReqValue(pszValue);
  6174. resp.setStatus("true");
  6175. return true;
  6176. }
  6177. else
  6178. {
  6179. bool ret = CWsDeployExCE::onGetValue(context, req, resp);
  6180. if (ret)
  6181. {
  6182. const char* val = resp.getReqValue();
  6183. StringBuffer sb;
  6184. if (pszValue)
  6185. sb.append(pszValue);
  6186. sb.append(val);
  6187. resp.setReqValue(sb.str());
  6188. resp.setStatus("true");
  6189. }
  6190. return ret;
  6191. }
  6192. }
  6193. void CWsDeployExCE::getWizOptions(StringBuffer& sb)
  6194. {
  6195. sb.clear().append("1");
  6196. }
  6197. void CWsDeployEx::getWizOptions(StringBuffer& sb)
  6198. {
  6199. sb.clear().append("3");
  6200. }
  6201. CWsDeployExCE* createWsDeployEE(IPropertyTree *cfg, const char* name)
  6202. {
  6203. return new CWsDeployEx;
  6204. }
  6205. CWsDeployExCE* createWsDeployCE(IPropertyTree *cfg, const char* name)
  6206. {
  6207. StringBuffer sb;
  6208. sb.append(XML_TAG_SOFTWARE"/"XML_TAG_ESPPROCESS"/"XML_TAG_ESPBINDING"/");
  6209. sb.appendf("["XML_ATTR_SERVICE"='%s']", name);
  6210. IPropertyTree* pTree = cfg->queryPropTree(sb.str());
  6211. const char* ver = "CE";
  6212. if (pTree)
  6213. ver = pTree->queryProp(XML_ATTR_VERSION);
  6214. if (ver && *ver && !strcmp(ver, "EE"))
  6215. return new CWsDeployEx;
  6216. return new CWsDeployExCE;
  6217. }
  6218. bool CWsDeployFileInfo::checkForRequiredComponents(IPropertyTree* pEnvRoot, const char* ip,
  6219. StringBuffer& reqdCompNames, const char* buildSet, bool autoadd/*=false*/)
  6220. {
  6221. StringBuffer prop, prop2, xpath, genEnvConf;
  6222. Owned<IProperties> algProps;
  6223. StringArray compOnAllNodes,compExcludeOnAllNodes;
  6224. bool retVal = true;
  6225. bool bExclude = false;
  6226. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalConfFile", m_pService->getName());
  6227. const char* pConfFile = m_pService->getCfg()->queryProp(xpath.str());
  6228. xpath.clear().appendf("Software/EspProcess/EspService[@name='%s']/LocalEnvConfFile", m_pService->getName());
  6229. const char* pEnvConfFile = m_pService->getCfg()->queryProp(xpath.str());
  6230. if (pConfFile && *pConfFile && pEnvConfFile && *pEnvConfFile)
  6231. {
  6232. Owned<IProperties> pParams = createProperties(pConfFile);
  6233. Owned<IProperties> pEnvParams = createProperties(pEnvConfFile);
  6234. const char* genenv = pParams->queryProp("wizardalgorithm");
  6235. if (genenv && *genenv)
  6236. {
  6237. const char* cfgpath = pEnvParams->queryProp("configs");
  6238. if (!cfgpath || !*cfgpath)
  6239. cfgpath = CONFIG_DIR;
  6240. genEnvConf.clear().append(cfgpath);
  6241. if (genEnvConf.charAt(genEnvConf.length() - 1) != PATHSEPCHAR)
  6242. genEnvConf.append(PATHSEPCHAR);
  6243. genEnvConf.append(genenv);
  6244. if(checkFileExists(genEnvConf.str()))
  6245. algProps.setown(createProperties(genEnvConf.str()));
  6246. else
  6247. throw MakeStringException( -1 , "The algorithm file %s does not exists", genEnvConf.str());
  6248. algProps->getProp("comps_on_all_nodes", prop);
  6249. algProps->getProp("exclude_from_comps_on_all_nodes", prop2);
  6250. compOnAllNodes.appendList(prop.str(), ",");
  6251. compExcludeOnAllNodes.appendList(prop2.str(), ",");
  6252. for (unsigned i = 0; buildSet != NULL && i < compExcludeOnAllNodes.ordinality(); i++)
  6253. {
  6254. if (strcmp(compExcludeOnAllNodes.item(i),buildSet) == 0)
  6255. {
  6256. bExclude = true;
  6257. break;
  6258. }
  6259. }
  6260. const char* flag = pParams->queryProp("autoaddallnodescomp");
  6261. if (!autoadd)
  6262. autoadd = (flag && *flag == '1') ? true : false;
  6263. }
  6264. }
  6265. for(unsigned i = 0; bExclude == false && i < compOnAllNodes.ordinality(); i++)
  6266. {
  6267. xpath.clear().appendf("./Programs/Build/BuildSet[@name=\"%s\"]", compOnAllNodes.item(i));
  6268. Owned<IPropertyTreeIterator> buildSetIter = pEnvRoot->getElements(xpath.str());
  6269. buildSetIter->first();
  6270. IPropertyTree* pBuildSet;
  6271. if (buildSetIter->isValid())
  6272. pBuildSet = &buildSetIter->query();
  6273. else
  6274. continue;
  6275. const char* processName = pBuildSet->queryProp(XML_ATTR_PROCESS_NAME);
  6276. xpath.clear().appendf("./Software/%s[1]", processName);
  6277. IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str());
  6278. if (!pCompTree)
  6279. {
  6280. if (autoadd)
  6281. {
  6282. StringBuffer buildSetPath, sbNewName;
  6283. Owned<IPropertyTree> pSchema = loadSchema(pEnvRoot->queryPropTree("./Programs/Build[1]"), pBuildSet, buildSetPath, m_Environment);
  6284. xpath.clear().appendf("./Software/%s[@name='%s']", processName, compOnAllNodes.item(i));
  6285. pCompTree = generateTreeFromXsd(pEnvRoot, pSchema, processName, pBuildSet->queryProp(XML_ATTR_NAME), m_pService->getCfg(), m_pService->getName(), false);
  6286. IPropertyTree* pInstTree = pCompTree->queryPropTree(XML_TAG_INSTANCE);
  6287. if (pInstTree)
  6288. pCompTree->removeTree(pInstTree);
  6289. addComponentToEnv(pEnvRoot, compOnAllNodes.item(i), sbNewName, pCompTree);
  6290. }
  6291. else
  6292. {
  6293. reqdCompNames.appendf("%s\n", compOnAllNodes.item(i));
  6294. retVal = false;
  6295. continue;
  6296. }
  6297. }
  6298. xpath.clear().appendf(XML_TAG_INSTANCE"["XML_ATTR_NETADDRESS"='%s']", ip);
  6299. IPropertyTree* pInst = pCompTree->queryPropTree(xpath.str());
  6300. if (!pInst)
  6301. {
  6302. if (autoadd)
  6303. {
  6304. StringBuffer sb, sbl, compName, nodeName;
  6305. xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_HARDWARE, XML_TAG_COMPUTER,
  6306. XML_ATTR_NETADDRESS, ip);
  6307. IPropertyTree* computer = pEnvRoot->queryPropTree(xpath.str());
  6308. if(computer)
  6309. {
  6310. nodeName.clear().append(computer->queryProp(XML_ATTR_NAME));
  6311. xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, processName, XML_ATTR_BUILDSET, compOnAllNodes.item(i));
  6312. sb.clear().appendf("<Instance buildSet=\"%s\" compName=\"%s\" ><Instance name=\"%s\" /></Instance>",
  6313. compOnAllNodes.item(i), pCompTree->queryProp(XML_ATTR_NAME), nodeName.str());
  6314. Owned<IPropertyTree> pInstance = createPTreeFromXMLString(sb.str());
  6315. addInstanceToCompTree(pEnvRoot, pInstance, sbl.clear(), sb.clear(), NULL);
  6316. }
  6317. }
  6318. else
  6319. {
  6320. reqdCompNames.appendf("%s\n", compOnAllNodes.item(i));
  6321. retVal = false;
  6322. continue;
  6323. }
  6324. }
  6325. }
  6326. return retVal;
  6327. }