apps_controller.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. var misc = require('utils/misc');
  20. var date = require('utils/date');
  21. App.MainAppsController = Em.ArrayController.extend({
  22. name:'mainAppsController',
  23. content: [],
  24. loaded : false,
  25. loading : false,
  26. /**
  27. * List of users.
  28. * Will be used for filtering in user column.
  29. * Go to App.MainAppsView.userFilterView for more information
  30. */
  31. users: function () {
  32. return this.get('content').mapProperty("userName").uniq().map(function(userName){
  33. return {
  34. name: userName,
  35. checked: false
  36. };
  37. });
  38. }.property('content.length'),
  39. loadRuns:function () {
  40. this.set('loading', true);
  41. var self = this;
  42. //var runsUrl = App.testMode ? "/data/apps/runs.json" : App.apiPrefix + "/jobhistory/workflow?orderBy=startTime&sortDir=DESC&limit=" + App.maxRunsForAppBrowser;
  43. var runsUrl = App.testMode ? "/data/apps/runs.json" : App.apiPrefix + this.get("runUrl");
  44. App.HttpClient.get(runsUrl, App.runsMapper, {
  45. complete:function (jqXHR, textStatus) {
  46. self.set('loading', false);
  47. self.set('loaded', true);
  48. }
  49. });
  50. },
  51. //Pagination Object
  52. paginationObject:{
  53. iTotalDisplayRecords :null,
  54. iTotalRecords:null,
  55. startIndex:null,
  56. endIndex:null
  57. },
  58. /*
  59. Set number of filtered jobs when switching to all jobs
  60. */
  61. iTotalDisplayRecordsObserver:function(){
  62. if(this.get("filterObject.allFilterActivated")){
  63. //this.set("paginationObject.filteredDisplayRecords","-10");
  64. this.set("filterObject.allFilterActivated", false);
  65. }else{
  66. this.set("filterObject.filteredDisplayRecords",this.get("paginationObject.iTotalDisplayRecords"));
  67. }
  68. }.observes("paginationObject.iTotalDisplayRecords"),
  69. //Filter object
  70. filterObject : Ember.Object.create({
  71. sSearch_0:"",
  72. sSearch_1:"",
  73. sSearch_2:"",
  74. sSearch_3:"",
  75. minJobs:"",
  76. maxJobs:"",
  77. minInputBytes:"",
  78. maxInputBytes:"",
  79. minOutputBytes:"",
  80. maxOutputBytes:"",
  81. minDuration:"",
  82. maxDuration:"",
  83. minStartTime:"",
  84. maxStartTime:"",
  85. sSearch:"",
  86. iDisplayLength:"",
  87. iDisplayStart:"",
  88. iSortCol_0:"",
  89. sSortDir_0:"",
  90. allFilterActivated:false,
  91. filteredDisplayRecords:null,
  92. viewType:"all",
  93. viewTypeClickEvent:false,
  94. /**
  95. * Direct binding to job filter field
  96. */
  97. runType:"",
  98. onRunTypeChange:function(){
  99. if(this.runType == "MapReduce"){
  100. this.set("sSearch_2","mr");
  101. }else if(this.runType == "Hive"){
  102. this.set("sSearch_2","hive");
  103. }else if(this.runType == "Pig"){
  104. this.set("sSearch_2","pig");
  105. }else{
  106. this.set("sSearch_2","");
  107. }
  108. }.observes("runType"),
  109. /**
  110. * Direct binding to job filter field
  111. */
  112. jobs:"",
  113. onJobsChange:function(){
  114. var minMaxTmp = this.parseNumber(this.jobs);
  115. this.set("minJobs", minMaxTmp.min);
  116. this.set("maxJobs", minMaxTmp.max);
  117. }.observes("jobs"),
  118. /**
  119. * Direct binding to Input filter field
  120. */
  121. input:"",
  122. onInputChange:function(){
  123. var minMaxTmp = this.parseBandWidth(this.input);
  124. this.set("minInputBytes", minMaxTmp.min);
  125. this.set("maxInputBytes", minMaxTmp.max);
  126. }.observes("input"),
  127. /**
  128. * Direct binding to Output filter field
  129. */
  130. output:"",
  131. onOutputChange:function(){
  132. var minMaxTmp = this.parseBandWidth(this.output);
  133. this.set("minOutputBytes", minMaxTmp.min);
  134. this.set("maxOutputBytes", minMaxTmp.max);
  135. }.observes("output"),
  136. /**
  137. * Direct binding to Duration filter field
  138. */
  139. duration:"",
  140. onDurationChange:function(){
  141. var minMaxTmp = this.parseDuration(this.duration);
  142. this.set("minDuration", minMaxTmp.min);
  143. this.set("maxDuration", minMaxTmp.max);
  144. }.observes("duration"),
  145. /**
  146. * Direct binding to Run Date filter field
  147. */
  148. runDate:"",
  149. onRunDateChange:function(){
  150. var minMaxTmp = this.parseDate(this.runDate);
  151. this.set("minStartTime", minMaxTmp.min);
  152. this.set("maxStartTime", minMaxTmp.max);
  153. }.observes("runDate"),
  154. parseDuration:function(value){
  155. var tmp={
  156. min:"",
  157. max:""
  158. };
  159. var compareChar = isNaN(value.charAt(0)) ? value.charAt(0) : false;
  160. var compareScale = value.match(/s|m|h/);
  161. compareScale = compareScale ? compareScale[0] : "";
  162. var compareValue = compareChar ? parseFloat(value.substr(1, value.length)) : parseFloat(value.substr(0, value.length));
  163. if(isNaN(compareValue)){
  164. return tmp;
  165. }
  166. switch (compareScale) {
  167. case 'h':
  168. tmp.min = Math.ceil((parseFloat(compareValue)-0.0001)*1000*60*60);
  169. tmp.max = Math.floor((parseFloat(compareValue)+0.0001)*1000*60*60);
  170. break;
  171. case 'm':
  172. tmp.min = Math.ceil((parseFloat(compareValue)-0.001)*1000*60);
  173. tmp.max = Math.floor((parseFloat(compareValue)+0.001)*1000*60);
  174. break;
  175. case 's':
  176. tmp.min = Math.ceil((parseFloat(compareValue)-0.01)*1000);
  177. tmp.max = Math.floor((parseFloat(compareValue)+0.01)*1000);
  178. break;
  179. default:
  180. tmp.min = Math.max(1024,Math.ceil((compareValue-0.05)*1024));
  181. tmp.max = Math.min(1048575,Math.floor((compareValue+0.05)*1024));
  182. }
  183. switch (compareChar) {
  184. case '<':
  185. tmp.min="";
  186. break;
  187. case '>':
  188. tmp.max="";
  189. break;
  190. }
  191. return tmp;
  192. },
  193. parseDate:function(value){
  194. var tmp={
  195. min:"",
  196. max:""
  197. };
  198. var nowTime = new Date().getTime();
  199. switch (value){
  200. case 'Any':
  201. break;
  202. case 'Past 1 Day':
  203. tmp.min= nowTime - 86400000;
  204. break;
  205. case 'Past 2 Days':
  206. tmp.min= nowTime - 172800000;
  207. break;
  208. case 'Past 7 Days':
  209. tmp.min= nowTime - 604800000;
  210. break;
  211. case 'Past 14 Days':
  212. tmp.min= nowTime - 1209600000;
  213. break;
  214. case 'Past 30 Days':
  215. tmp.min= nowTime - 2592000000;
  216. break;
  217. case 'Running Now':
  218. tmp.min= nowTime;
  219. break;
  220. }
  221. return tmp;
  222. },
  223. parseBandWidth:function(value){
  224. var tmp={
  225. min:"",
  226. max:""
  227. };
  228. var compareChar = isNaN(value.charAt(0)) ? value.charAt(0) : false;
  229. var compareScale = value.match(/kb|k|mb|m|gb|g/);
  230. compareScale = compareScale ? compareScale[0] : "";
  231. var compareValue = compareChar ? parseFloat(value.substr(1, value.length)) : parseFloat(value.substr(0, value.length));
  232. if(isNaN(compareValue)){
  233. return tmp;
  234. }
  235. switch (compareScale) {
  236. case 'g': case 'gb':
  237. tmp.min = Math.max(1073741824,Math.ceil((compareValue-0.005)*1073741824));
  238. tmp.max = Math.floor((compareValue+0.005)*1073741824);
  239. break;
  240. case 'm': case 'mb':
  241. tmp.min = Math.max(1048576,Math.ceil((compareValue-0.05)*1048576));
  242. tmp.max = Math.min(1073741823,Math.floor((compareValue+0.05)*1048576));
  243. break;
  244. case 'k': case 'kb':
  245. tmp.min = Math.max(1024,Math.ceil((compareValue-0.05)*1024));
  246. tmp.max = Math.min(1048575,Math.floor((compareValue+0.05)*1024));
  247. break;
  248. default:
  249. tmp.min = Math.max(1024,Math.ceil((compareValue-0.05)*1024));
  250. tmp.max = Math.min(1048575,Math.floor((compareValue+0.05)*1024));
  251. }
  252. switch (compareChar) {
  253. case '<':
  254. tmp.min="";
  255. break;
  256. case '>':
  257. tmp.max="";
  258. break;
  259. }
  260. return tmp;
  261. },
  262. parseNumber:function(value){
  263. var tmp={
  264. min:"",
  265. max:""
  266. };
  267. switch (value.charAt(0)) {
  268. case '<':
  269. tmp.max=value.substr(1);
  270. break;
  271. case '>':
  272. tmp.min=value.substr(1);
  273. break;
  274. case '=':
  275. tmp.min=value.substr(1);
  276. tmp.max=value.substr(1);
  277. break;
  278. default:
  279. tmp.min=value;
  280. tmp.max=value;
  281. }
  282. return tmp;
  283. },
  284. /**
  285. * Create link for server request
  286. * @return {String}
  287. */
  288. createAppLink:function(){
  289. var link = "/jobhistory/datatable?";
  290. if(this.sSearch_0){
  291. link += "sSearch_0=" + this.sSearch_0 + "&";
  292. }
  293. if(this.sSearch_1){
  294. link += "sSearch_1=" + this.sSearch_1 + "&";
  295. }
  296. if(this.sSearch_2 && this.sSearch_2 != "Any"){
  297. link += "sSearch_2=" + this.sSearch_2 + "&";
  298. }
  299. if(this.sSearch_3){
  300. link += "sSearch_3=" + this.sSearch_3 + "&";
  301. }
  302. if(this.minJobs){
  303. link += "minJobs=" + this.minJobs + "&";
  304. }
  305. if(this.maxJobs){
  306. link += "maxJobs=" + this.maxJobs + "&";
  307. }
  308. if(this.minInputBytes){
  309. link += "minInputBytes=" + this.minInputBytes + "&";
  310. }
  311. if(this.maxInputBytes){
  312. link += "maxInputBytes=" + this.maxInputBytes + "&";
  313. }
  314. if(this.minOutputBytes){
  315. link += "minOutputBytes=" + this.minOutputBytes + "&";
  316. }
  317. if(this.maxOutputBytes){
  318. link += "maxOutputBytes=" + this.maxOutputBytes + "&";
  319. }
  320. if(this.minDuration){
  321. link += "minDuration=" + this.minDuration + "&";
  322. }
  323. if(this.maxDuration){
  324. link += "maxDuration=" + this.maxDuration + "&";
  325. }
  326. if(this.minStartTime){
  327. link += "minStartTime=" + this.minStartTime + "&";
  328. }
  329. if(this.maxStartTime){
  330. link += "maxStartTime=" + this.maxStartTime + "&";
  331. }
  332. if(this.sSearch){
  333. link += "sSearch=" + this.sSearch + "&";
  334. }
  335. if(this.iDisplayLength){
  336. link += "iDisplayLength=" + this.iDisplayLength + "&";
  337. }
  338. if(this.iDisplayStart){
  339. link += "iDisplayStart=" + this.iDisplayStart + "&";
  340. }
  341. if(this.iSortCol_0){
  342. link += "iSortCol_0=" + this.iSortCol_0 + "&";
  343. }
  344. if(this.sSortDir_0){
  345. link += "sSortDir_0=" + this.sSortDir_0 + "&";
  346. }
  347. link = link.slice(0,link.length-1);
  348. var valueInString=link.match(/&/g);
  349. if(!this.get("viewTypeClickEvent"))
  350. if(valueInString != null){
  351. this.set("viewType","filtered");
  352. }else{
  353. this.set("viewType","all");
  354. }
  355. return link;
  356. }
  357. }),
  358. /**
  359. * reset all filters in table
  360. *
  361. */
  362. clearFilters: function () {
  363. var obj=this.get("filterObject");
  364. obj.set("sSearch_0","");
  365. obj.set("sSearch_1","");
  366. obj.set("sSearch_2","");
  367. obj.set("sSearch_3","");
  368. obj.set("runType","Any");
  369. obj.set("jobs","");
  370. obj.set("input","");
  371. obj.set("output","");
  372. obj.set("duration","");
  373. obj.set("runDate","Any");
  374. },
  375. runUrl : "/jobhistory/datatable",
  376. runTimeout : null,
  377. valueObserver: function(){
  378. var link = this.get('filterObject').createAppLink();
  379. if(this.get("filterObject.viewType") == "filtered"){
  380. this.set("runUrl", link);
  381. }else{
  382. this.set("runUrl", "/jobhistory/datatable?iDisplayLength="+this.get('filterObject.iDisplayLength'));
  383. }
  384. var timeout = this.get('runTimeout');
  385. var self = this;
  386. clearTimeout(timeout);
  387. timeout = setTimeout(function(){
  388. console.log(self.get("runUrl"));
  389. self.loadRuns();
  390. }, 300);
  391. this.set('runTimeout', timeout);
  392. }.observes(
  393. 'filterObject.sSearch_0',
  394. 'filterObject.sSearch_1',
  395. 'filterObject.sSearch_2',
  396. 'filterObject.sSearch_3',
  397. 'filterObject.minJobs',
  398. 'filterObject.maxJobs',
  399. 'filterObject.minInputBytes',
  400. 'filterObject.maxInputBytes',
  401. 'filterObject.minOutputBytes',
  402. 'filterObject.maxOutputBytes',
  403. 'filterObject.minDuration',
  404. 'filterObject.maxDuration',
  405. 'filterObject.minStartTime',
  406. 'filterObject.maxStartTime',
  407. 'filterObject.sSearch',
  408. 'filterObject.iDisplayLength',
  409. 'filterObject.iDisplayStart',
  410. 'filterObject.iSortCol_0',
  411. 'filterObject.sSortDir_0',
  412. 'filterObject.viewType'
  413. ),
  414. serverData: "",
  415. summary: null,
  416. /**
  417. * Observer for summary data from server
  418. */
  419. summaryInfo: function(){
  420. var tmp;
  421. var summary = this.get('serverData');
  422. if(!summary){
  423. tmp = {
  424. 'jobs': {
  425. 'avg': '-',
  426. 'min': '-',
  427. 'max': '-'
  428. },
  429. 'input': {
  430. 'avg': '-',
  431. 'min': '-',
  432. 'max': '-'
  433. },
  434. 'output': {
  435. 'avg': '-',
  436. 'min': '-',
  437. 'max': '-'
  438. },
  439. 'duration': {
  440. 'avg': '-',
  441. 'min': '-',
  442. 'max': '-'
  443. },
  444. 'times': {
  445. 'oldest': '-',
  446. 'youngest': '-'
  447. }
  448. };
  449. }else{
  450. tmp = {
  451. 'jobs': {
  452. 'avg': summary.jobs.avg.toFixed(2),
  453. 'min': summary.jobs.min,
  454. 'max': summary.jobs.max
  455. },
  456. 'input': {
  457. 'avg': misc.formatBandwidth(summary.input.avg),
  458. 'min': misc.formatBandwidth(summary.input.min),
  459. 'max': misc.formatBandwidth(summary.input.max)
  460. },
  461. 'output': {
  462. 'avg': misc.formatBandwidth(summary.output.avg),
  463. 'min': misc.formatBandwidth(summary.output.min),
  464. 'max': misc.formatBandwidth(summary.output.max)
  465. },
  466. 'duration': {
  467. 'avg': date.timingFormat(Math.round(summary.duration.avg)),
  468. 'min': date.timingFormat(summary.duration.min),
  469. 'max': date.timingFormat(summary.duration.max)
  470. },
  471. 'times': {
  472. 'oldest': new Date(summary.times.oldest).toDateString(),
  473. 'youngest': new Date(summary.times.youngest).toDateString()
  474. }
  475. };
  476. }
  477. this.set("summary",tmp);
  478. }.observes('serverData'),
  479. columnsName: Ember.ArrayController.create({
  480. content: [
  481. { name: 'App ID', index: 0 },
  482. { name: 'Name', index: 1 },
  483. { name: 'Type', index: 2 },
  484. { name: 'User', index: 3 },
  485. { name: 'Jobs', index: 4 },
  486. { name: 'Input', index: 5 },
  487. { name: 'Output', index: 6 },
  488. { name: 'Duration', index: 7 },
  489. { name: 'Run Date', index: 8 }
  490. ]
  491. })
  492. })