ws_topologyService.cpp 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #pragma warning (disable : 4786)
  15. #include "math.h"
  16. #include "ws_topologyService.hpp"
  17. #include "workunit.hpp"
  18. #include "mpbase.hpp"
  19. #include "daclient.hpp"
  20. #include "dadfs.hpp"
  21. #include "dafdesc.hpp"
  22. #include "dasds.hpp"
  23. #include "danqs.hpp"
  24. #include "swapnodemain.hpp"
  25. #include "dalienv.hpp"
  26. #ifdef _USE_ZLIB
  27. #include "zcrypt.hpp"
  28. #endif
  29. #include "exception_util.hpp"
  30. #include "jwrapper.hpp"
  31. #define SDS_LOCK_TIMEOUT 30000
  32. static const char* FEATURE_URL = "ClusterTopologyAccess";
  33. static const char* MACHINE_URL = "MachineInfoAccess";
  34. //static const long LOGFILESIZELIMIT = 10000000; //In case of a huge file
  35. static const long LOGFILESIZELIMIT = 100000; //Limit page size to 100k
  36. //static const long LOGFILESIZELIMIT = 1000; //In case of a huge file
  37. static const long AVERAGELOGROWSIZE = 2000;
  38. const char* TEMPZIPDIR = "tempzipfiles";
  39. void CWsTopologyEx::init(IPropertyTree *cfg, const char *process, const char *service)
  40. {
  41. StringBuffer xpath;
  42. if (!daliClientActive())
  43. {
  44. ERRLOG("No Dali Connection Active.");
  45. throw MakeStringException(ECLWATCH_CANNOT_CONNECT_DALI, "No Connection to Dali server is active. Please specify a Dali server in the configuration file.");
  46. }
  47. m_envFactory.setown( getEnvironmentFactory() );
  48. //load threshold values for monitoring cpu load, disk/memory usage
  49. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]", process, service);
  50. Owned<IPropertyTree> pServiceNode = cfg->getPropTree(xpath.str());
  51. m_cpuThreshold = pServiceNode->getPropInt("@warnIfCpuLoadOver", 95);
  52. loadThresholdValue(pServiceNode, "@warnIfFreeStorageUnder", m_diskThreshold, m_bDiskThresholdIsPercentage);
  53. loadThresholdValue(pServiceNode, "@warnIfFreeMemoryUnder", m_memThreshold, m_bMemThresholdIsPercentage);
  54. m_bEncapsulatedSystem = false;
  55. StringBuffer systemUseRewrite;
  56. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/SystemUseRewrite", process, service);
  57. cfg->getProp(xpath.str(), systemUseRewrite);
  58. if (streq(systemUseRewrite.str(), "true"))
  59. m_bEncapsulatedSystem = true;
  60. xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/PreflightProcessFilter", process, service);
  61. cfg->getProp(xpath.str(), m_preflightProcessFilter);
  62. m_enableSNMP = false;
  63. }
  64. void CWsTopologyEx::loadThresholdValue(IPropertyTree* pServiceNode, const char* attrName, unsigned int& thresholdValue,
  65. bool& bThresholdIsPercentage)
  66. {
  67. const char* threshold = pServiceNode->queryProp(attrName);
  68. if (threshold && *threshold)
  69. {
  70. thresholdValue = atoi(threshold);
  71. StringBuffer buf(threshold);
  72. buf.toUpperCase();
  73. bThresholdIsPercentage = strstr(buf.str(), "MB") == NULL;
  74. }
  75. else
  76. {
  77. thresholdValue = 95;
  78. bThresholdIsPercentage = true;
  79. }
  80. }
  81. bool CWsTopologyEx::onTpSwapNode(IEspContext &context,IEspTpSwapNodeRequest &req, IEspTpSwapNodeResponse &resp)
  82. {
  83. try
  84. {
  85. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Full, false))
  86. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to Swap Node. Permission denied.");
  87. //another client (like configenv) may have updated the constant environment so reload it
  88. m_envFactory->validateCache();
  89. resp.setTpSwapNodeResult(false);
  90. SwapNode(req.getCluster(),req.getOldIP(),req.getNewIP(),0);
  91. resp.setTpSwapNodeResult(true);
  92. StringBuffer path;
  93. path.appendf("/Environment/Software/ThorCluster[@name='%s']", req.getCluster());
  94. StringBuffer encodedXpath;
  95. JBASE64_Encode(path, path.length(), encodedXpath, false);
  96. path.clear().append("/WsTopology/TpMachineQuery?Type=THORMACHINES&Cluster=");
  97. path.append(req.getCluster()).append("&Path=").append(encodedXpath);
  98. resp.setRedirectUrl(path.str());
  99. }
  100. catch(IException* e)
  101. {
  102. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  103. }
  104. return true;
  105. }
  106. bool CWsTopologyEx::onTpSetMachineStatus(IEspContext &context,IEspTpSetMachineStatusRequest &req, IEspTpSetMachineStatusResponse &resp)
  107. {
  108. try
  109. {
  110. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Write, false))
  111. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to Set Machine Status. Permission denied.");
  112. resp.setTpSetMachineStatusResult(true);
  113. }
  114. catch(IException* e)
  115. {
  116. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  117. }
  118. return true;
  119. }
  120. bool CWsTopologyEx::onTpLogFileDisplay(IEspContext &context,IEspTpLogFileRequest &req, IEspTpLogFileResponse &resp)
  121. {
  122. onTpLogFile(context, req, resp);
  123. return true;
  124. }
  125. bool CWsTopologyEx::onTpLogFile(IEspContext &context,IEspTpLogFileRequest &req, IEspTpLogFileResponse &resp)
  126. {
  127. try
  128. {
  129. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  130. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to get Log File. Permission denied.");
  131. MemoryBuffer membuff;
  132. const char* name = req.getName();
  133. const char* type = req.getType();
  134. if (type && *type && ((strcmp(type,"thormaster_log") == 0) || (strcmp(type,"tpcomp_log") == 0)))
  135. {
  136. ReadLog readLogReq;
  137. readLogReq.pageNumber = req.getPageNumber();
  138. readLogReq.startDate = req.getStartDate();
  139. readLogReq.endDate = req.getEndDate();
  140. readLogReq.firstRows = req.getFirstRows();
  141. readLogReq.lastRows = req.getLastRows();
  142. readLogReq.filterType = req.getFilterType();
  143. readLogReq.reverse = req.getReversely();
  144. readLogReq.zip = req.getZip();
  145. readLogReq.fileSize = -1;
  146. readLogReq.prevPage = -1;
  147. readLogReq.nextPage = -1;
  148. int lastHours = -1;
  149. if (readLogReq.filterType == 2) //in the last n hours
  150. {
  151. if (readLogReq.startDate.length() < 19 || readLogReq.endDate.length() < 19)
  152. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invlid 'Hours' field.");
  153. char fromHour[3], toHour[3];
  154. fromHour[0] = readLogReq.startDate.charAt(11);
  155. fromHour[1] = readLogReq.startDate.charAt(12);
  156. toHour[0] = readLogReq.endDate.charAt(11);
  157. toHour[1] = readLogReq.endDate.charAt(12);
  158. lastHours = atoi(toHour)-atoi(fromHour);
  159. }
  160. else if (readLogReq.filterType == 6) //from date/time to date/time
  161. {
  162. if (readLogReq.startDate.length() < 19 && readLogReq.endDate.length() < 19)
  163. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invlid 'Date' field.");
  164. }
  165. bool hasDate = false;
  166. StringBuffer startDate, endDate, logname, returnbuff;
  167. if (strcmp(type,"thormaster_log"))
  168. {
  169. logname = name;
  170. }
  171. else
  172. {
  173. logname.append(CCluster(name)->queryRoot()->queryProp("LogFile"));
  174. }
  175. Owned<IFile> rFile = createIFile(logname.str());
  176. if (!rFile || !rFile->exists())
  177. throw MakeStringException(ECLWATCH_CANNOT_OPEN_FILE,"Cannot open file %s.",logname.str());
  178. readLogReq.fileSize = rFile->size();
  179. readLogReq.TotalPages = (int) ceil(((double)readLogReq.fileSize)/LOGFILESIZELIMIT);
  180. if (readLogReq.filterType == 4) //by page number: 0 to n-1
  181. {
  182. if (readLogReq.pageNumber > readLogReq.TotalPages - 1)
  183. readLogReq.pageNumber = readLogReq.TotalPages - 1;
  184. }
  185. if (!req.getLoadData())
  186. {
  187. hasDate = true;
  188. if (readLogReq.startDate.length() > 0)
  189. resp.setStartDate(readLogReq.startDate.str());
  190. if (readLogReq.endDate.length() > 0)
  191. resp.setEndDate(readLogReq.endDate.str());
  192. if (readLogReq.filterType == 0 || readLogReq.filterType == 4)
  193. {
  194. offset_t readFrom = LOGFILESIZELIMIT * readLogReq.pageNumber;
  195. if (readFrom > readLogReq.fileSize)
  196. readFrom = 0;
  197. offset_t fileSize = readLogReq.fileSize - readFrom;
  198. if (fileSize > LOGFILESIZELIMIT)
  199. {
  200. readLogReq.nextPage = readLogReq.pageNumber + 1;
  201. }
  202. if (readFrom > 0)
  203. {
  204. readLogReq.prevPage = readLogReq.pageNumber - 1;
  205. }
  206. }
  207. else if (readLogReq.filterType == 3) //Last page
  208. {
  209. int pageCount = 1;
  210. offset_t readFrom = 0;
  211. offset_t fileSize = readLogReq.fileSize;
  212. while (fileSize > LOGFILESIZELIMIT)
  213. {
  214. fileSize -= LOGFILESIZELIMIT;
  215. readFrom += LOGFILESIZELIMIT;
  216. pageCount++;
  217. }
  218. if (readFrom > 0)
  219. {
  220. readLogReq.prevPage = pageCount - 2;
  221. }
  222. readLogReq.pageNumber = pageCount - 1;
  223. }
  224. else if (readLogReq.filterType == 6) //from date/time to date/time
  225. {
  226. if (readLogReq.startDate.length() > 18)
  227. {
  228. CDateTime startdt;
  229. StringBuffer fromStr = readLogReq.startDate;
  230. fromStr.setCharAt(10, 'T');
  231. startdt.setString(fromStr.str(), NULL, true);
  232. StringBuffer startStr;
  233. unsigned year, month, day, hour, minute, second, nano;
  234. startdt.getDate(year, month, day, true);
  235. startdt.getTime(hour, minute, second, nano, true);
  236. startStr.appendf("%02d/%02d/%4d %02d:%02d:%02d", month, day, year, hour, minute, second);
  237. startDate.append(startStr.str());
  238. }
  239. if (readLogReq.endDate.length() > 18)
  240. {
  241. CDateTime enddt;
  242. StringBuffer toStr = readLogReq.endDate;
  243. toStr.setCharAt(10, 'T');
  244. enddt.setString(toStr.str(), NULL, true);
  245. StringBuffer endStr;
  246. unsigned year, month, day, hour, minute, second, nano;
  247. enddt.getDate(year, month, day, true);
  248. enddt.getTime(hour, minute, second, nano, true);
  249. endStr.appendf("%02d/%02d/%4d %02d:%02d:%02d", month, day, year, hour, minute, second);
  250. endDate.append(endStr.str());
  251. }
  252. }
  253. }
  254. else if (type && *type && strcmp(type,"thormaster_log"))
  255. {
  256. readLogFile(logname, readLogReq, startDate, endDate, hasDate, returnbuff);
  257. }
  258. else
  259. {
  260. readLogFile(logname, readLogReq, startDate, endDate, hasDate, returnbuff);
  261. }
  262. resp.setHasDate(hasDate);
  263. if (lastHours > 0)
  264. resp.setLastHours(lastHours);
  265. if (startDate.length() > 0)
  266. resp.setStartDate(startDate.str());
  267. if (endDate.length() > 0)
  268. resp.setEndDate(endDate.str());
  269. if (readLogReq.lastRows > 0)
  270. resp.setLastRows(readLogReq.lastRows);
  271. if (readLogReq.firstRows > 0)
  272. resp.setFirstRows(readLogReq.firstRows);
  273. double version = context.getClientVersion();
  274. if (version > 1.05)
  275. {
  276. resp.setTotalPages( readLogReq.TotalPages );
  277. }
  278. if (returnbuff.length() > 0)
  279. {
  280. if (returnbuff.length() > LOGFILESIZELIMIT)
  281. {
  282. StringBuffer returnbuff0;
  283. returnbuff0.append(returnbuff.str(), 0, LOGFILESIZELIMIT);
  284. returnbuff0.appendf("\r\n****** Warning: cannot display all. The page size is limited to %ld bytes. ******", LOGFILESIZELIMIT);
  285. resp.setLogData(returnbuff0.str());
  286. if (readLogReq.filterType == 1)
  287. {
  288. readLogReq.pageFrom = 0;
  289. readLogReq.pageTo = LOGFILESIZELIMIT;
  290. }
  291. else if ((readLogReq.filterType == 2) || (readLogReq.filterType == 5))
  292. {
  293. readLogReq.pageFrom = readLogReq.fileSize - returnbuff.length();
  294. readLogReq.pageTo = readLogReq.pageFrom + LOGFILESIZELIMIT;
  295. }
  296. else if (readLogReq.filterType == 6)
  297. {
  298. readLogReq.pageTo = readLogReq.pageFrom + LOGFILESIZELIMIT;
  299. }
  300. }
  301. else
  302. {
  303. resp.setLogData(returnbuff.str());
  304. if (readLogReq.filterType == 1)
  305. {
  306. readLogReq.pageFrom = 0;
  307. readLogReq.pageTo = returnbuff.length();
  308. }
  309. else if ((readLogReq.filterType == 2) || (readLogReq.filterType == 5))
  310. {
  311. readLogReq.pageFrom = readLogReq.fileSize - returnbuff.length();
  312. readLogReq.pageTo = readLogReq.fileSize;
  313. }
  314. else if (readLogReq.filterType == 6)
  315. {
  316. readLogReq.pageTo = readLogReq.pageFrom + returnbuff.length();
  317. }
  318. }
  319. }
  320. if (readLogReq.fileSize > 0)
  321. resp.setFileSize(readLogReq.fileSize);
  322. if (readLogReq.pageNumber > 0)
  323. resp.setPageNumber(readLogReq.pageNumber);
  324. if (readLogReq.pageFrom > 0)
  325. resp.setPageFrom(readLogReq.pageFrom);
  326. if (readLogReq.pageTo > 0)
  327. resp.setPageTo(readLogReq.pageTo);
  328. if (readLogReq.prevPage >= 0)
  329. resp.setPrevPage(readLogReq.prevPage);
  330. if (readLogReq.nextPage > 0)
  331. resp.setNextPage(readLogReq.nextPage);
  332. resp.setName(req.getName());
  333. resp.setType(type);
  334. resp.setFilterType(readLogReq.filterType);
  335. resp.setReversely(readLogReq.reverse);
  336. resp.setZip(readLogReq.zip);
  337. }
  338. else if (type && *type && (strcmp(type,"xml") == 0))
  339. {
  340. StringBuffer redirect;
  341. redirect.append("/WsTopology/TpXMLFile");
  342. redirect.appendf("?Name=%s", req.getName());
  343. resp.setRedirectUrl(redirect.str());
  344. }
  345. }
  346. catch(IException* e)
  347. {
  348. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  349. }
  350. return true;
  351. }
  352. bool CWsTopologyEx::onSystemLog(IEspContext &context,IEspSystemLogRequest &req, IEspSystemLogResponse &resp)
  353. {
  354. try
  355. {
  356. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  357. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to get Log File. Permission denied.");
  358. const char* name = req.getName();
  359. if (!name || !*name)
  360. throw MakeStringException(ECLWATCH_INVALID_FILE_NAME,"File name not specified.");
  361. StringBuffer logname;
  362. const char* type = req.getType();
  363. if (type && !strcmp(type,"thormaster_log"))
  364. {
  365. logname.append(CCluster(name)->queryRoot()->queryProp("LogFile"));
  366. }
  367. else
  368. {
  369. logname = name;
  370. }
  371. int nZip = req.getZip();
  372. //Remove path from file name
  373. char* ppStr = (char*) logname.str();
  374. char* pStr = strchr(ppStr, '/');
  375. while (pStr)
  376. {
  377. ppStr = pStr+1;
  378. pStr = strchr(ppStr, '/');
  379. }
  380. pStr = strchr(ppStr, '\\');
  381. while (pStr)
  382. {
  383. ppStr = pStr+1;
  384. pStr = strchr(ppStr, '\\');
  385. }
  386. StringBuffer fileName, headerStr;
  387. if (ppStr && *ppStr)
  388. {
  389. fileName.append(ppStr);
  390. }
  391. else
  392. {
  393. fileName.append("SystemLog");
  394. }
  395. headerStr.appendf("attachment;filename=%s", fileName.str());
  396. if (nZip > 2)
  397. headerStr.append(".gz");
  398. else if (nZip > 1)
  399. headerStr.append(".zip");
  400. Owned<IFile> rFile = createIFile(logname.str());
  401. if (!rFile)
  402. throw MakeStringException(ECLWATCH_CANNOT_OPEN_FILE,"Cannot open file %s.", logname.str());
  403. OwnedIFileIO rIO = rFile->openShared(IFOread,IFSHfull);
  404. if (!rIO)
  405. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE,"Cannot read file %s.",logname.str());
  406. offset_t fileSize = rFile->size();
  407. StringBuffer tmpBuf;
  408. tmpBuf.ensureCapacity((unsigned)fileSize);
  409. tmpBuf.setLength((unsigned)fileSize);
  410. size32_t nRead = rIO->read(0, (size32_t) fileSize, (char*)tmpBuf.str());
  411. if (nRead != fileSize)
  412. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE, "Failed to read file %s.", logname.str());
  413. if (nZip < 2)
  414. {
  415. MemoryBuffer membuff;
  416. membuff.setBuffer(tmpBuf.length(), (void*)tmpBuf.str());
  417. resp.setThefile(membuff);
  418. resp.setThefile_mimetype(HTTP_TYPE_TEXT_PLAIN);
  419. context.addCustomerHeader("Content-disposition", headerStr.str());
  420. }
  421. else
  422. {
  423. #ifndef _USE_ZLIB
  424. throw MakeStringException(ERRORID_ECLWATCH_TOPOLOGY+109,"The data cannot be compressed.");
  425. #else
  426. StringBuffer ifname;
  427. unsigned threadID = (unsigned) (memsize_t) GetCurrentThreadId();
  428. if (nZip > 2)
  429. ifname.appendf("%s%sT%xAT%x", TEMPZIPDIR, PATHSEPSTR, threadID, msTick());
  430. else
  431. ifname.appendf("%s%sT%xAT%x.zip", TEMPZIPDIR, PATHSEPSTR, threadID, msTick());
  432. int ret = 0;
  433. IZZIPor* Zipor = createZZIPor();
  434. if (nZip > 2)
  435. ret = Zipor->gzipToFile(tmpBuf.length(), (void*)tmpBuf.str(), ifname.str());
  436. else
  437. ret = Zipor->zipToFile(tmpBuf.length(), (void*)tmpBuf.str(), fileName.str(), ifname.str());
  438. releaseIZ(Zipor);
  439. if (ret < 0)
  440. {
  441. Owned<IFile> rFile = createIFile(ifname.str());
  442. if (rFile->exists())
  443. rFile->remove();
  444. throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA,"The data cannot be compressed.");
  445. }
  446. int outlen = 0;
  447. unsigned char* outd = NULL;
  448. ret = loadFile(ifname.str(), outlen, outd);
  449. if(ret < 0 || outlen < 1 || !outd || !*outd)
  450. {
  451. Owned<IFile> rFile = createIFile(ifname.str());
  452. if (rFile->exists())
  453. rFile->remove();
  454. if (outd)
  455. free(outd);
  456. throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA,"The data cannot be compressed.");
  457. }
  458. MemoryBuffer membuff;
  459. membuff.setBuffer(outlen, (void*)outd);
  460. resp.setThefile(membuff);
  461. if (nZip > 2)
  462. resp.setThefile_mimetype("application/x-gzip");
  463. else
  464. resp.setThefile_mimetype("application/zip");
  465. context.addCustomerHeader("Content-disposition", headerStr.str());
  466. Owned<IFile> rFile1 = createIFile(ifname.str());
  467. if (rFile1->exists())
  468. rFile1->remove();
  469. if (outd)
  470. free(outd);
  471. #endif
  472. }
  473. }
  474. catch(IException* e)
  475. {
  476. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  477. }
  478. return true;
  479. }
  480. bool CWsTopologyEx::onTpXMLFile(IEspContext &context,IEspTpXMLFileRequest &req, IEspTpXMLFileResponse &resp)
  481. {
  482. try
  483. {
  484. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  485. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to get Configuration File. Permission denied.");
  486. StringBuffer strBuff;
  487. getThorXml(req.getName(),strBuff);
  488. MemoryBuffer membuff;
  489. membuff.setBuffer(strBuff.length(), (void*)strBuff.toCharArray());
  490. resp.setThefile_mimetype("text/xml");
  491. resp.setThefile(membuff);
  492. }
  493. catch(IException* e)
  494. {
  495. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  496. }
  497. return true;
  498. }
  499. void CWsTopologyEx::getThorXml(const char *cluster,StringBuffer& returnStr)
  500. {
  501. CCluster conn(cluster);
  502. toXML(conn->queryRoot(), returnStr);
  503. }
  504. void CWsTopologyEx::getThorLog(const char *cluster,MemoryBuffer& returnbuff)
  505. {
  506. StringBuffer logname;
  507. logname.append(CCluster(cluster)->queryRoot()->queryProp("LogFile"));
  508. Owned<IFile> rFile = createIFile(logname.str());
  509. if (!rFile)
  510. throw MakeStringException(ECLWATCH_CANNOT_OPEN_FILE,"Cannot open file %s.",logname.str());
  511. OwnedIFileIO rIO = rFile->openShared(IFOread,IFSHfull);
  512. if (!rIO)
  513. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE,"Cannot read file %s.",logname.str());
  514. read(rIO, 0, (size32_t)-1, returnbuff);
  515. }
  516. int CWsTopologyEx::loadFile(const char* fname, int& len, unsigned char* &buf, bool binary)
  517. {
  518. len = 0;
  519. buf = NULL;
  520. FILE* fp = fopen(fname, binary?"rb":"rt");
  521. if (fp)
  522. {
  523. char* buffer[1024];
  524. int bytes;
  525. for (;;)
  526. {
  527. bytes = fread(buffer, 1, sizeof(buffer), fp);
  528. if (!bytes)
  529. break;
  530. buf = (unsigned char*)realloc(buf, len + bytes + 1);
  531. memcpy(buf + len, buffer, bytes);
  532. len += bytes;
  533. }
  534. fclose(fp);
  535. }
  536. else
  537. {
  538. printf("unable to open file %s\n", fname);
  539. return -1;
  540. }
  541. if(buf)
  542. buf[len] = '\0';
  543. return 0;
  544. }
  545. void CWsTopologyEx::readLogFile(StringBuffer logname, ReadLog& readLogReq, StringBuffer& startDate, StringBuffer& endDate,
  546. bool& hasDate, StringBuffer& returnbuff)
  547. {
  548. Owned<IFile> rFile = createIFile(logname.str());
  549. if (!rFile)
  550. throw MakeStringException(ECLWATCH_CANNOT_OPEN_FILE,"Cannot open file %s.",logname.str());
  551. OwnedIFileIO rIO = rFile->openShared(IFOread,IFSHfull);
  552. if (!rIO)
  553. throw MakeStringException(ECLWATCH_CANNOT_OPEN_FILE,"Cannot read file %s.",logname.str());
  554. if (readLogReq.filterType == 1 && readLogReq.firstRows < 1) //last n rows
  555. throw MakeStringException(ECLWATCH_INVALID_INPUT, "'First' field should be defined.");
  556. if (readLogReq.filterType == 5 && readLogReq.lastRows < 1) //last n rows
  557. throw MakeStringException(ECLWATCH_INVALID_INPUT, "'Last' field should be defined.");
  558. readLogReq.fileSize = rFile->size();
  559. if (readLogReq.filterType == 0 || readLogReq.filterType == 4) //by page number: 0 to n-1
  560. {
  561. offset_t readFrom = LOGFILESIZELIMIT * readLogReq.pageNumber;
  562. if (readFrom > readLogReq.fileSize)
  563. readFrom = 0;
  564. offset_t fileSize = readLogReq.fileSize - readFrom;
  565. if (fileSize > LOGFILESIZELIMIT)
  566. {
  567. fileSize = LOGFILESIZELIMIT;
  568. readLogReq.nextPage = readLogReq.pageNumber + 1;
  569. }
  570. if (readFrom > 0)
  571. {
  572. readLogReq.prevPage = readLogReq.pageNumber - 1;
  573. }
  574. returnbuff.ensureCapacity((unsigned)fileSize);
  575. returnbuff.setLength((unsigned)fileSize);
  576. size32_t nRead = rIO->read(readFrom, (size32_t) fileSize, (char*)returnbuff.str());
  577. if (nRead != fileSize)
  578. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE, "Failed to read file %s.", logname.str());
  579. readLogReq.pageFrom = (long) readFrom;
  580. readLogReq.pageTo = (long) (readFrom + nRead);
  581. if (readFrom < 1)
  582. {
  583. if (nRead > 28)
  584. {
  585. char* pTr = (char*) returnbuff.str();
  586. CDateTime dt;
  587. hasDate = readLogTime(pTr, 9, 19, dt);
  588. }
  589. }
  590. else
  591. {
  592. offset_t fileSize0 = 29;
  593. StringBuffer returnbuff0;
  594. returnbuff0.ensureCapacity((unsigned)fileSize0);
  595. returnbuff0.setLength((unsigned)fileSize0);
  596. size32_t nRead0 = rIO->read(0, (size32_t)fileSize0, (char*)returnbuff0.str());
  597. if (nRead0 > 28)
  598. {
  599. char* pTr = (char*) returnbuff0.str();
  600. CDateTime dt;
  601. hasDate = readLogTime(pTr, 9, 19, dt);
  602. }
  603. }
  604. }
  605. else if (readLogReq.filterType == 3) //Last page
  606. {
  607. int pageCount = 1;
  608. offset_t readFrom = 0;
  609. offset_t fileSize = readLogReq.fileSize;
  610. while (fileSize > LOGFILESIZELIMIT)
  611. {
  612. fileSize -= LOGFILESIZELIMIT;
  613. readFrom += LOGFILESIZELIMIT;
  614. pageCount++;
  615. }
  616. if (readFrom > 0)
  617. {
  618. readLogReq.prevPage = pageCount - 2;
  619. }
  620. returnbuff.ensureCapacity((unsigned)fileSize);
  621. returnbuff.setLength((unsigned)fileSize);
  622. size32_t nRead = rIO->read(readFrom, (size32_t)fileSize, (char*)returnbuff.str());
  623. if (nRead != fileSize)
  624. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE, "Failed to read file %s.", logname.str());
  625. readLogReq.pageFrom = readFrom;
  626. readLogReq.pageTo = readFrom + nRead;
  627. offset_t fileSize0 = 29;
  628. StringBuffer returnbuff0;
  629. returnbuff0.ensureCapacity((unsigned)fileSize0);
  630. returnbuff0.setLength((unsigned)fileSize0);
  631. size32_t nRead0 = rIO->read(0, (size32_t)fileSize0, (char*)returnbuff0.str());
  632. if (nRead0 > 28)
  633. {
  634. char* pTr = (char*) returnbuff0.str();
  635. CDateTime dt;
  636. hasDate = readLogTime(pTr, 9, 19, dt);
  637. }
  638. }
  639. else
  640. {
  641. if (!readLogReq.zip)
  642. {
  643. StringArray rowList;
  644. readLogFile(logname, rIO, readLogReq, hasDate, rowList);
  645. if (rowList.length() > 0)
  646. {
  647. for (unsigned i = 0; i < rowList.length(); i++)
  648. {
  649. StringBuffer item = rowList.item(i);
  650. if (readLogReq.filterType != 5)
  651. {
  652. if (!readLogReq.reverse)
  653. {
  654. returnbuff.append(item);
  655. }
  656. else
  657. {
  658. returnbuff.insert(0, item);
  659. }
  660. }
  661. else
  662. {
  663. if (readLogReq.reverse)
  664. {
  665. returnbuff.append(item);
  666. }
  667. else
  668. {
  669. returnbuff.insert(0, item);
  670. }
  671. }
  672. }
  673. }
  674. }
  675. }
  676. }
  677. void CWsTopologyEx::readLogFile(StringBuffer logname, OwnedIFileIO rIO, ReadLog& readLogReq, bool& hasDate, StringArray& returnbuff)
  678. {
  679. bool returnNow = false;
  680. int ltBytes = 1; //how many bytes used for Line Terminator
  681. bool firstChuck = true;
  682. bool lastChuck = false;
  683. bool hasLineID = false;
  684. offset_t readFrom = 0;
  685. offset_t readFrom0 = 0;
  686. unsigned locationFlag = 0; //Not in the area to be retrieved
  687. StringBuffer dataLeft;
  688. offset_t fileSize = readLogReq.fileSize;
  689. while (fileSize > 0)
  690. {
  691. StringBuffer dataBuffer;
  692. lastChuck = readToABuffer(logname, rIO, fileSize, readFrom, dataLeft, dataBuffer);
  693. offset_t readPtr = 0;
  694. offset_t totalBytes = dataBuffer.length();
  695. char* pTr = (char*) dataBuffer.str();
  696. long firstOrLastRowID = -1;
  697. if (firstChuck) //first time
  698. {
  699. firstChuck = false;
  700. ltBytes = checkLineTerminator(pTr);
  701. //if rowID < 0, no row id found
  702. long rowID = readLogLineID(pTr);
  703. if ((totalBytes > 8) && (rowID > -1))
  704. hasLineID = true;
  705. if (totalBytes > 28)
  706. {
  707. CDateTime dt;
  708. hasDate = readLogTime(pTr, 9, 19, dt);
  709. }
  710. if (hasLineID && (readLogReq.filterType == 1)) //first n rows
  711. {
  712. firstOrLastRowID = rowID;
  713. }
  714. else if (readLogReq.filterType == 5) //last n rows
  715. {
  716. offset_t estimateSize = AVERAGELOGROWSIZE*readLogReq.lastRows;
  717. if (readLogReq.fileSize > 5 * estimateSize) //try a short cut since the file is too big
  718. {
  719. int n = 1;
  720. dataLeft.clear();
  721. dataBuffer.clear();
  722. fileSize = readLogReq.fileSize;
  723. readFrom = fileSize-estimateSize;
  724. fileSize = estimateSize;
  725. readToABuffer(logname, rIO, fileSize, readFrom, dataLeft, dataBuffer);
  726. readPtr = 0;
  727. totalBytes = dataBuffer.length();
  728. pTr = (char*) dataBuffer.str();
  729. //Find out a start point to check the data rows
  730. bool bLT = false;
  731. while (!bLT && (readPtr < totalBytes))
  732. {
  733. bLT = readLineTerminator(pTr, ltBytes);
  734. pTr++;
  735. readPtr++;
  736. }
  737. //Find out the row number of the last data row
  738. StringBuffer dataRow;
  739. char* pTr1 = pTr;
  740. offset_t readPtr1 = readPtr;
  741. bLT = false;
  742. while (readPtr1 < totalBytes)
  743. {
  744. dataRow.append(pTr1[0]);
  745. //Check if this is the end of the row
  746. bLT = readLineTerminator(pTr1, ltBytes);
  747. if (!bLT)
  748. {
  749. pTr1++;
  750. readPtr1++;
  751. continue;
  752. }
  753. if (dataRow.length() > 8)
  754. {
  755. long id = readLogLineID((char*) dataRow.str());
  756. if (id > -1)
  757. firstOrLastRowID = id;
  758. }
  759. dataRow.clear();
  760. pTr1++;
  761. readPtr1++;
  762. }
  763. if (dataRow.length() > 8)
  764. {
  765. long id = readLogLineID((char*) dataRow.str());
  766. if (id > -1)
  767. firstOrLastRowID = id;
  768. }
  769. }
  770. }
  771. }
  772. char* pTr0 = pTr;
  773. StringBuffer dataRow;
  774. while (totalBytes - readPtr > 27)
  775. {
  776. //Try to read a line
  777. bool bLT = false;
  778. while (readPtr < totalBytes)
  779. {
  780. dataRow.append(pTr[0]);
  781. //Check if this is the end of the row
  782. bLT = readLineTerminator(pTr, ltBytes);
  783. if (!bLT)
  784. {
  785. pTr++;
  786. readPtr++;
  787. continue;
  788. }
  789. if (dataRow.length() > 0)
  790. {
  791. addALogLine(readFrom0, locationFlag, firstOrLastRowID, dataRow, readLogReq, returnbuff);
  792. dataRow.clear();
  793. }
  794. readPtr++;
  795. pTr++;
  796. if (readPtr < totalBytes)
  797. pTr0 = pTr;
  798. else
  799. pTr0 = NULL;
  800. break;
  801. }
  802. if (locationFlag > 1)
  803. break;
  804. }
  805. if (locationFlag > 1)
  806. break;
  807. dataLeft.clear();
  808. if (pTr0)
  809. dataLeft.append(pTr0);
  810. if (lastChuck)
  811. {
  812. addALogLine(readFrom0, locationFlag, firstOrLastRowID, dataLeft, readLogReq, returnbuff);
  813. break;
  814. }
  815. }
  816. return;
  817. }
  818. bool CWsTopologyEx::readToABuffer(StringBuffer logname, OwnedIFileIO rIO, offset_t& fileSize, offset_t& readFrom,
  819. StringBuffer dataLeft, StringBuffer& dataBuffer)
  820. {
  821. bool lastPage = true;
  822. offset_t readSize = fileSize;
  823. if (readSize > LOGFILESIZELIMIT)
  824. {
  825. readSize = LOGFILESIZELIMIT;
  826. lastPage = false;
  827. }
  828. StringBuffer buf;
  829. buf.ensureCapacity((unsigned)readSize);
  830. buf.setLength((unsigned)readSize);
  831. size32_t nRead = rIO->read(readFrom, (size32_t)readSize, (char*)buf.str());
  832. if (nRead != readSize)
  833. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE, "Failed to read file %s.", logname.str());
  834. dataBuffer.clear();
  835. if (dataLeft.length() > 0)
  836. dataBuffer.append(dataLeft);
  837. dataBuffer.append(buf);
  838. readFrom += nRead;
  839. fileSize -= nRead;
  840. return lastPage;
  841. }
  842. long CWsTopologyEx::readLogLineID(char* pTr)
  843. {
  844. long id = -1;
  845. StringBuffer lineID;
  846. int i = 0;
  847. while (i < 8)
  848. {
  849. if ((pTr[i] < 48) || ((pTr[i] > 57) && (pTr[i] < 65)) || (pTr[i] > 70))
  850. {
  851. lineID.clear();
  852. break;
  853. }
  854. lineID.append(pTr[i]);
  855. i++;
  856. }
  857. if (lineID.length() > 0)
  858. {
  859. id = strtol(lineID, NULL, 16);
  860. }
  861. return id;
  862. }
  863. bool CWsTopologyEx::readLogTime(char* pTr, int start, int length, CDateTime& dt)
  864. {
  865. bool bRet = false;
  866. try
  867. {
  868. char str[20];
  869. memset(str, 0, 20);
  870. strncpy(str, pTr+start, length);
  871. StringBuffer strBuf = str;
  872. strBuf.setCharAt(10, 'T');
  873. dt.setString(strBuf.str(), NULL, true);
  874. bRet = true;
  875. }
  876. catch(IException* e)
  877. {
  878. e->Release();
  879. }
  880. return bRet;
  881. }
  882. int CWsTopologyEx::checkLineTerminator(char* pTr)
  883. {
  884. char* ppTr = pTr;
  885. while(ppTr)
  886. {
  887. if (ppTr[0] == '\r' && ppTr[1] == '\n')
  888. {
  889. return 2;
  890. }
  891. if (ppTr[0] == '\r' || ppTr[0] == '\n')
  892. {
  893. return 1;
  894. }
  895. ppTr++;
  896. }
  897. return 0;
  898. }
  899. bool CWsTopologyEx::readLineTerminator(char* pTr, int& byteCount)
  900. {
  901. bool bFoundLineEnd = false;
  902. if (byteCount > 1)
  903. {
  904. if (pTr[0] == '\n')
  905. {
  906. bFoundLineEnd = true;
  907. }
  908. }
  909. else if (pTr[0] == '\r' || pTr[0] == '\n')
  910. {
  911. bFoundLineEnd = true;
  912. }
  913. return bFoundLineEnd;
  914. }
  915. void CWsTopologyEx::addALogLine(offset_t& readFrom, unsigned& locationFlag, long firstOrLastRowID, StringBuffer dataRow, ReadLog& readLogReq, StringArray& returnbuff)
  916. {
  917. long rowID = readLogLineID((char*)dataRow.str());
  918. if (readLogReq.filterType == 1) //first n rows
  919. {
  920. if (firstOrLastRowID > -1)
  921. {//there is row id to be used
  922. locationFlag = 1; //enter the area to be retrieved
  923. if ((rowID < 0) || (rowID - firstOrLastRowID < (long) readLogReq.firstRows)) //no row ID or the row ID is less than readLogReq.firstRows
  924. {
  925. returnbuff.append(dataRow);
  926. }
  927. else
  928. {
  929. locationFlag = 2; //out of the area to be retrieved
  930. }
  931. }
  932. else
  933. {
  934. locationFlag = 1; //enter the area to be retrieved
  935. returnbuff.append(dataRow);
  936. if (returnbuff.length() == readLogReq.firstRows)
  937. locationFlag = 2; //stop now since we have enough rows
  938. }
  939. }
  940. else if (readLogReq.filterType == 5) //last n rows
  941. {
  942. if (firstOrLastRowID > -1)
  943. {//there is row id to be used
  944. if ((locationFlag < 1) && (rowID > -1) && (firstOrLastRowID - rowID < (long) readLogReq.lastRows))
  945. locationFlag = 1;
  946. if (locationFlag > 0) //Add the rest of rows
  947. returnbuff.add(dataRow, 0);
  948. }
  949. else
  950. {
  951. if (returnbuff.length() == readLogReq.lastRows)
  952. returnbuff.remove(readLogReq.lastRows - 1);
  953. returnbuff.add(dataRow, 0);
  954. locationFlag = 1; //always in the area to be retrieved, but may be pushed out later
  955. }
  956. }
  957. else
  958. {
  959. if (rowID < 0) //row id not found
  960. {
  961. if (locationFlag > 0)
  962. {
  963. returnbuff.append(dataRow);
  964. }
  965. readFrom += dataRow.length();
  966. return;
  967. }
  968. char str[20];
  969. memset(str, 0, 20);
  970. dataRow.getChars(9, 28, str);
  971. if (readLogReq.endDate.length() > 0 && strcmp(str, readLogReq.endDate.str()) > 0)
  972. locationFlag = 2; //out of the area to be retrieved
  973. else if (readLogReq.startDate.length() < 1 || strcmp(str, readLogReq.startDate.str()) >= 0)
  974. {
  975. returnbuff.append(dataRow);
  976. if ((locationFlag < 1) && (readLogReq.filterType == 6))
  977. {
  978. readLogReq.pageFrom = readFrom;
  979. }
  980. readFrom += dataRow.length();
  981. locationFlag = 1; //enter the area to be retrieved
  982. }
  983. else
  984. {
  985. readFrom += dataRow.length();
  986. }
  987. }
  988. return;
  989. }
  990. bool CWsTopologyEx::onTpClusterQuery(IEspContext &context, IEspTpClusterQueryRequest &req, IEspTpClusterQueryResponse &resp)
  991. {
  992. try
  993. {
  994. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  995. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Cluster Query. Permission denied.");
  996. //another client (like configenv) may have updated the constant environment so reload it
  997. m_envFactory->validateCache();
  998. IArrayOf<IEspTpCluster> clusters;
  999. const char* type = req.getType();
  1000. if (!type || !*type || (strcmp(eqRootNode,type) == 0) || (strcmp(eqAllClusters,type) == 0))
  1001. {
  1002. m_TpWrapper.getClusterProcessList(eqHoleCluster, clusters);
  1003. m_TpWrapper.getClusterProcessList(eqThorCluster, clusters);
  1004. m_TpWrapper.getClusterProcessList(eqRoxieCluster,clusters);
  1005. }
  1006. else
  1007. {
  1008. m_TpWrapper.getClusterProcessList(type,clusters);
  1009. }
  1010. double version = context.getClientVersion();
  1011. if (version > 1.07)
  1012. {
  1013. resp.setEnableSNMP(m_enableSNMP);
  1014. }
  1015. resp.setTpClusters(clusters);
  1016. }
  1017. catch(IException* e)
  1018. {
  1019. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1020. }
  1021. return false;
  1022. }
  1023. bool CWsTopologyEx::onTpTargetClusterQuery(IEspContext &context, IEspTpTargetClusterQueryRequest &req, IEspTpTargetClusterQueryResponse &resp)
  1024. {
  1025. try
  1026. {
  1027. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1028. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Cluster Query. Permission denied.");
  1029. //another client (like configenv) may have updated the constant environment so reload it
  1030. m_envFactory->validateCache();
  1031. double version = context.getClientVersion();
  1032. IArrayOf<IEspTpTargetCluster> clusters;
  1033. const char* type = req.getType();
  1034. const char* name = req.getName();
  1035. if (!type || !*type || (strcmp(eqRootNode,type) == 0) || (strcmp(eqAllClusters,type) == 0))
  1036. {
  1037. m_TpWrapper.queryTargetClusters(version, eqAllClusters, NULL, clusters);
  1038. }
  1039. else if (!name || !*name)
  1040. {
  1041. m_TpWrapper.queryTargetClusters(version, type, NULL, clusters);
  1042. }
  1043. else
  1044. {
  1045. m_TpWrapper.queryTargetClusters(version, type, name, clusters);
  1046. }
  1047. resp.setMemThreshold( m_memThreshold );
  1048. resp.setDiskThreshold( m_diskThreshold );
  1049. resp.setCpuThreshold( m_cpuThreshold );
  1050. resp.setMemThresholdType( m_bMemThresholdIsPercentage ? "0" : "1");
  1051. resp.setDiskThresholdType( m_bDiskThresholdIsPercentage ? "0" : "1");
  1052. resp.setTpTargetClusters(clusters);
  1053. resp.setShowDetails(req.getShowDetails());
  1054. if ((version > 1.12) && (m_preflightProcessFilter.length() > 0))
  1055. {
  1056. resp.setPreflightProcessFilter(m_preflightProcessFilter);
  1057. }
  1058. }
  1059. catch(IException* e)
  1060. {
  1061. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1062. }
  1063. return false;
  1064. }
  1065. bool CWsTopologyEx::onTpLogicalClusterQuery(IEspContext &context, IEspTpLogicalClusterQueryRequest &req, IEspTpLogicalClusterQueryResponse &resp)
  1066. {
  1067. try
  1068. {
  1069. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1070. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Cluster Query. Permission denied.");
  1071. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  1072. Owned<IConstEnvironment> constEnv = factory->openEnvironmentByFile();
  1073. Owned<IPropertyTree> root = &constEnv->getPTree();
  1074. if (!root)
  1075. throw MakeStringException(ECLWATCH_CANNOT_GET_ENV_INFO, "Failed to get environment information.");
  1076. IArrayOf<IEspTpLogicalCluster> clusters;
  1077. Owned<IPropertyTreeIterator> clusterIterator = root->getElements("Software/Topology/Cluster");
  1078. if (clusterIterator->first())
  1079. {
  1080. do {
  1081. IPropertyTree &cluster0 = clusterIterator->query();
  1082. StringBuffer processName;
  1083. const char* clusterName0 = cluster0.queryProp("@name");
  1084. if (!clusterName0 || !*clusterName0)
  1085. continue;
  1086. IEspTpLogicalCluster* pService = createTpLogicalCluster("","");
  1087. pService->setName(clusterName0);
  1088. pService->setLanguageVersion("3.0.0");
  1089. clusters.append(*pService);
  1090. } while (clusterIterator->next());
  1091. }
  1092. resp.setTpLogicalClusters(clusters);
  1093. }
  1094. catch(IException* e)
  1095. {
  1096. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1097. }
  1098. return true;
  1099. }
  1100. bool CWsTopologyEx::onTpGroupQuery(IEspContext &context, IEspTpGroupQueryRequest &req, IEspTpGroupQueryResponse &resp)
  1101. {
  1102. try
  1103. {
  1104. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1105. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Group Query. Permission denied.");
  1106. IArrayOf<IEspTpGroup> Groups;
  1107. m_TpWrapper.getGroupList(Groups);
  1108. resp.setTpGroups(Groups);
  1109. }
  1110. catch(IException* e)
  1111. {
  1112. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1113. }
  1114. return true;
  1115. }
  1116. bool CWsTopologyEx::onTpClusterInfo(IEspContext &context, IEspTpClusterInfoRequest &req, IEspTpClusterInfoResponse& resp)
  1117. {
  1118. try
  1119. {
  1120. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1121. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to get Cluster Information. Permission denied.");
  1122. CClusterQueue cq(req.getName()); // NB name is probably queue name
  1123. if (cq.thors.ordinality()>0)
  1124. {
  1125. IPropertyTree &tree = cq.thors.item(0);
  1126. resp.setName(tree.queryProp("@thorname"));
  1127. resp.setWorkUnit(tree.queryProp("WorkUnit"));
  1128. double version = context.getClientVersion();
  1129. if (version > 1.09)
  1130. {
  1131. IArrayOf<IEspTpQueue> Queues;
  1132. ForEachItemIn(i,cq.thors)
  1133. {
  1134. IPropertyTree &tree = cq.thors.item(i);
  1135. IEspTpQueue* pQueue = createTpQueue("","");
  1136. pQueue->setName(tree.queryProp("@thorname"));
  1137. pQueue->setWorkUnit(tree.queryProp("WorkUnit"));
  1138. Queues.append(*pQueue);
  1139. }
  1140. resp.setTpQueues(Queues);
  1141. }
  1142. }
  1143. else // fallback to cluster name
  1144. {
  1145. IArrayOf<IEspTpQueue> Queues;
  1146. CCluster conn(req.getName());
  1147. IPropertyTree* tree = conn->queryRoot();
  1148. IEspTpQueue* pQueue = createTpQueue("","");
  1149. pQueue->setName(req.getName());
  1150. pQueue->setWorkUnit(tree->queryProp("WorkUnit"));
  1151. Queues.append(*pQueue);
  1152. resp.setTpQueues(Queues);
  1153. resp.setName(req.getName());
  1154. resp.setWorkUnit(tree->queryProp("WorkUnit"));
  1155. }
  1156. }
  1157. catch(IException* e)
  1158. {
  1159. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1160. }
  1161. return true;
  1162. }
  1163. bool CWsTopologyEx::onTpServiceQuery(IEspContext &context, IEspTpServiceQueryRequest &req, IEspTpServiceQueryResponse &resp)
  1164. {
  1165. try
  1166. {
  1167. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1168. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Service Query. Permission denied.");
  1169. double version = context.getClientVersion();
  1170. const char* type = req.getType();
  1171. if (!type || !*type || (strcmp(eqAllServices,type) == 0))
  1172. {
  1173. //another client (like configenv) may have updated the constant environment so reload it
  1174. m_envFactory->validateCache();
  1175. IEspTpServices& ServiceList = resp.updateServiceList();
  1176. m_TpWrapper.getTpDaliServers( ServiceList.getTpDalis() );
  1177. m_TpWrapper.getTpEclServers( ServiceList.getTpEclServers() );
  1178. m_TpWrapper.getTpEclCCServers( ServiceList.getTpEclCCServers() );
  1179. m_TpWrapper.getTpEclAgents( ServiceList.getTpEclAgents() );
  1180. m_TpWrapper.getTpEspServers( ServiceList.getTpEspServers() );
  1181. m_TpWrapper.getTpDfuServers( ServiceList.getTpDfuServers() );
  1182. m_TpWrapper.getTpSashaServers( ServiceList.getTpSashaServers() );
  1183. m_TpWrapper.getTpGenesisServers( ServiceList.getTpGenesisServers() );
  1184. m_TpWrapper.getTpLdapServers( ServiceList.getTpLdapServers() );
  1185. m_TpWrapper.getTpDropZones( ServiceList.getTpDropZones() );
  1186. m_TpWrapper.getTpFTSlaves( ServiceList.getTpFTSlaves() );
  1187. m_TpWrapper.getTpDkcSlaves( ServiceList.getTpDkcSlaves() );
  1188. if (version > 1.15)
  1189. {
  1190. m_TpWrapper.getTpEclSchedulers( ServiceList.getTpEclSchedulers() );
  1191. }
  1192. }
  1193. resp.setMemThreshold( m_memThreshold );
  1194. resp.setDiskThreshold( m_diskThreshold );
  1195. resp.setCpuThreshold( m_cpuThreshold );
  1196. resp.setMemThresholdType( m_bMemThresholdIsPercentage ? "0" : "1");
  1197. resp.setDiskThresholdType( m_bDiskThresholdIsPercentage ? "0" : "1");
  1198. if (version > 1.06 && m_bEncapsulatedSystem)
  1199. {
  1200. resp.setEncapsulatedSystem( m_bEncapsulatedSystem );
  1201. }
  1202. if (version > 1.07)
  1203. {
  1204. resp.setEnableSNMP(m_enableSNMP);
  1205. }
  1206. if ((version > 1.12) && (m_preflightProcessFilter.length() > 0))
  1207. {
  1208. resp.setPreflightProcessFilter(m_preflightProcessFilter);
  1209. }
  1210. }
  1211. catch(IException* e)
  1212. {
  1213. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1214. }
  1215. return true;
  1216. }
  1217. bool CWsTopologyEx::onTpMachineQuery(IEspContext &context, IEspTpMachineQueryRequest &req, IEspTpMachineQueryResponse &resp)
  1218. {
  1219. try
  1220. {
  1221. //another client (like configenv) may have updated the constant environment so reload it
  1222. m_envFactory->validateCache();
  1223. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
  1224. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Machine Query. Permission denied.");
  1225. double version = context.getClientVersion();
  1226. IArrayOf<IEspTpMachine> MachineList;
  1227. const char* path = req.getPath();
  1228. const char* directory = req.getDirectory();
  1229. bool hasThorSpareProcess = false;
  1230. const char* type = req.getType();
  1231. if (!type || !*type || (strcmp(eqAllNodes,type) == 0))
  1232. {
  1233. m_TpWrapper.getClusterMachineList(eqTHORMACHINES, path, directory, MachineList, hasThorSpareProcess);
  1234. m_TpWrapper.getClusterMachineList(eqHOLEMACHINES, path, directory, MachineList, hasThorSpareProcess);
  1235. m_TpWrapper.getClusterMachineList(eqROXIEMACHINES,path, directory, MachineList, hasThorSpareProcess);
  1236. }
  1237. else
  1238. {
  1239. m_TpWrapper.getClusterMachineList(type, path, directory, MachineList, hasThorSpareProcess);
  1240. }
  1241. resp.setTpMachines(MachineList);
  1242. resp.setType( req.getType() );
  1243. resp.setCluster( req.getCluster() );
  1244. resp.setOldIP( req.getOldIP() );
  1245. resp.setPath( req.getPath() );
  1246. resp.setLogDirectory( req.getLogDirectory() );
  1247. resp.setMemThreshold( m_memThreshold );
  1248. resp.setDiskThreshold( m_diskThreshold );
  1249. resp.setCpuThreshold( m_cpuThreshold );
  1250. resp.setMemThresholdType( m_bMemThresholdIsPercentage ? "0" : "1");
  1251. resp.setDiskThresholdType( m_bDiskThresholdIsPercentage ? "0" : "1");
  1252. SecAccessFlags access;
  1253. bool bEnablePreflightInfo = context.authorizeFeature(MACHINE_URL, access) &&
  1254. access >= SecAccess_Read;
  1255. resp.setEnablePreflightInfo( bEnablePreflightInfo );
  1256. if (version > 1.07)
  1257. {
  1258. resp.setEnableSNMP(m_enableSNMP);
  1259. }
  1260. if ((version > 1.12) && (m_preflightProcessFilter.length() > 0))
  1261. {
  1262. resp.setPreflightProcessFilter(m_preflightProcessFilter);
  1263. }
  1264. if (version > 1.14 && hasThorSpareProcess)
  1265. {
  1266. resp.setHasThorSpareProcess( hasThorSpareProcess );
  1267. }
  1268. }
  1269. catch(IException* e)
  1270. {
  1271. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1272. }
  1273. return false;
  1274. }
  1275. bool CWsTopologyEx::onTpGetComponentFile(IEspContext &context,
  1276. IEspTpGetComponentFileRequest &req,
  1277. IEspTpGetComponentFileResponse &resp)
  1278. {
  1279. try
  1280. {
  1281. if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Full, false))
  1282. throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Permission denied.");
  1283. const char* fileType = req.getFileType();
  1284. if (!fileType || (0!=stricmp(fileType, "cfg") && 0!=stricmp(fileType, "log")))
  1285. throw MakeStringException(ECLWATCH_INVALID_FILE_TYPE, "A valid file type requested. Only configuration and log files are supported!");
  1286. const char* compType = req.getCompType();
  1287. if (!compType || !*compType)
  1288. throw MakeStringExceptionDirect(ECLWATCH_INVALID_COMPONENT_TYPE, "Component type must be specified!");
  1289. const char* compName = req.getCompName();
  1290. const char* directory = req.getDirectory();
  1291. const char* netAddress = req.getNetAddress();
  1292. const char* fileName = NULL;
  1293. OS_TYPE osType = (OS_TYPE) req.getOsType();
  1294. bool bCluster = false;
  1295. if (!stricmp(fileType, "cfg"))
  1296. {
  1297. if (!stricmp(compType, eqDali))
  1298. fileName = "daliconf.xml";
  1299. else if (!stricmp(compType, eqDfu))
  1300. fileName = "dfuserver.xml";
  1301. else if (!stricmp(compType, eqEclServer))
  1302. fileName = "eclserver.xml";
  1303. else if (!stricmp(compType, eqEclCCServer))
  1304. fileName = "eclccserver.xml";
  1305. else if (!stricmp(compType, eqEclScheduler))
  1306. fileName = "eclscheduler.xml";
  1307. else if (!stricmp(compType, eqAgentExec))
  1308. fileName = "agentexec.xml";
  1309. else if (!stricmp(compType, eqEsp))
  1310. fileName = "esp.xml";
  1311. else if (!stricmp(compType, eqSashaServer))
  1312. fileName = "sashaconf.xml";
  1313. else if (!stricmp(compType, eqEclAgent))
  1314. fileName = osType==OS_WINDOWS ? "setvars.bat" : NULL;
  1315. else
  1316. {
  1317. const unsigned int len = strlen(compType);
  1318. if (len>4)
  1319. if (!strnicmp(compType, "Roxie", 5))
  1320. compType = "RoxieCluster", fileName = "RoxieTopology.xml", bCluster = true;
  1321. else if (!strnicmp(compType, "Thor", 4))
  1322. compType = "ThorCluster", fileName = "thor.xml", bCluster = true;
  1323. else if (!strnicmp(compType, "Hole", 4))
  1324. compType = "HoleCluster", fileName = "edata.ini", bCluster = true;
  1325. }
  1326. }
  1327. else
  1328. {
  1329. if (!stricmp(compType, eqDali))
  1330. fileName = "DaServer.log";
  1331. else if (!stricmp(compType, eqDfu))
  1332. fileName = "dfuserver.log";
  1333. else if (!stricmp(compType, eqEclServer))
  1334. fileName = "ECLSERVER.log";
  1335. else if (!stricmp(compType, eqEclCCServer))
  1336. fileName = "eclccserver.log";
  1337. else if (!stricmp(compType, eqEclScheduler))
  1338. fileName = "eclscheduler.log";
  1339. else if (!stricmp(compType, eqEsp))
  1340. fileName = "esp.log";
  1341. else if (!stricmp(compType, eqSashaServer))
  1342. fileName = "saserver.log";
  1343. else if (!stricmp(compType, eqEclAgent))
  1344. fileName = "";
  1345. else
  1346. {
  1347. const unsigned int len = strlen(compType);
  1348. if (len>4)
  1349. if (!strnicmp(compType, "Roxie", 5))
  1350. compType = "RoxieCluster", fileName = "", bCluster = true;
  1351. else if (!strnicmp(compType, "Thor", 4))
  1352. compType = "ThorCluster", fileName = "", bCluster = true;
  1353. else if (!strnicmp(compType, "Hole", 4))
  1354. compType = "HoleCluster", fileName = "", bCluster = true;
  1355. }
  1356. }
  1357. if (!fileName)
  1358. throw MakeStringExceptionDirect(ECLWATCH_INVALID_COMPONENT_OR_FILE_TYPE, "Unsupported component or file type specified!");
  1359. //the paths are all windows or samba network shares so construct windows network path
  1360. StringBuffer netAddressStr;
  1361. SCMStringBuffer scmNetAddress;
  1362. StringAttr sDirectory;
  1363. if (bCluster && !(netAddress && *netAddress))
  1364. {
  1365. //another client (like configenv) may have updated the constant environment so reload it
  1366. m_envFactory->validateCache();
  1367. Owned<IConstEnvironment> constEnv = m_envFactory->openEnvironmentByFile();
  1368. Owned<IPropertyTree> pRoot = &constEnv->getPTree();
  1369. StringBuffer xpath;
  1370. xpath.appendf("Software/%s[@name='%s']", compType, compName);
  1371. IPropertyTree* pCluster = pRoot->queryPropTree( xpath.str() );
  1372. if (!pCluster)
  1373. throw MakeStringException(ECLWATCH_COMPONENT_NOT_IN_ENV_INFO, "%s '%s' is not defined!", compType, compName);
  1374. if (!directory || !*directory)
  1375. {
  1376. sDirectory.set( pCluster->queryProp("@directory") );
  1377. directory = sDirectory.get();
  1378. }
  1379. xpath.clear();
  1380. if (!stricmp(compType, "RoxieCluster"))
  1381. xpath.append("RoxieServerProcess[1]");
  1382. else
  1383. if (!stricmp(compType, "ThorCluster"))
  1384. xpath.append("ThorMasterProcess");
  1385. else//HoleCluster
  1386. xpath.append("HoleControlProcess");
  1387. xpath.append("@computer");
  1388. const char* computer = pCluster->queryProp(xpath.str());
  1389. if (computer && *computer)
  1390. {
  1391. Owned<IConstMachineInfo> pMachine = constEnv->getMachine(computer);
  1392. if (pMachine)
  1393. {
  1394. pMachine->getNetAddress(scmNetAddress);
  1395. netAddressStr = scmNetAddress.str();
  1396. if (!strcmp(netAddressStr.str(), "."))
  1397. {
  1398. StringBuffer ipStr;
  1399. IpAddress ipaddr = queryHostIP();
  1400. ipaddr.getIpText(ipStr);
  1401. if (ipStr.length() > 0)
  1402. {
  1403. netAddressStr = ipStr.str();
  1404. }
  1405. }
  1406. }
  1407. }
  1408. }
  1409. if (netAddressStr.length() > 0)
  1410. netAddress = netAddressStr.str();
  1411. if (!directory || !*directory)
  1412. throw MakeStringExceptionDirect(ECLWATCH_INVALID_FILE_FOLDER, "Directory must be specified!");
  1413. if (!netAddress || !*netAddress)
  1414. throw MakeStringExceptionDirect(ECLWATCH_INVALID_IP, "Network address must be specified!");
  1415. StringBuffer sDir(directory);
  1416. const char pathSepChar = osType == OS_WINDOWS ? '\\' : '/';
  1417. if (*directory != pathSepChar)
  1418. sDir.insert(0, osType == OS_WINDOWS ? "\\" : "/");
  1419. if (osType == OS_WINDOWS)
  1420. sDir.replace(':', '$');
  1421. if (*fileName)
  1422. {
  1423. const unsigned int dirLen = sDir.length();
  1424. if (*fileName && *(sDir.str() + dirLen - 1) != pathSepChar)
  1425. sDir.append(pathSepChar);
  1426. }
  1427. //access remote path as \\ip\dir\file if we are running on windows, otherwise as //ip/dir/file
  1428. sDir.replace(pathSepChar == '/' ? '\\' : '/', pathSepChar);
  1429. StringBuffer uncPath;
  1430. uncPath.append(pathSepChar).append(pathSepChar).append(netAddress).append(sDir).append(fileName);
  1431. if (stricmp(fileType, "log") == 0)
  1432. {
  1433. StringBuffer url("/WsTopology/TpLogFile/");
  1434. if (bCluster)
  1435. url.appendf("%s?Name=%s&Type=tpcomp_log", compType, uncPath.str());
  1436. else
  1437. url.appendf("%s?Name=%s&Type=tpcomp_log&Reversely=true&FilterType=5&LastRows=300", compType, uncPath.str());
  1438. resp.setRedirectUrl(url.str());
  1439. }
  1440. else
  1441. {
  1442. Owned<IFile> pFile = createIFile(uncPath.str());
  1443. if (!pFile->exists())
  1444. {
  1445. if (!stricmp(fileType, "cfg") && !stricmp(compType, "DfuServerProcess"))
  1446. {
  1447. uncPath.clear().append(pathSepChar).append(pathSepChar).append(netAddress).append(sDir).append("dfuserver.ini");
  1448. pFile.setown(createIFile(uncPath.str()));
  1449. if (!pFile->exists())
  1450. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST, "The file '%s' does not exist!", uncPath.str());
  1451. }
  1452. else if (!stricmp(fileType, "cfg") && !stricmp(compType, "ThorCluster"))
  1453. {
  1454. uncPath.clear().append(pathSepChar).append(pathSepChar).append(netAddress).append(sDir).append("thor.ini");
  1455. pFile.setown(createIFile(uncPath.str()));
  1456. if (!pFile->exists())
  1457. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST, "The file '%s' does not exist!", uncPath.str());
  1458. }
  1459. else
  1460. {
  1461. throw MakeStringException(ECLWATCH_INVALID_FILE_TYPE, "The file '%s' does not exist!", uncPath.str());
  1462. }
  1463. }
  1464. Owned<IFileIO> pFileIO = pFile->openShared(IFOread, IFSHfull);
  1465. if (!pFileIO)
  1466. throw MakeStringException(ECLWATCH_CANNOT_OPEN_FILE, "The file '%s' could not be opened!", uncPath.str());
  1467. offset_t fileSize = pFile->size();
  1468. const long FILESIZELIMIT = 10000000; //In case of a huge file
  1469. if (fileSize > FILESIZELIMIT)
  1470. fileSize = FILESIZELIMIT;
  1471. MemoryBuffer buf;
  1472. size32_t nRead = read(pFileIO, 0, (size32_t)fileSize, buf);
  1473. if (nRead != fileSize)
  1474. throw MakeStringException(ECLWATCH_CANNOT_READ_FILE, "Failed to read file %s.", uncPath.str());
  1475. const char* pchBuf = buf.toByteArray();
  1476. const char* pchExt = strrchr(fileName, '.');
  1477. if (!pchExt || (pchBuf[0] != '<') || stricmp(++pchExt, "xml"))
  1478. {
  1479. resp.setFileContents_mimetype(HTTP_TYPE_TEXT_PLAIN);
  1480. resp.setFileContents(buf);
  1481. }
  1482. else
  1483. {
  1484. const char* plainText = req.getPlainText();
  1485. if (plainText && (!stricmp(plainText, "yes")))
  1486. {
  1487. StringBuffer xslBuf, xmlBuf;
  1488. if (esp::readFile("xslt/xmlformatter.xsl", xslBuf)<=0)
  1489. throw MakeStringException(ECLWATCH_FILE_NOT_EXIST, "Cannot open stylesheet xmlformatter.xsl");
  1490. Owned<IXslProcessor> proc = getXslProcessor();
  1491. Owned<IXslTransform> trans = proc->createXslTransform();
  1492. xmlBuf.append(buf.toByteArray(), 0, buf.length());
  1493. trans->setXmlSource(xmlBuf.str(), xmlBuf.length());
  1494. trans->setXslSource(xslBuf, xslBuf.length());
  1495. StringBuffer htmlBuf;
  1496. trans->transform(htmlBuf);
  1497. MemoryBuffer buf0;
  1498. buf0.append(htmlBuf.str());
  1499. resp.setFileContents(buf0);
  1500. resp.setFileContents_mimetype(HTTP_TYPE_TEXT_HTML);
  1501. }
  1502. else
  1503. {
  1504. //if this is an xml file and is missing the xml tag at the top then add it
  1505. if (strncmp(pchBuf, "<?", 2))
  1506. {
  1507. const char* header="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><?xml-stylesheet href=\"../esp/xslt/xmlformatter.xsl\" type=\"text/xsl\"?>";
  1508. const unsigned int headerLen = strlen(header);
  1509. buf.insertDirect(0, headerLen);
  1510. buf.writeDirect(0, headerLen, header);
  1511. }
  1512. else
  1513. {
  1514. const char* pBuf = strstr(pchBuf+2, "?>");
  1515. if (pBuf)
  1516. {
  1517. const char* header="<?xml-stylesheet href=\"../esp/xslt/xmlformatter.xsl\" type=\"text/xsl\"?>";
  1518. const unsigned int headerLen = strlen(header);
  1519. unsigned pos = pBuf - pchBuf + 2;
  1520. buf.insertDirect(pos, headerLen);
  1521. buf.writeDirect(pos, headerLen, header);
  1522. }
  1523. }
  1524. resp.setFileContents(buf);
  1525. resp.setFileContents_mimetype(HTTP_TYPE_TEXT_XML);
  1526. }
  1527. }
  1528. }
  1529. }
  1530. catch(IException* e)
  1531. {
  1532. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1533. }
  1534. return true;
  1535. }