ws_machineServiceRexec.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  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 "ws_machineService.hpp"
  15. #include "jarray.hpp"
  16. #include "jmisc.hpp"
  17. #include "exception_util.hpp"
  18. #include "rmtssh.hpp"
  19. //---------------------------------------------------------------------------------------------
  20. //NOTE: PART III of implementation for Cws_machineEx
  21. // PART I and II are in ws_machineService.cpp and ws_machineServiceMetrics.cpp resp.
  22. //---------------------------------------------------------------------------------------------
  23. static const char* EXEC_FEATURE_URL = "ExecuteAccess";
  24. //---------------------------------------------------------------------------------------------
  25. class CRemoteExecThreadParam : public CWsMachineThreadParam
  26. {
  27. public:
  28. IMPLEMENT_IINTERFACE;
  29. Owned<IEspRemoteExecResult> m_pExecResult;
  30. StringBuffer m_sCommand;
  31. StringBuffer m_userId;
  32. StringBuffer m_password;
  33. StringBuffer m_sConfigAddress;
  34. bool m_bWait;
  35. IEspContext& m_context;
  36. CRemoteExecThreadParam( const char* pszAddress, const char* cmd, bool wait,
  37. Cws_machineEx* pService, IEspContext &context)
  38. : CWsMachineThreadParam(pszAddress, "", pService),
  39. m_sCommand(cmd), m_bWait(wait), m_context(context)
  40. {
  41. }
  42. CRemoteExecThreadParam( const char* pszAddress, const char* pszConfigAddress, const char* cmd, bool wait,
  43. Cws_machineEx* pService, IEspContext &context)
  44. : CWsMachineThreadParam(pszAddress, "", "", pService),
  45. m_sCommand(cmd), m_bWait(wait), m_context(context)
  46. {
  47. m_sConfigAddress = pszConfigAddress;
  48. }
  49. virtual void setResultObject(void* pExecResult)
  50. {
  51. m_pExecResult.set( static_cast<IEspRemoteExecResult*>( pExecResult ));
  52. }
  53. virtual void setResponse( const char* resp )
  54. {
  55. m_pExecResult->setResponse( resp );
  56. }
  57. virtual void setResultCode( int code )
  58. {
  59. m_pExecResult->setResultCode( code );
  60. }
  61. virtual void setUserID( const char* userID )
  62. {
  63. m_userId.clear().append( userID );
  64. }
  65. virtual void setPassword( const char* password )
  66. {
  67. m_password.clear().append( password );
  68. }
  69. virtual void doWork()
  70. {
  71. try
  72. {
  73. StringBuffer userId;
  74. StringBuffer password;
  75. bool bLinux;
  76. if (m_sConfigAddress.length() < 1)
  77. {
  78. m_pService->getAccountAndPlatformInfo(m_sAddress.str(), userId, password, bLinux);
  79. }
  80. else
  81. {
  82. m_pService->getAccountAndPlatformInfo(m_sConfigAddress.str(), userId, password, bLinux);
  83. }
  84. if (!m_userId.length() || !m_password.length())
  85. {
  86. //BUG: 9825 - remote execution on linux needs to use individual accounts
  87. //use userid/password in ESP context for remote execution...
  88. if (bLinux)
  89. {
  90. userId.clear();
  91. password.clear();
  92. m_context.getUserID(userId);
  93. m_context.getPassword(password);
  94. }
  95. }
  96. else
  97. {
  98. userId.clear().append(m_userId);
  99. password.clear().append(m_password);
  100. }
  101. if (!m_sCommand.length())
  102. setResultCode(-1);
  103. else
  104. {
  105. IFRunSSH * connection = createFRunSSH();
  106. connection->init(m_sCommand.str(),NULL,NULL,NULL,5,0);
  107. connection->exec(IpAddress(m_sAddress.str()),NULL,true);
  108. }
  109. }
  110. // CFRunSSH uses a MakeStringExceptionDirect throw to pass code and result string to caller
  111. catch(IException* e)
  112. {
  113. // errorCode == -1 on successful CFRunSSH execution
  114. if(e->errorCode() == -1)
  115. setResultCode(0);
  116. else
  117. setResultCode(e->errorCode());
  118. StringBuffer buf;
  119. e->errorMessage(buf);
  120. if (buf.length() && buf.charAt(buf.length() - 1) == '\n') // strip newline
  121. buf.setLength(buf.length() - 1);
  122. // set regardless of return
  123. setResponse(buf.str());
  124. e->Release();
  125. }
  126. #ifndef NO_CATCHALL
  127. catch(...)
  128. {
  129. setResponse("An unknown exception occurred!");
  130. setResultCode(-1);
  131. }
  132. #endif
  133. }//doWork()
  134. };
  135. #ifndef _CONTAINERIZED
  136. //-------------------------------------------------StartStop--------------------------------------------------
  137. class CStartStopThreadParam : public CRemoteExecThreadParam
  138. {
  139. public:
  140. IMPLEMENT_IINTERFACE;
  141. Owned<IEspStartStopResult> m_pResult;
  142. bool m_bStop;
  143. bool m_useHPCCInit;
  144. #ifndef OLD_START_STOP
  145. CStartStopThreadParam( const char* pszAddress, const char* pszConfigAddress, bool bStop, bool useHPCCInit, Cws_machineEx* pService, IEspContext &context)
  146. : CRemoteExecThreadParam(pszAddress, pszConfigAddress, "", true, pService, context),
  147. m_bStop(bStop), m_useHPCCInit(useHPCCInit)
  148. {
  149. }
  150. #else
  151. CStartStopThreadParam( const char* pszAddress, bool bStop, bool useHPCCInit, Cws_machineEx* pService, IEspContext &context)
  152. : CRemoteExecThreadParam(pszAddress, "", true, pService, context),
  153. m_bStop(bStop), m_useHPCCInit(useHPCCInit)
  154. {
  155. }
  156. #endif
  157. virtual void setResultObject(void* pResult)
  158. {
  159. m_pResult.set( static_cast<IEspStartStopResult*>( pResult ));
  160. }
  161. virtual void setResponse( const char* resp )
  162. {
  163. m_pResult->setResponse( resp );
  164. }
  165. virtual void setResultCode( int code )
  166. {
  167. m_pResult->setResultCode( code );
  168. }
  169. virtual void doWork()
  170. {
  171. if (m_useHPCCInit)
  172. {
  173. //address specified can be either IP or name of component
  174. const char* address = m_sAddress.str();
  175. const char* configAddress = m_sConfigAddress.str();
  176. if (!address || !*address)
  177. throw MakeStringException(ECLWATCH_INVALID_IP_OR_COMPONENT, "Invalid address or component name was specified!");
  178. if (!strchr(address, '.')) //not an IP address
  179. {
  180. const char* compType = m_pResult->getCompType();
  181. const char* compName = address;
  182. if (!compType || !*compType)
  183. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_TYPE, "No component type specified!");
  184. StringBuffer xpath;
  185. if (!strcmp(compType, "RoxieCluster"))
  186. {
  187. xpath.append("RoxieServer");
  188. }
  189. else if (!strcmp(compType, "ThorCluster"))
  190. {
  191. xpath.append("ThorMaster");
  192. }
  193. else if (!strcmp(compType, "HoleCluster"))
  194. {
  195. xpath.append("HoleControl");
  196. }
  197. else
  198. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_TYPE, "Failed to resolve component type '%s'", compType);
  199. Owned<IPropertyTree> pComponent = m_pService->getComponent(compType, compName);
  200. xpath.append("Process[1]/@computer");
  201. const char* computer = pComponent->queryProp(xpath.str());
  202. if (!computer || !*computer)
  203. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_INFO, "Failed to resolve computer for %s '%s'!", compType, compName);
  204. Owned<IConstEnvironment> pConstEnv = m_pService->getConstEnvironment();
  205. Owned<IConstMachineInfo> pConstMc = pConstEnv->getMachine(computer);
  206. SCMStringBuffer sAddress;
  207. pConstMc->getNetAddress(sAddress);
  208. if (!stricmp(m_sAddress.str(), m_sConfigAddress.str()))
  209. {
  210. m_sAddress.clear().append(sAddress.str());
  211. m_sConfigAddress = m_sAddress;
  212. m_pResult->setAddress( sAddress.str() );
  213. }
  214. else
  215. {
  216. m_sAddress.clear().append(sAddress.str());
  217. m_pResult->setAddress( sAddress.str() );
  218. if (configAddress && !strchr(configAddress, '.')) //not an IP address
  219. {
  220. Owned<IPropertyTree> pComponent = m_pService->getComponent(compType, configAddress);
  221. xpath.append("Process[1]/@computer");
  222. const char* computer = pComponent->queryProp(xpath.str());
  223. if (!computer || !*computer)
  224. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_INFO, "Failed to resolve computer for %s '%s'!", compType, configAddress);
  225. Owned<IConstEnvironment> pConstEnv = m_pService->getConstEnvironment();
  226. Owned<IConstMachineInfo> pConstMc = pConstEnv->getMachine(computer);
  227. SCMStringBuffer sAddress;
  228. pConstMc->getNetAddress(sAddress);
  229. m_sConfigAddress.clear().append(sAddress.str());
  230. }
  231. }
  232. }
  233. if ((m_sAddress.length() > 0) && !stricmp(m_sAddress.str(), "."))
  234. {
  235. StringBuffer ipStr;
  236. IpAddress ipaddr = queryHostIP();
  237. ipaddr.getIpText(ipStr);
  238. if (ipStr.length() > 0)
  239. {
  240. #ifdef MACHINE_IP
  241. m_sAddress.clear().append(MACHINE_IP);
  242. #else
  243. m_sAddress.clear().append(ipStr.str());
  244. #endif
  245. m_pResult->setAddress( m_sAddress.str() );
  246. }
  247. }
  248. #ifdef OLD_START_STOP
  249. int OS = m_pResult->getOS();
  250. StringBuffer sPath( m_pResult->getPath() );
  251. if (OS == 0)
  252. sPath.replace('$', ':');
  253. else
  254. if (sPath.charAt(0) != '/')
  255. sPath.insert(0, '/');
  256. m_sCommand.clear().append(sPath).append( OS==0 ? '\\' : '/');
  257. m_sCommand.append(m_bStop ? "stop" : "startup");
  258. if (OS == 0)
  259. m_sCommand.append(".bat");
  260. m_sCommand.append(' ');
  261. m_sCommand.append(sPath);
  262. #else
  263. StringBuffer sPath( m_pResult->getPath() );
  264. if (sPath.charAt(sPath.length() - 1) == '/')
  265. sPath.setLength(sPath.length() - 1);
  266. if (sPath.length() > 0)
  267. {
  268. char* pStr = (char*) sPath.str();
  269. char* ppStr = strchr(pStr, '/');
  270. while (ppStr)
  271. {
  272. ppStr++;
  273. pStr = ppStr;
  274. ppStr = strchr(pStr, '/');
  275. }
  276. if (!m_bStop)
  277. m_sCommand.appendf("sudo /etc/init.d/hpcc-init -c %s start", pStr);
  278. else
  279. m_sCommand.appendf("sudo /etc/init.d/hpcc-init -c %s stop", pStr);
  280. }
  281. #endif
  282. m_pResult->setCommand( m_sCommand.str() );
  283. }
  284. else
  285. {
  286. //address specified can be either IP or name of component
  287. const char* address = m_sAddress.str();
  288. if (!address || !*address)
  289. throw MakeStringException(ECLWATCH_INVALID_IP_OR_COMPONENT, "Invalid address or component name was specified!");
  290. if (!strchr(address, '.')) //not an IP address
  291. {
  292. const char* compType = m_pResult->getCompType();
  293. const char* compName = address;
  294. if (!compType || !*compType)
  295. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_TYPE, "No component type specified!");
  296. StringBuffer xpath;
  297. if (!strcmp(compType, "RoxieCluster"))
  298. {
  299. xpath.append("RoxieServer");
  300. }
  301. else if (!strcmp(compType, "ThorCluster"))
  302. {
  303. xpath.append("ThorMaster");
  304. }
  305. else if (!strcmp(compType, "HoleCluster"))
  306. {
  307. xpath.append("HoleControl");
  308. }
  309. else
  310. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_TYPE, "Failed to resolve component type '%s'", compType);
  311. Owned<IPropertyTree> pComponent = m_pService->getComponent(compType, compName);
  312. xpath.append("Process[1]/@computer");
  313. const char* computer = pComponent->queryProp(xpath.str());
  314. if (!computer || !*computer)
  315. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_INFO, "Failed to resolve computer for %s '%s'!", compType, compName);
  316. Owned<IConstEnvironment> pConstEnv = m_pService->getConstEnvironment();
  317. Owned<IConstMachineInfo> pConstMc = pConstEnv->getMachine(computer);
  318. SCMStringBuffer sAddress;
  319. pConstMc->getNetAddress(sAddress);
  320. m_sAddress.clear().append(sAddress.str());
  321. m_pResult->setAddress( sAddress.str() );
  322. }
  323. int OS = m_pResult->getOS();
  324. StringBuffer sPath( m_pResult->getPath() );
  325. if (OS == 0)
  326. sPath.replace('$', ':');
  327. else
  328. if (sPath.charAt(0) != '/')
  329. sPath.insert(0, '/');
  330. m_sCommand.clear().append(sPath).append( OS==0 ? '\\' : '/');
  331. m_sCommand.append(m_bStop ? "stop" : "startup");
  332. if (OS == 0)
  333. m_sCommand.append(".bat");
  334. m_sCommand.append(' ');
  335. m_sCommand.append(sPath);
  336. m_pResult->setCommand( m_sCommand.str() );
  337. }
  338. CRemoteExecThreadParam::doWork();
  339. }
  340. };
  341. void Cws_machineEx::ConvertAddress( const char* originalAddress, StringBuffer& newAddress)
  342. {
  343. if (!originalAddress || !*originalAddress)
  344. throw MakeStringException(ECLWATCH_INVALID_IP_OR_COMPONENT, "No network address or computer name specified!");
  345. StringArray sArray;
  346. sArray.appendList(originalAddress, ":");
  347. if (sArray.ordinality() < 4)
  348. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Incomplete arguments");
  349. const char* address = sArray.item(0);
  350. const char* compType= sArray.item(1);
  351. const char* compName= sArray.item(2);
  352. const char* OS = sArray.item(3);
  353. const char* path = sArray.item(4);
  354. StringBuffer process;
  355. if (sArray.ordinality() > 5)
  356. {
  357. const char* ClusterType = sArray.item(5);
  358. if (ClusterType && *ClusterType)
  359. {
  360. if (strcmp("THORMACHINES",ClusterType) == 0)
  361. {
  362. process.append("ThorMasterProcess");
  363. }
  364. else if (strcmp("ROXIEMACHINES",ClusterType) == 0)
  365. {
  366. process.append("RoxieServerProcess");
  367. }
  368. }
  369. }
  370. if (strchr(address, '.')) //have an IP address
  371. {
  372. newAddress.clear().append(originalAddress);
  373. return;
  374. }
  375. StringBuffer xpath;
  376. if (!strcmp(compType, "RoxieCluster"))
  377. {
  378. xpath.append("RoxieServer");
  379. }
  380. else if (!strcmp(compType, "ThorCluster"))
  381. {
  382. xpath.append("ThorMaster");
  383. }
  384. else if (!strcmp(compType, "HoleCluster"))
  385. {
  386. xpath.append("HoleControl");
  387. }
  388. else
  389. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_TYPE, "Failed to resolve address for component type '%s'", compType);
  390. Owned<IPropertyTree> pComponent = getComponent(compType, address);
  391. xpath.append("Process[1]/@computer");
  392. const char* computer = pComponent->queryProp(xpath.str());
  393. if (!computer || !*computer)
  394. throw MakeStringException(ECLWATCH_INVALID_COMPONENT_INFO, "Failed to resolve computer for %s '%s'!", compType, address);
  395. Owned<IConstEnvironment> pConstEnv = getConstEnvironment();
  396. Owned<IConstMachineInfo> pConstMc = pConstEnv->getMachine(computer);
  397. SCMStringBuffer sAddress;
  398. pConstMc->getNetAddress(sAddress);
  399. #ifndef OLD_START_STOP
  400. {
  401. StringBuffer sConfigAddress;
  402. sConfigAddress.append(sAddress.str());
  403. if (!strcmp(sAddress.str(), "."))
  404. {
  405. StringBuffer ipStr;
  406. IpAddress ipaddr = queryHostIP();
  407. ipaddr.getIpText(ipStr);
  408. if (ipStr.length() > 0)
  409. {
  410. #ifdef MACHINE_IP
  411. sAddress.set(MACHINE_IP);
  412. #else
  413. sAddress.set(ipStr.str());
  414. #endif
  415. }
  416. }
  417. if (process.length() > 0)
  418. newAddress.clear().appendf("%s|%s:%s:%s:%s:%s", sAddress.str(), sConfigAddress.str(), process.str(), compName, OS, path);
  419. else
  420. newAddress.clear().appendf("%s|%s:%s:%s:%s:%s", sAddress.str(), sConfigAddress.str(), compType, compName, OS, path);
  421. }
  422. #else
  423. if (process.length() > 0)
  424. newAddress.clear().appendf("%s:%s:%s:%s:%s", sAddress.str(), process.str(), compName, OS, path);
  425. else
  426. newAddress.clear().appendf("%s:%s:%s:%s:%s", sAddress.str(), compType, compName, OS, path);
  427. //newAddress.clear().appendf("%s:ThorMasterProcess:%s:%s:%s", sAddress.str(), compName, OS, path);
  428. #endif
  429. return;
  430. }
  431. #endif
  432. bool Cws_machineEx::doStartStop(IEspContext &context, StringArray& addresses, char* userName, char* password, bool bStop,
  433. IEspStartStopResponse &resp)
  434. {
  435. #ifdef _CONTAINERIZED
  436. UNIMPLEMENTED_X("CONTAINERIZED(Cws_machineEx::doStartStop)");
  437. #else
  438. bool containCluster = false;
  439. double version = context.getClientVersion();
  440. const int ordinality= addresses.ordinality();
  441. UnsignedArray threadHandles;
  442. IArrayOf<IEspStartStopResult> resultsArray;
  443. for (int index=0; index<ordinality; index++)
  444. {
  445. const char* address0 = addresses.item(index);
  446. //address passed in is of the form "192.168.1.4:EspProcess:2:path1"
  447. StringArray sArray;
  448. sArray.appendList(addresses.item(index), ":");
  449. if (sArray.ordinality() < 4)
  450. throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Incomplete arguments");
  451. Owned<IEspStartStopResult> pResult = static_cast<IEspStartStopResult*>(new CStartStopResult(""));
  452. const char* address = sArray.item(0);
  453. const char* compType= sArray.item(1);
  454. const char* OS = sArray.item(3);//index 2 is component name
  455. const char* path = sArray.item(4);
  456. if (!(address && *address && compType && *compType && OS && *OS && path && *path))
  457. throw MakeStringExceptionDirect(ECLWATCH_INVALID_INPUT, "Invalid input");
  458. if (!stricmp(compType, "ThorCluster") || !stricmp(compType, "RoxieCluster"))
  459. containCluster = true;
  460. #ifndef OLD_START_STOP
  461. {
  462. char* configAddress = NULL;
  463. char* props1 = (char*) strchr(address, '|');
  464. if (props1)
  465. {
  466. configAddress = props1+1;
  467. *props1 = '\0';
  468. }
  469. else
  470. {
  471. configAddress = (char*) address;
  472. }
  473. StringBuffer newAddress;
  474. ConvertAddress(address0, newAddress);
  475. pResult->setAddressOrig ( newAddress.str() );//can be either IP or name of component
  476. pResult->setAddress ( address );//can be either IP or name of component
  477. pResult->setCompType( compType );
  478. if (version > 1.04)
  479. {
  480. pResult->setName( path );
  481. const char* pStr2 = strstr(path, "LexisNexis");
  482. if (pStr2)
  483. {
  484. char name[256];
  485. const char* pStr1 = strchr(pStr2, '|');
  486. if (!pStr1)
  487. {
  488. strcpy(name, pStr2+11);
  489. }
  490. else
  491. {
  492. strncpy(name, pStr2+11, pStr1 - pStr2 -11);
  493. name[pStr1 - pStr2 -11] = 0;
  494. }
  495. pResult->setName( name );
  496. }
  497. }
  498. pResult->setOS( atoi(OS) );
  499. pResult->setPath( path );
  500. resultsArray.append(*pResult.getLink());
  501. CStartStopThreadParam* pThreadReq;
  502. pThreadReq = new CStartStopThreadParam(address, configAddress, bStop, m_useDefaultHPCCInit, this, context);
  503. pThreadReq->setResultObject( pResult );
  504. if (userName && *userName)
  505. pThreadReq->setUserID( userName );
  506. if (password && *password)
  507. pThreadReq->setPassword( password );
  508. PooledThreadHandle handle = m_threadPool->start( pThreadReq );
  509. threadHandles.append(handle);
  510. }
  511. #else
  512. {
  513. StringBuffer newAddress;
  514. ConvertAddress(address0, newAddress);
  515. char* pStr = (char*) strchr(address, '|');;
  516. if (pStr)
  517. pStr[0] = 0;
  518. pResult->setAddressOrig ( newAddress.str() );//can be either IP or name of component
  519. pResult->setAddress ( address );//can be either IP or name of component
  520. pResult->setCompType( compType );
  521. pResult->setOS( atoi(OS) );
  522. pResult->setPath( path );
  523. resultsArray.append(*pResult.getLink());
  524. CStartStopThreadParam* pThreadReq;
  525. pThreadReq = new CStartStopThreadParam(address, bStop, this, context);
  526. pThreadReq->setResultObject( pResult );
  527. if (userName && *userName)
  528. pThreadReq->setUserID( userName );
  529. if (password && *password)
  530. pThreadReq->setPassword( password );
  531. PooledThreadHandle handle = m_threadPool->start( pThreadReq );
  532. threadHandles.append(handle);
  533. }
  534. #endif
  535. }
  536. //block for worker theads to finish, if necessary, and then collect results
  537. //
  538. PooledThreadHandle* pThreadHandle = threadHandles.getArray();
  539. unsigned i=threadHandles.ordinality();
  540. while (i--)
  541. {
  542. m_threadPool->join(*pThreadHandle, 30000);//abort after 30 secs in remote possibility that the command blocks
  543. pThreadHandle++;
  544. }
  545. resp.setStartStopResults(resultsArray);
  546. resp.setStop(bStop);
  547. if (version > 1.08)
  548. {
  549. resp.setContainCluster(containCluster);
  550. }
  551. return true;
  552. #endif
  553. }
  554. bool Cws_machineEx::onStartStop( IEspContext &context, IEspStartStopRequest &req,
  555. IEspStartStopResponse &resp)
  556. {
  557. throw MakeStringException(ECLWATCH_INTERNAL_ERROR, "StartStop feature not supported.");
  558. //following code is no longer accessible but will remain for reference
  559. try
  560. {
  561. context.ensureFeatureAccess(EXEC_FEATURE_URL, SecAccess_Full, ECLWATCH_EXECUTION_ACCESS_DENIED, "Failed to Start/stop. Permission denied.");
  562. char* userName = (char*) m_sTestStr1.str();
  563. char* password = (char*) m_sTestStr2.str();
  564. doStartStop(context, req.getAddresses(), userName, password, req.getStop(), resp);
  565. }
  566. catch(IException* e)
  567. {
  568. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  569. }
  570. return true;
  571. }
  572. void Cws_machineEx::updatePathInAddress(const char* address, StringBuffer& addrStr)
  573. {
  574. addrStr.append(address);
  575. StringArray sArray;
  576. sArray.appendList(address, ":");
  577. const char* OS = sArray.item(3);
  578. const char* Dir = sArray.item(4);
  579. if (OS && *OS && Dir && *Dir)
  580. {
  581. char oldC1 = '/';
  582. char oldC2 = '$';
  583. char newC1 = '\\';
  584. char newC2 = ':';
  585. int os = atoi(OS);
  586. if (os == 2) //2: linux
  587. {
  588. oldC1 = '\\';
  589. oldC2 = ':';
  590. newC1 = '/';
  591. newC2 = '$';
  592. }
  593. StringBuffer dirStr(Dir);
  594. dirStr.replace(oldC1, newC1);
  595. dirStr.replace(oldC2, newC2);
  596. if ((os == 2) && (dirStr.charAt(0) != '/'))
  597. dirStr.insert(0, '/');
  598. addrStr.clear();
  599. for (unsigned i = 0; i < sArray.length(); i++)
  600. {
  601. const char* item = sArray.item(i);
  602. if (i == 4)
  603. addrStr.appendf(":%s", dirStr.str());
  604. else if (item && *item)
  605. {
  606. if (i == 0)
  607. addrStr.append(item);
  608. else
  609. addrStr.appendf(":%s", item);
  610. }
  611. }
  612. }
  613. return;
  614. }
  615. bool Cws_machineEx::onStartStopBegin( IEspContext &context, IEspStartStopBeginRequest &req,
  616. IEspStartStopBeginResponse &resp)
  617. {
  618. throw MakeStringException(ECLWATCH_INTERNAL_ERROR, "StartStopBegin feature not supported.");
  619. //following code is no longer accessible but will remain for reference
  620. try
  621. {
  622. context.ensureFeatureAccess(EXEC_FEATURE_URL, SecAccess_Full, ECLWATCH_EXECUTION_ACCESS_DENIED, "Failed to Start/stop. Permission denied.");
  623. StringBuffer addresses;
  624. StringArray& addresses0 = req.getAddresses();
  625. for(unsigned i = 0; i < addresses0.length(); i++)
  626. {
  627. StringBuffer addrStr;
  628. const char* address = addresses0.item(i);
  629. updatePathInAddress(address, addrStr);
  630. if (i > 0)
  631. addresses.appendf("|Addresses_i%d=%s", i+1, addrStr.str());
  632. else
  633. addresses.appendf("Addresses_i1=%s", addrStr.str());
  634. }
  635. resp.setAddresses(addresses);
  636. resp.setKey1(req.getKey1());
  637. resp.setKey2(req.getKey2());
  638. resp.setStop(req.getStop());
  639. double version = context.getClientVersion();
  640. if (version > 1.07)
  641. {
  642. resp.setAutoRefresh( req.getAutoRefresh() );
  643. resp.setMemThreshold(req.getMemThreshold());
  644. resp.setDiskThreshold(req.getDiskThreshold());
  645. resp.setCpuThreshold(req.getCpuThreshold());
  646. resp.setMemThresholdType(req.getMemThresholdType());
  647. resp.setDiskThresholdType(req.getDiskThresholdType());
  648. }
  649. }
  650. catch(IException* e)
  651. {
  652. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  653. }
  654. return true;
  655. }
  656. bool Cws_machineEx::onStartStopDone( IEspContext &context, IEspStartStopDoneRequest &req,
  657. IEspStartStopResponse &resp)
  658. {
  659. throw MakeStringException(ECLWATCH_INTERNAL_ERROR, "StartStopDone feature not supported.");
  660. //following code is no longer accessible but will remain for reference
  661. try
  662. {
  663. context.ensureFeatureAccess(EXEC_FEATURE_URL, SecAccess_Full, ECLWATCH_EXECUTION_ACCESS_DENIED, "Failed to Start/stop. Permission denied.");
  664. const char*addresses0 = req.getAddresses();
  665. bool bStop = req.getStop();
  666. char* userName = (char*) m_sTestStr1.str();
  667. char* password = (char*) m_sTestStr2.str();
  668. StringArray addresses;
  669. char* pAddr = (char*) addresses0;
  670. while (pAddr)
  671. {
  672. char* ppAddr = strstr(pAddr, "|Addresses_");
  673. if (!ppAddr)
  674. {
  675. char* ppAddr0 = strchr(pAddr, '=');
  676. if (!ppAddr0)
  677. addresses.append(pAddr);
  678. else
  679. addresses.append(ppAddr0+1);
  680. break;
  681. }
  682. else
  683. {
  684. char addr[1024];
  685. strncpy(addr, pAddr, ppAddr - pAddr);
  686. addr[ppAddr - pAddr] = 0;
  687. char* ppAddr0 = strchr(addr, '=');
  688. if (!ppAddr0)
  689. addresses.append(addr);
  690. else
  691. addresses.append(ppAddr0+1);
  692. pAddr = ppAddr + 1;
  693. }
  694. }
  695. doStartStop(context, addresses, userName, password, bStop, resp);
  696. double version = context.getClientVersion();
  697. if (version > 1.07)
  698. {
  699. resp.setAutoRefresh( req.getAutoRefresh() );
  700. resp.setMemThreshold(req.getMemThreshold());
  701. resp.setDiskThreshold(req.getDiskThreshold());
  702. resp.setCpuThreshold(req.getCpuThreshold());
  703. resp.setMemThresholdType(req.getMemThresholdType());
  704. resp.setDiskThresholdType(req.getDiskThresholdType());
  705. }
  706. }
  707. catch(IException* e)
  708. {
  709. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  710. }
  711. return true;
  712. }