ESPWorkunit.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. /*##############################################################################
  2. # HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################## */
  16. define([
  17. "dojo/_base/declare",
  18. "dojo/_base/lang",
  19. "dojo/_base/xhr",
  20. "hpcc/ESPResult",
  21. "hpcc/ESPBase"
  22. ], function (declare, lang, xhr, ESPResult, ESPBase) {
  23. return declare(ESPBase, {
  24. Wuid: "",
  25. stateID: 0,
  26. state: "",
  27. text: "",
  28. resultCount: 0,
  29. results: [],
  30. graphs: [],
  31. exceptions: [],
  32. timers: [],
  33. WUInfoResponse: {},
  34. onCreate: function () {
  35. },
  36. onUpdate: function () {
  37. },
  38. onSubmit: function () {
  39. },
  40. constructor: function (args) {
  41. declare.safeMixin(this, args);
  42. if (this.Wuid) {
  43. this.WUInfoResponse = {
  44. Wuid: this.Wuid
  45. }
  46. }
  47. },
  48. isComplete: function () {
  49. switch (this.stateID) {
  50. case 1: //WUStateCompiled
  51. if (lang.exists("WUInfoResponse.ActionEx", this) && this.WUInfoResponse.ActionEx == "compile") {
  52. return true;
  53. }
  54. break;
  55. case 3: //WUStateCompleted:
  56. case 4: //WUStateFailed:
  57. case 5: //WUStateArchived:
  58. case 7: //WUStateAborted:
  59. return true;
  60. }
  61. return false;
  62. },
  63. monitor: function (callback, monitorDuration) {
  64. if (!monitorDuration)
  65. monitorDuration = 0;
  66. var request = {
  67. Wuid: this.Wuid,
  68. TruncateEclTo64k: true,
  69. IncludeExceptions: false,
  70. IncludeGraphs: false,
  71. IncludeSourceFiles: false,
  72. IncludeResults: false,
  73. IncludeResultsViewNames: false,
  74. IncludeVariables: false,
  75. IncludeTimers: false,
  76. IncludeDebugValues: false,
  77. IncludeApplicationValues: false,
  78. IncludeWorkflows: false,
  79. IncludeXmlSchemas: false,
  80. SuppressResultSchemas: true
  81. };
  82. var context = this;
  83. xhr.post({
  84. url: this.getBaseURL() + "/WUInfo.json",
  85. handleAs: "json",
  86. content: request,
  87. load: function (response) {
  88. if (lang.exists("WUInfoResponse.Workunit", response)) {
  89. context.WUInfoResponse = response.WUInfoResponse.Workunit;
  90. context.stateID = context.WUInfoResponse.StateID;
  91. context.state = context.WUInfoResponse.State;
  92. context.protected = context.WUInfoResponse.Protected;
  93. if (callback) {
  94. callback(context.WUInfoResponse);
  95. }
  96. if (!context.isComplete()) {
  97. var timeout = 30; // Seconds
  98. if (monitorDuration < 5) {
  99. timeout = 1;
  100. } else if (monitorDuration < 10) {
  101. timeout = 2;
  102. } else if (monitorDuration < 30) {
  103. timeout = 5;
  104. } else if (monitorDuration < 60) {
  105. timeout = 10;
  106. } else if (monitorDuration < 120) {
  107. timeout = 20;
  108. }
  109. setTimeout(function () {
  110. context.monitor(callback, monitorDuration + timeout);
  111. }, timeout * 1000);
  112. }
  113. }
  114. },
  115. error: function () {
  116. done = true;
  117. }
  118. });
  119. },
  120. create: function (ecl) {
  121. var request = {};
  122. request['rawxml_'] = "1";
  123. var context = this;
  124. xhr.post({
  125. url: this.getBaseURL() + "/WUCreate.json",
  126. handleAs: "json",
  127. content: request,
  128. load: function (response) {
  129. context.Wuid = response.WUCreateResponse.Workunit.Wuid;
  130. context.onCreate();
  131. },
  132. error: function () {
  133. }
  134. });
  135. },
  136. update: function (request, appData, callback) {
  137. lang.mixin(request, {
  138. Wuid: this.Wuid,
  139. rawxml_: true
  140. });
  141. if (this.WUInfoResponse) {
  142. lang.mixin(request, {
  143. StateOrig: this.WUInfoResponse.State,
  144. JobnameOrig: this.WUInfoResponse.Jobname,
  145. DescriptionOrig: this.WUInfoResponse.Description,
  146. ProtectedOrig: this.WUInfoResponse.Protected,
  147. ScopeOrig: this.WUInfoResponse.Scope,
  148. ClusterOrig: this.WUInfoResponse.Cluster
  149. });
  150. }
  151. if (appData) {
  152. request['ApplicationValues.ApplicationValue.itemcount'] = appData.length;
  153. var i = 0;
  154. for (key in appData) {
  155. request['ApplicationValues.ApplicationValue.' + i + '.Application'] = "ESPWorkunit.js";
  156. request['ApplicationValues.ApplicationValue.' + i + '.Name'] = key;
  157. request['ApplicationValues.ApplicationValue.' + i + '.Value'] = appData[key];
  158. ++i;
  159. }
  160. }
  161. var context = this;
  162. xhr.post({
  163. url: this.getBaseURL() + "/WUUpdate.json",
  164. handleAs: "json",
  165. content: request,
  166. load: function (response) {
  167. context.WUInfoResponse = lang.mixin(context.WUInfoResponse, response.WUUpdateResponse.Workunit);
  168. context.onUpdate();
  169. if (callback && callback.load) {
  170. callback.load(response);
  171. }
  172. },
  173. error: function (error) {
  174. if (callback && callback.error) {
  175. callback.error(e);
  176. }
  177. }
  178. });
  179. },
  180. submit: function (target) {
  181. var request = {
  182. Wuid: this.Wuid,
  183. Cluster: target
  184. };
  185. request['rawxml_'] = "1";
  186. var context = this;
  187. xhr.post({
  188. url: this.getBaseURL() + "/WUSubmit.json",
  189. handleAs: "json",
  190. content: request,
  191. load: function (response) {
  192. context.onSubmit();
  193. },
  194. error: function (error) {
  195. }
  196. });
  197. },
  198. _resubmit: function (clone, resetWorkflow, callback) {
  199. var request = {
  200. Wuids: this.Wuid,
  201. CloneWorkunit: clone,
  202. ResetWorkflow: resetWorkflow,
  203. rawxml_: true
  204. };
  205. var context = this;
  206. xhr.post({
  207. url: this.getBaseURL() + "/WUResubmit.json",
  208. handleAs: "json",
  209. content: request,
  210. load: function (response) {
  211. if (callback && callback.load) {
  212. callback.load(response);
  213. }
  214. },
  215. error: function (e) {
  216. if (callback && callback.error) {
  217. callback.error(e);
  218. }
  219. }
  220. });
  221. },
  222. clone: function (callback) {
  223. this._resubmit(true, false, callback);
  224. },
  225. resubmit: function (callback) {
  226. this._resubmit(false, false, callback);
  227. },
  228. restart: function (callback) {
  229. this._resubmit(false, true, callback);
  230. },
  231. _action: function (action, callback) {
  232. var request = {
  233. Wuids: this.Wuid,
  234. ActionType: action,
  235. rawxml_: true
  236. };
  237. var context = this;
  238. xhr.post({
  239. url: this.getBaseURL() + "/WUAction.json",
  240. handleAs: "json",
  241. content: request,
  242. load: function (response) {
  243. if (callback && callback.load) {
  244. callback.load(response);
  245. }
  246. },
  247. error: function (e) {
  248. if (callback && callback.error) {
  249. callback.error(e);
  250. }
  251. }
  252. });
  253. },
  254. abort: function (callback) {
  255. this._action("Abort", callback);
  256. },
  257. doDelete: function (callback) {
  258. this._action("Delete", callback);
  259. },
  260. publish: function (jobName) {
  261. var request = {
  262. Wuid: this.Wuid,
  263. JobName: jobName,
  264. Activate: 1,
  265. UpdateWorkUnitName: 1,
  266. Wait: 5000,
  267. rawxml_: true
  268. };
  269. var context = this;
  270. xhr.post({
  271. url: this.getBaseURL() + "/WUPublishWorkunit.json",
  272. handleAs: "json",
  273. content: request,
  274. load: function (response) {
  275. },
  276. error: function (e) {
  277. }
  278. });
  279. },
  280. getInfo: function (args) {
  281. var request = {
  282. Wuid: this.Wuid,
  283. TruncateEclTo64k: args.onGetText ? false : true,
  284. IncludeExceptions: args.onGetWUExceptions ? true : false,
  285. IncludeGraphs: args.onGetGraphs ? true : false,
  286. IncludeSourceFiles: args.onGetSourceFiles ? true : false,
  287. IncludeResults: args.onGetResults ? true : false,
  288. IncludeResultsViewNames: false,
  289. IncludeVariables: args.onGetVariables ? true : false,
  290. IncludeTimers: args.onGetTimers ? true : false,
  291. IncludeDebugValues: false,
  292. IncludeApplicationValues: args.onGetApplicationValues ? true : false,
  293. IncludeWorkflows: false,
  294. IncludeXmlSchemas: args.onGetResults ? true : false,
  295. SuppressResultSchemas: args.onGetResults ? false : true,
  296. rawxml_: true
  297. };
  298. var context = this;
  299. xhr.post({
  300. url: this.getBaseURL() + "/WUInfo.json",
  301. handleAs: "json",
  302. content: request,
  303. load: function (response) {
  304. if (lang.exists("WUInfoResponse.Workunit", response)) {
  305. context.WUInfoResponse = response.WUInfoResponse.Workunit;
  306. if (args.onGetText && lang.exists("Query.Text", context.WUInfoResponse)) {
  307. context.text = context.WUInfoResponse.Query.Text;
  308. args.onGetText(context.text);
  309. }
  310. if (args.onGetWUExceptions && lang.exists("Exceptions.ECLException", context.WUInfoResponse)) {
  311. context.exceptions = [];
  312. for (var i = 0; i < context.WUInfoResponse.Exceptions.ECLException.length; ++i) {
  313. context.exceptions.push(context.WUInfoResponse.Exceptions.ECLException[i]);
  314. }
  315. args.onGetWUExceptions(context.exceptions);
  316. }
  317. if (args.onGetApplicationValues && lang.exists("ApplicationValues.ApplicationValue", context.WUInfoResponse)) {
  318. context.applicationValues = context.WUInfoResponse.ApplicationValues.ApplicationValue;
  319. args.onGetApplicationValues(context.applicationValues)
  320. }
  321. if (args.onGetVariables && lang.exists("Variables.ECLResult", context.WUInfoResponse)) {
  322. context.variables = [];
  323. var variables = context.WUInfoResponse.Variables.ECLResult;
  324. for (var i = 0; i < variables.length; ++i) {
  325. context.variables.push(lang.mixin({
  326. ColumnType: variables[i].ECLSchemas && variables[i].ECLSchemas.ECLSchemaItem.length ? variables[i].ECLSchemas.ECLSchemaItem[0].ColumnType : "unknown"
  327. }, variables[i]));
  328. }
  329. args.onGetVariables(context.variables);
  330. }
  331. if (args.onGetResults && lang.exists("Results.ECLResult", context.WUInfoResponse)) {
  332. context.results = [];
  333. var results = context.WUInfoResponse.Results.ECLResult;
  334. for (var i = 0; i < results.length; ++i) {
  335. context.results.push(new ESPResult(lang.mixin({ wu: context, Wuid: context.Wuid }, results[i])));
  336. }
  337. args.onGetResults(context.results);
  338. }
  339. if (args.onGetSourceFiles && lang.exists("SourceFiles.ECLSourceFile", context.WUInfoResponse)) {
  340. context.sourceFiles = [];
  341. var sourceFiles = context.WUInfoResponse.SourceFiles.ECLSourceFile;
  342. for (var i = 0; i < sourceFiles.length; ++i) {
  343. context.sourceFiles.push(new ESPResult(lang.mixin({ wu: context, Wuid: context.Wuid }, sourceFiles[i])));
  344. }
  345. args.onGetSourceFiles(context.sourceFiles);
  346. }
  347. if (args.onGetTimers && lang.exists("Timers.ECLTimer", context.WUInfoResponse)) {
  348. context.timers = [];
  349. for (var i = 0; i < context.WUInfoResponse.Timers.ECLTimer.length; ++i) {
  350. var timeParts = context.WUInfoResponse.Timers.ECLTimer[i].Value.split(":");
  351. var secs = 0;
  352. for (var j = 0; j < timeParts.length; ++j) {
  353. secs = secs * 60 + timeParts[j] * 1;
  354. }
  355. context.timers.push(lang.mixin(context.WUInfoResponse.Timers.ECLTimer[i], {
  356. Seconds: Math.round(secs * 1000) / 1000,
  357. HasSubGraphId: context.WUInfoResponse.Timers.ECLTimer[i].SubGraphId && context.WUInfoResponse.Timers.ECLTimer[i].SubGraphId != "" ? true : false
  358. }));
  359. }
  360. args.onGetTimers(context.timers);
  361. }
  362. if (args.onGetGraphs && lang.exists("Graphs.ECLGraph", context.WUInfoResponse)) {
  363. context.graphs = context.WUInfoResponse.Graphs.ECLGraph;
  364. if (context.timers || context.applicationValues) {
  365. for (var i = 0; i < context.graphs.length; ++i) {
  366. if (context.timers) {
  367. context.graphs[i].Time = 0;
  368. for (var j = 0; j < context.timers.length; ++j) {
  369. if (context.timers[j].GraphName == context.graphs[i].Name) {
  370. context.graphs[i].Time += context.timers[j].Seconds;
  371. }
  372. context.graphs[i].Time = Math.round(context.graphs[i].Time * 1000) / 1000;
  373. }
  374. }
  375. if (context.applicationValues) {
  376. var idx = context.getApplicationValueIndex("ESPWorkunit.js", context.graphs[i].Name + "_SVG");
  377. if (idx >= 0) {
  378. context.graphs[i].svg = context.applicationValues[idx].Value;
  379. }
  380. }
  381. }
  382. }
  383. args.onGetGraphs(context.graphs)
  384. }
  385. if (args.onGetAll) {
  386. args.onGetAll(context.WUInfoResponse);
  387. }
  388. }
  389. },
  390. error: function (e) {
  391. }
  392. });
  393. },
  394. getGraphIndex: function (name) {
  395. for (var i = 0; i < this.graphs.length; ++i) {
  396. if (this.graphs[i].Name == name) {
  397. return i;
  398. }
  399. }
  400. return -1;
  401. },
  402. getApplicationValueIndex: function (application, name) {
  403. for (var i = 0; i < this.applicationValues.length; ++i) {
  404. if (this.applicationValues[i].Application == application && this.applicationValues[i].Name == name) {
  405. return i;
  406. }
  407. }
  408. return -1;
  409. },
  410. getState: function () {
  411. return this.state;
  412. },
  413. getStateIconClass: function () {
  414. switch (this.stateID) {
  415. case 1:
  416. case 3:
  417. return "iconCompleted";
  418. case 2:
  419. case 11:
  420. case 15:
  421. return "iconRunning";
  422. case 4:
  423. case 7:
  424. return "iconFailed";
  425. case 5:
  426. case 8:
  427. case 10:
  428. case 12:
  429. case 13:
  430. case 14:
  431. case 16:
  432. return "iconArchived";
  433. case 6:
  434. return "iconAborting";
  435. case 9:
  436. return "iconSubmitted";
  437. case 999:
  438. return "iconDeleted";
  439. }
  440. return "iconWorkunit";
  441. },
  442. getStateImage: function () {
  443. switch (this.stateID) {
  444. case 1:
  445. return "img/workunit_completed.png";
  446. case 2:
  447. return "img/workunit_running.png";
  448. case 3:
  449. return "img/workunit_completed.png";
  450. case 4:
  451. return "img/workunit_failed.png";
  452. case 5:
  453. return "img/workunit_warning.png";
  454. case 6:
  455. return "img/workunit_aborting.png";
  456. case 7:
  457. return "img/workunit_failed.png";
  458. case 8:
  459. return "img/workunit_warning.png";
  460. case 9:
  461. return "img/workunit_submitted.png";
  462. case 10:
  463. return "img/workunit_warning.png";
  464. case 11:
  465. return "img/workunit_running.png";
  466. case 12:
  467. return "img/workunit_warning.png";
  468. case 13:
  469. return "img/workunit_warning.png";
  470. case 14:
  471. return "img/workunit_warning.png";
  472. case 15:
  473. return "img/workunit_running.png";
  474. case 16:
  475. return "img/workunit_warning.png";
  476. case 999:
  477. return "img/workunit_deleted.png";
  478. }
  479. return "img/workunit.png";
  480. },
  481. getProtectedImage: function () {
  482. if (this.protected) {
  483. return "img/locked.png"
  484. }
  485. return "img/unlocked.png"
  486. },
  487. fetchText: function (onFetchText) {
  488. if (this.text) {
  489. onFetchText(this.text);
  490. return;
  491. }
  492. this.getInfo({
  493. onGetText: onFetchText
  494. });
  495. },
  496. fetchXML: function (onFetchXML) {
  497. if (this.xml) {
  498. onFetchXML(this.xml);
  499. return;
  500. }
  501. var request = {
  502. Wuid: this.Wuid,
  503. Type: "XML"
  504. };
  505. var context = this;
  506. xhr.post({
  507. url: this.getBaseURL() + "/WUFile.json",
  508. handleAs: "text",
  509. content: request,
  510. load: function (response) {
  511. context.xml = response;
  512. onFetchXML(response);
  513. },
  514. error: function (e) {
  515. }
  516. });
  517. },
  518. fetchResults: function (onFetchResults) {
  519. if (this.results && this.results.length) {
  520. onFetchResults(this.results);
  521. return;
  522. }
  523. this.getInfo({
  524. onGetResults: onFetchResults
  525. });
  526. },
  527. fetchTimers: function (onFetchTimers) {
  528. if (this.timers && this.timers.length) {
  529. onFetchTimers(this.timers);
  530. return;
  531. }
  532. this.getInfo({
  533. onGetTimers: onFetchTimers
  534. });
  535. },
  536. fetchGraphs: function (onFetchGraphs) {
  537. if (this.graphs && this.graphs.length) {
  538. onFetchGraphs(this.graphs);
  539. return;
  540. }
  541. this.getInfo({
  542. onGetGraphs: onFetchGraphs
  543. });
  544. },
  545. fetchGraphXgmmlByName: function (name, onFetchGraphXgmml) {
  546. var idx = this.getGraphIndex(name);
  547. if (idx >= 0) {
  548. this.fetchGraphXgmml(idx, onFetchGraphXgmml);
  549. }
  550. },
  551. fetchGraphXgmml: function (idx, onFetchGraphXgmml) {
  552. var request = {};
  553. request['Wuid'] = this.Wuid;
  554. request['GraphName'] = this.graphs[idx].Name;
  555. request['rawxml_'] = "1";
  556. var context = this;
  557. xhr.post({
  558. url: this.getBaseURL() + "/WUGetGraph.json",
  559. handleAs: "json",
  560. content: request,
  561. load: function (response) {
  562. context.graphs[idx].xgmml = response.WUGetGraphResponse.Graphs.ECLGraphEx[0].Graph;
  563. onFetchGraphXgmml(context.graphs[idx].xgmml, context.graphs[idx].svg);
  564. },
  565. error: function () {
  566. }
  567. });
  568. },
  569. setGraphSvg: function (graphName, svg) {
  570. var idx = this.getGraphIndex(graphName);
  571. if (idx >= 0) {
  572. this.graphs[idx].svg = svg;
  573. var appData = [];
  574. appData[graphName + "_SVG"] = svg;
  575. this.update({}, appData);
  576. }
  577. }
  578. });
  579. });