PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/bitrix/js/scale/action.js

https://gitlab.com/Rad1calDreamer/honey
JavaScript | 511 lines | 386 code | 75 blank | 50 comment | 92 complexity | 2e9b8f829c22483977fb67d813cdc8ad MD5 | raw file
  1. /**
  2. * Class BX.Scale.Action
  3. * Describes action's props, view & behavior
  4. */
  5. ;(function(window) {
  6. if (BX.Scale.Action) return;
  7. /**
  8. * Class BX.Scale.Action
  9. * @constructor
  10. */
  11. BX.Scale.Action = function (id, params)
  12. {
  13. this.id = id;
  14. this.name = params.NAME;
  15. this.userParams = params.USER_PARAMS;
  16. this.freeParams = {};
  17. if(params && params.TYPE !== undefined)
  18. this.type = params.TYPE;
  19. else
  20. this.type = "ACTION";
  21. if(this.type == "CHAIN" && params.ACTIONS !== undefined)
  22. this.actions = params.ACTIONS;
  23. else if(this.type == "MODIFYED")
  24. this.allParams = params;
  25. this.currentOperation = "";
  26. this.paramsDialog = null;
  27. this.async = params.ASYNC == "Y";
  28. this.pageRefresh = params.PAGE_REFRESH == "Y";
  29. this.backupAlert = params.BACKUP_ALERT == "Y";
  30. this.timeToComplete = null;
  31. this.timeToCompleteInterval = null;
  32. this.extraDbConfirm = params.CHECK_EXTRA_DB_USER_ASK == "Y";
  33. this.skipConfirmation = false;
  34. };
  35. /**
  36. * Returns list of params to ask user
  37. * @returns {{}}
  38. */
  39. BX.Scale.Action.prototype.getUserParams = function()
  40. {
  41. var result = {};
  42. if(this.type == "CHAIN")
  43. result = this.extractUserParamsFromActions();
  44. else
  45. result = this.userParams;
  46. return result;
  47. };
  48. /**
  49. * In case actions chain returns all user params from all actions
  50. * @returns {{}}
  51. */
  52. BX.Scale.Action.prototype.extractUserParamsFromActions = function()
  53. {
  54. var result = {};
  55. for(var actionId in this.actions)
  56. {
  57. var actUserParams = BX.Scale.actionsCollection.getObject(this.actions[actionId]).getUserParams();
  58. for(var paramId in actUserParams)
  59. result[paramId] = actUserParams[paramId];
  60. }
  61. return result;
  62. };
  63. /**
  64. * Starts execution of the action
  65. * @param serverHostname
  66. * @param paramsValues
  67. * @param skipBackupAlert
  68. */
  69. BX.Scale.Action.prototype.start = function(serverHostname, paramsValues, skipBackupAlert)
  70. {
  71. var _this = this;
  72. if(this.backupAlert && !skipBackupAlert)
  73. {
  74. BX.Scale.AdminFrame.confirm(
  75. BX.message("SCALE_PANEL_JS_ADVICE_TO_BACKUP"),
  76. BX.message("SCALE_PANEL_JS_ADVICE_TO_BACKUP_TITLE"),
  77. function(){ window.location.href = "/bitrix/admin/dump.php?lang="+BX.message('LANGUAGE_ID'); },
  78. function() { _this.start(serverHostname, paramsValues, true); }
  79. );
  80. return;
  81. }
  82. if(this.extraDbConfirm)
  83. {
  84. BX.Scale.AdminFrame.confirm(
  85. BX.message("SCALE_PANEL_JS_EXTRA_DB_CONFIRM"),
  86. BX.message("SCALE_PANEL_JS_EXTRA_DB_CONFIRM_TITLE"),
  87. function() {
  88. _this.extraDbConfirm = false;
  89. _this.skipConfirmation = true;
  90. _this.start(serverHostname, paramsValues, true);
  91. }
  92. );
  93. return;
  94. }
  95. var userParams = this.getUserParams();
  96. var freeParams = {};
  97. this.currentOperation = "start";
  98. if(paramsValues !== undefined)
  99. {
  100. for(var key in paramsValues)
  101. {
  102. if(userParams && userParams[key] !== undefined)
  103. userParams[key].DEFAULT_VALUE = paramsValues[key];
  104. else
  105. this.freeParams[key] = paramsValues[key];
  106. }
  107. }
  108. if(userParams !== undefined)
  109. {
  110. this.paramsDialog = new BX.Scale.ActionParamsDialog({
  111. title: this.name,
  112. userParams: userParams,
  113. serverHostname: serverHostname,
  114. callback: this.sendRequest,
  115. context: this
  116. });
  117. this.paramsDialog.show();
  118. }
  119. else if(!this.skipConfirmation)
  120. {
  121. BX.Scale.AdminFrame.confirm(
  122. BX.message("SCALE_PANEL_JS_ACT_CONFIRM")+" "+this.name.toLowerCase()+"?",
  123. BX.message("SCALE_PANEL_JS_ACT_CONFIRM_TITLE"),
  124. BX.proxy(function(){ this.sendRequest({ serverHostname: serverHostname, freeParams: freeParams }); }, this)
  125. );
  126. }
  127. else if(this.skipConfirmation)
  128. {
  129. this.skipConfirmation = false;
  130. this.sendRequest({ serverHostname: serverHostname, freeParams: freeParams });
  131. }
  132. };
  133. /**
  134. * Shows the action execution results
  135. * @param result
  136. */
  137. BX.Scale.Action.prototype.showResultDialog = function(result)
  138. {
  139. var resultDialog = new BX.Scale.ActionResultDialog({
  140. actionName: this.name,
  141. result: result,
  142. pageRefresh: this.pageRefresh
  143. });
  144. resultDialog.show();
  145. };
  146. /**
  147. * Shows the dialog of the async action's execution process
  148. * @param {object} result -request result
  149. */
  150. BX.Scale.Action.prototype.showAsyncDialog = function(result)
  151. {
  152. BX.Scale.ActionProcessDialog.addActionProcess(this.name);
  153. BX.Scale.AdminFrame.timeIntervalId = setInterval(BX.proxy(this.checkAsyncState, this), BX.Scale.AdminFrame.timeAsyncRefresh);
  154. if( result.ACTION_RESULT
  155. && result.ACTION_RESULT[this.id]
  156. && result.ACTION_RESULT[this.id].OUTPUT
  157. && result.ACTION_RESULT[this.id].OUTPUT.DATA
  158. )
  159. {
  160. if(result.ACTION_RESULT[this.id].OUTPUT.DATA.message)
  161. BX.Scale.ActionProcessDialog.addActionMessage(result.ACTION_RESULT[this.id].OUTPUT.DATA.message);
  162. if(result.ACTION_RESULT[this.id].OUTPUT.DATA.params)
  163. {
  164. for(var i in result.ACTION_RESULT[this.id].OUTPUT.DATA.params)
  165. {
  166. BX.Scale.AdminFrame.currentAsyncActionBID = i;
  167. break;
  168. }
  169. }
  170. }
  171. BX.Scale.ActionProcessDialog.pageRefresh = this.pageRefresh;
  172. BX.Scale.ActionProcessDialog.show();
  173. if(BX.Scale.AdminFrame.currentAsyncActionBID.length <= 0)
  174. {
  175. BX.Scale.ActionProcessDialog.addActionMessage(result.ACTION_RESULT[this.id].OUTPUT.TEXT);
  176. if(result.ACTION_RESULT[this.id].ERROR.length > 0)
  177. BX.Scale.ActionProcessDialog.addActionMessage(result.ACTION_RESULT[this.id].ERROR);
  178. BX.Scale.ActionProcessDialog.setActionResult(false, BX.message("SCALE_PANEL_JS_BID_ERROR"));
  179. }
  180. };
  181. /**
  182. * Forms request params to execute action
  183. */
  184. BX.Scale.Action.prototype.checkAsyncState = function()
  185. {
  186. if(BX.Scale.AdminFrame.currentAsyncActionBID.length <= 0 )
  187. return false;
  188. var sendPrams = {
  189. operation: "check_state",
  190. bid: BX.Scale.AdminFrame.currentAsyncActionBID
  191. };
  192. var callbacks = {
  193. onsuccess: function(result){
  194. if(this.timeToCompleteInterval !== null)
  195. {
  196. BX.Scale.AdminFrame.failureAnswersCount = 0;
  197. clearInterval(this.timeToCompleteInterval);
  198. this.timeToComplete = null;
  199. BX.Scale.ActionProcessDialog.addActionMessage("", true);
  200. }
  201. if(result)
  202. {
  203. BX.Scale.AdminFrame.failureAnswersCount = 0;
  204. if(result.ERROR.length <= 0 && result.ACTION_STATE && result.ACTION_STATE.status)
  205. {
  206. if(result.ACTION_STATE.status == "finished")
  207. {
  208. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  209. BX.Scale.ActionProcessDialog.setActionResult(true, BX.message("SCALE_PANEL_JS_ACT_EXEC_SUCCESS"));
  210. BX.Scale.AdminFrame.currentAsyncActionBID = "";
  211. }
  212. else if(result.ACTION_STATE.status == "error")
  213. {
  214. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  215. var mess = "";
  216. if(result.ACTION_STATE.error_messages)
  217. {
  218. for(var i in result.ACTION_STATE.error_messages)
  219. {
  220. mess += result.ACTION_STATE.error_messages[i]+"<br>";
  221. }
  222. }
  223. BX.Scale.ActionProcessDialog.setActionResult(false, mess);
  224. BX.Scale.AdminFrame.currentAsyncActionBID = "";
  225. }
  226. else if(result.ACTION_STATE.status == "interrupt")
  227. {
  228. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  229. BX.Scale.ActionProcessDialog.setActionResult(false, BX.message("SCALE_PANEL_JS_ACT_EXEC_INTERRUPTED"));
  230. BX.Scale.AdminFrame.currentAsyncActionBID = "";
  231. }
  232. else
  233. {
  234. if(result.ACTION_STATE.status == "running" && result.ACTION_STATE.last_action && result.ACTION_STATE.last_action.length > 0)
  235. {
  236. BX.Scale.ActionProcessDialog.addActionMessage("last operation:<br>"+result.ACTION_STATE.last_action, true);
  237. }
  238. }
  239. }
  240. else if(!result.ACTION_STATE || result.ACTION_STATE.status)
  241. {
  242. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  243. BX.Scale.ActionProcessDialog.setActionResult(false);
  244. }
  245. else
  246. {
  247. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  248. BX.Scale.ActionProcessDialog.setActionResult(false, BX.message("SCALE_PANEL_JS_ERROR")+" "+result.ERROR);
  249. }
  250. }
  251. else
  252. {
  253. if(BX.Scale.AdminFrame.failureAnswersCountAllow >= BX.Scale.AdminFrame.failureAnswersCount)
  254. {
  255. BX.Scale.AdminFrame.failureAnswersCount++;
  256. return;
  257. }
  258. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  259. BX.Scale.ActionProcessDialog.setActionResult(false, BX.message("SCALE_PANEL_JS_ACT_EXEC_ERROR"));
  260. }
  261. },
  262. onfailure: function(type, e){
  263. var now = new Date();
  264. if(type == "processing" &&
  265. e.data &&
  266. e.data.search('SCALE_SERVER_NOT_AVAILABLE') != -1 &&
  267. (
  268. this.timeToComplete === null ||
  269. now.getTime() > this.timeToComplete
  270. )
  271. )
  272. {
  273. var _this = this;
  274. var timeToComplete = this.extractTimeToComplete(e.data);
  275. if(this.timeToComplete < timeToComplete)
  276. this.timeToComplete = timeToComplete;
  277. this.timeToCompleteInterval = window.setInterval(function(){
  278. var timePeriod = _this.makeTimeToCompleteString(_this.timeToComplete);
  279. if(timePeriod)
  280. BX.Scale.ActionProcessDialog.addActionMessage(timePeriod, true);
  281. },1000);
  282. return;
  283. }
  284. if(BX.Scale.AdminFrame.failureAnswersCountAllow >= BX.Scale.AdminFrame.failureAnswersCount)
  285. {
  286. BX.Scale.AdminFrame.failureAnswersCount++;
  287. return;
  288. }
  289. clearInterval(BX.Scale.AdminFrame.timeIntervalId );
  290. BX.Scale.ActionProcessDialog.setActionResult(false, BX.message("SCALE_PANEL_JS_ACT_RES_ERROR"));
  291. }
  292. };
  293. BX.Scale.Communicator.sendRequest(sendPrams, callbacks, this, false);
  294. return true;
  295. };
  296. /**
  297. * Form request params to execute action
  298. * @param {object} params - action params
  299. */
  300. BX.Scale.Action.prototype.sendRequest = function(params)
  301. {
  302. var sendPrams = {
  303. actionId: this.id,
  304. serverHostname: params.serverHostname,
  305. operation: this.currentOperation
  306. },
  307. _this = this;
  308. if(params.userParams !== undefined)
  309. sendPrams.userParams = params.userParams;
  310. if(this.freeParams)
  311. sendPrams.freeParams = this.freeParams;
  312. if(this.type == "MODIFYED")
  313. sendPrams.actionParams = this.allParams;
  314. var callbacks = {
  315. onsuccess: function(result){
  316. if(result)
  317. {
  318. if(result.NEED_MORE_USER_INFO)
  319. {
  320. this.startModifyed(result.NEED_MORE_USER_INFO);
  321. return;
  322. }
  323. if(result.ERROR.length <= 0)
  324. {
  325. if(this.async)
  326. {
  327. _this.showAsyncDialog(result);
  328. }
  329. else
  330. {
  331. if(result.ACTION_RESULT
  332. && result.ACTION_RESULT.COPY_KEY_TO_SERVER
  333. && result.ACTION_RESULT.COPY_KEY_TO_SERVER.RESULT == "ERROR"
  334. && result.ACTION_RESULT.COPY_KEY_TO_SERVER.OUTPUT.DATA.message.search(/^User must change password/) != -1
  335. )
  336. {
  337. BX.Scale.AdminFrame.alert(
  338. BX.message("SCALE_PANEL_JS_PASS_MUST_BE_CHANGED"),
  339. BX.message("SCALE_PANEL_JS_WARNING"),
  340. function(){
  341. BX.Scale.actionsCollection.getObject("CHANGE_PASSWD_FIRST").start(sendPrams.serverHostname, sendPrams.userParams);
  342. BX.Scale.AdminFrame.nextActionId = "NEW_SERVER_CHAIN";
  343. }
  344. );
  345. }
  346. else
  347. {
  348. if(BX.Scale.AdminFrame.nextActionId != this.id
  349. && BX.Scale.AdminFrame.nextActionId !== null
  350. && BX.Scale.actionsCollection.getObject(BX.Scale.AdminFrame.nextActionId)
  351. )
  352. {
  353. BX.Scale.actionsCollection.getObject(BX.Scale.AdminFrame.nextActionId).start(sendPrams.serverHostname, sendPrams.userParams);
  354. BX.Scale.AdminFrame.nextActionId = null;
  355. }
  356. _this.showResultDialog(result);
  357. }
  358. }
  359. }
  360. else
  361. {
  362. BX.Scale.AdminFrame.alert(
  363. result.ERROR,
  364. BX.message("SCALE_PANEL_JS_ERROR")
  365. );
  366. }
  367. }
  368. else
  369. {
  370. BX.Scale.AdminFrame.alert(
  371. BX.message("SCALE_PANEL_JS_ACT_EXEC_ERROR"),
  372. BX.message("SCALE_PANEL_JS_ERROR")
  373. );
  374. }
  375. },
  376. onfailure: function(){
  377. BX.Scale.AdminFrame.alert(
  378. BX.message("SCALE_PANEL_JS_ACT_RES_ERROR"),
  379. BX.message("SCALE_PANEL_JS_ERROR")
  380. );
  381. }
  382. };
  383. BX.Scale.Communicator.sendRequest(sendPrams, callbacks, this, true);
  384. };
  385. /**
  386. * Parses time to end server unavailability from received special page
  387. * @param html
  388. * @returns {int} timestamp
  389. */
  390. BX.Scale.Action.prototype.extractTimeToComplete = function(html)
  391. {
  392. if(!html || typeof html != 'string')
  393. return false;
  394. var now = new Date(),
  395. availableDateTime = html.match(/availableDateTime\s=\s(\d+)/im)[1],
  396. serverNow = html.match(/serverNow\s=\s(\d+)/im)[1],
  397. timePeriod = availableDateTime - serverNow,
  398. timeToComplete = now.getTime() + timePeriod;
  399. if(now > timeToComplete)
  400. timeToComplete.setTime(now.getTime()+timePeriod);
  401. return timeToComplete;
  402. };
  403. /**
  404. * @param timeToComplete - timestamp
  405. * @returns {String}
  406. */
  407. BX.Scale.Action.prototype.makeTimeToCompleteString = function(timeToComplete)
  408. {
  409. var now = new Date();
  410. if(now > timeToComplete)
  411. return false;
  412. var deltaTime = timeToComplete-now,
  413. hours = Math.floor(deltaTime/3600000),
  414. minutes = Math.floor(deltaTime/60000)-hours*60,
  415. seconds = Math.floor(deltaTime/1000)-hours*3600-minutes*60;
  416. hours = (hours < 10) ? "0"+hours : hours;
  417. minutes = (minutes < 10) ? "0"+minutes : minutes;
  418. seconds = (seconds < 10) ? "0"+seconds : seconds;
  419. return BX.message("SCALE_PANEL_JS_ACT_SERVER_WILL_AVAILABLE")+"<br>"+
  420. hours+" "+BX.message("SCALE_PANEL_JS_ACT_HOUR")+". "+
  421. minutes+" "+BX.message("SCALE_PANEL_JS_ACT_MIN")+". "+
  422. seconds+" "+BX.message("SCALE_PANEL_JS_ACT_SEC")+".";
  423. };
  424. /**
  425. * If we need more info from user - let's ask him by starting new action
  426. * @param newActionParams
  427. */
  428. BX.Scale.Action.prototype.startModifyed = function(newActionParams)
  429. {
  430. delete(newActionParams.ACTION_PARAMS.MODIFYERS);
  431. newActionParams.ACTION_PARAMS.TYPE = "MODIFYED";
  432. var action = BX.Scale.actionsCollection.addObject(newActionParams.ACTION_ID+"_MODIF", newActionParams.ACTION_PARAMS);
  433. var hostname = newActionParams.HOSTNAME || false;
  434. action.start(hostname, {}, true);
  435. };
  436. })(window);