Repository: ambari Updated Branches: refs/heads/trunk ad0702ccd -> 64a65149f
AMBARI-6476. Create models for jobs. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/64a65149 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/64a65149 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/64a65149 Branch: refs/heads/trunk Commit: 64a65149f490272129329e1052c9d9427e132fa8 Parents: ad0702c Author: Oleg Nechiporenko <[email protected]> Authored: Mon Jul 14 18:10:09 2014 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Mon Jul 14 18:10:09 2014 +0300 ---------------------------------------------------------------------- .../src/main/resources/ui/app/scripts/app.js | 5 +- .../resources/ui/app/scripts/helpers/date.js | 216 +++++++++++++++++++ .../resources/ui/app/scripts/helpers/misc.js | 41 ++++ .../resources/ui/app/scripts/helpers/number.js | 57 +++++ .../resources/ui/app/scripts/helpers/string.js | 45 ++++ .../ui/app/scripts/helpers/validator.js | 26 +++ .../main/resources/ui/app/scripts/models/job.js | 69 ++++++ .../ui/app/scripts/models/jobs/abstract_job.js | 74 +++++++ .../ui/app/scripts/models/jobs/hive_job.js | 34 +++ .../ui/app/scripts/models/jobs/tez_dag.js | 209 ++++++++++++++++++ .../main/resources/ui/app/scripts/models/run.js | 121 +++++++++++ 11 files changed, 896 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js index 4b83e74..f4e1295 100644 --- a/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js @@ -18,10 +18,13 @@ var App = window.App = Ember.Application.create(); +App.Helpers = Ember.Namespace.create(); + /* Order and include as you please. */ +require('scripts/helpers/*'); require('scripts/controllers/*'); require('scripts/store'); -require('scripts/models/*'); +require('scripts/models/**/*'); require('scripts/routes/*'); require('scripts/components/*'); require('scripts/views/*'); http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/date.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/date.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/date.js new file mode 100644 index 0000000..66a5fb1 --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/date.js @@ -0,0 +1,216 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +App.Helpers.date = { + + /** + * List of monthes short names + * @type {string[]} + */ + dateMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + + /** + * List of days short names + * @type {string[]} + */ + dateDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + + /** + * Add leading zero + * + * @param {string} time + * @returns {string} + * @method dateFormatZeroFirst + */ + dateFormatZeroFirst: function (time) { + if (time < 10) return '0' + time; + return "" + time; + }, + + /** + * Convert timestamp to date-string 'DAY_OF_THE_WEEK, MONTH DAY, YEAR HOURS:MINUTES' + * + * @param {number} timestamp + * @param {bool} showSeconds should seconds be added to result string + * @param {bool} showMilliseconds should miliseconds be added to result string (if <code>showSeconds</code> is false, milliseconds wouldn't be added) + * @return {*} date + * @method dateFormat + */ + dateFormat: function (timestamp, showSeconds, showMilliseconds) { + if (!App.Helpers.validator.isValidInt(timestamp)) { + return timestamp; + } + var format = 'ddd, MMM DD, YYYY HH:mm'; + if (showSeconds) { + format += ':ss'; + if (showMilliseconds) { + format += ':SSS'; + } + } + return moment((new Date(timestamp)).toISOString().replace('Z', '')).format(format); + }, + + /** + * Convert timestamp to date-string 'DAY_OF_THE_WEEK MONTH DAY YEAR' + * + * @param {string} timestamp + * @return {string} + * @method dateFormatShort + */ + dateFormatShort: function (timestamp) { + if (!App.Helpers.validator.isValidInt(timestamp)) { + return timestamp; + } + var format = 'ddd MMM DD YYYY'; + var date = moment((new Date(timestamp)).toISOString().replace('Z', '')).format(format); + var today = moment((new Date()).toISOString().replace('Z', '')).format(format); + if (date === today) { + return 'Today ' + (new Date(timestamp)).toLocaleTimeString(); + } + return date; + }, + + /** + * Convert starTimestamp to 'DAY_OF_THE_WEEK, MONTH DAY, YEAR HOURS:MINUTES', except for the case: year equals 1969 + * + * @param {string} startTimestamp + * @return {string} startTimeSummary + * @method startTime + */ + startTime: function (startTimestamp) { + if (!App.Helpers.validator.isValidInt(startTimestamp)) { + return ''; + } + var startDate = new Date(startTimestamp); + var months = this.dateMonths; + var days = this.dateDays; + // generate start time + if (startDate.getFullYear() == 1969 || startTimestamp < 1) { + return 'Not started'; + } + var startTimeSummary = ''; + if (new Date(startTimestamp).setHours(0, 0, 0, 0) == new Date().setHours(0, 0, 0, 0)) { //today + startTimeSummary = 'Today ' + this.dateFormatZeroFirst(startDate.getHours()) + ':' + this.dateFormatZeroFirst(startDate.getMinutes()); + } else { + startTimeSummary = days[startDate.getDay()] + ' ' + months[startDate.getMonth()] + ' ' + + this.dateFormatZeroFirst(startDate.getDate()) + ' ' + startDate.getFullYear() + ' ' + + this.dateFormatZeroFirst(startDate.getHours()) + ':' + this.dateFormatZeroFirst(startDate.getMinutes()); + } + return startTimeSummary; + }, + + /** + * Provides the duration between the given start and end timestamp. If start time + * not valid, duration will be ''. If end time is not valid, duration will + * be till now, showing 'Lasted for xxx secs'. + * + * @param {string} startTimestamp + * @param {string} endTimestamp + * @return {string} durationSummary + * @method durationSummary + */ + durationSummary: function (startTimestamp, endTimestamp) { + // generate duration + var durationSummary = ''; + var startDate = new Date(startTimestamp); + var endDate = new Date(endTimestamp); + var self = this; + if (startDate.getFullYear() == 1969 || startTimestamp < 1) { + // not started + return Em.I18n.t('common.na'); + } + if (endDate.getFullYear() != 1969 && endTimestamp > 0) { + return '' + this.timingFormat(endTimestamp - startTimestamp, 1); //lasted for xx secs + } else { + // still running, duration till now + var time = (App.dateTime() - startTimestamp) < 0 ? 0 : (App.dateTime() - startTimestamp); + durationSummary = '' + this.timingFormat(time, 1); + } + return durationSummary; + }, + + /** + * Convert time in mseconds to + * 30 ms = 30 ms + * 300 ms = 300 ms + * 999 ms = 999 ms + * 1000 ms = 1.00 secs + * 3000 ms = 3.00 secs + * 35000 ms = 35.00 secs + * 350000 ms = 350.00 secs + * 999999 ms = 999.99 secs + * 1000000 ms = 16.66 mins + * 3500000 secs = 58.33 mins + * + * @param {number} time + * @param {bool} zeroValid for the case to show 0 when time is 0, not null + * @return {string|null} formatted date + * @method timingFormat + */ + timingFormat: function (time, /* optional */ zeroValid) { + var intTime = parseInt(time); + if (zeroValid && intTime == 0) { + return 0 + ' secs'; + } + if (!intTime) { + return null; + } + var timeStr = intTime.toString(); + var lengthOfNumber = timeStr.length; + var oneMinMs = 60000; + var oneHourMs = 3600000; + var oneDayMs = 86400000; + + if (lengthOfNumber < 4) { + return time + ' ms'; + } else if (lengthOfNumber < 7) { + time = (time / 1000).toFixed(2); + return time + ' secs'; + } else if (time < oneHourMs) { + time = (time / oneMinMs).toFixed(2); + return time + ' mins'; + } else if (time < oneDayMs) { + time = (time / oneHourMs).toFixed(2); + return time + ' hours'; + } else { + time = (time / oneDayMs).toFixed(2); + return time + ' days'; + } + }, + + /** + * Provides the duration between the given start and end time. If start time + * is not given, duration will be 0. If end time is not given, duration will + * be till now. + * + * @param {Number} startTime Start time from epoch + * @param {Number} endTime End time from epoch + * @return {Number} duration + * @method duration + */ + duration: function (startTime, endTime) { + var duration = 0; + if (startTime && startTime > 0) { + if (!endTime || endTime < 1) { + endTime = App.dateTime(); + } + duration = endTime - startTime; + } + return duration; + } +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/misc.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/misc.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/misc.js new file mode 100644 index 0000000..25af752 --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/misc.js @@ -0,0 +1,41 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +App.Helpers.misc = { + + /** + * Convert value from bytes to appropriate measure + */ + formatBandwidth: function (value) { + if (value) { + if (value < 1024) { + value = '<1KB'; + } else { + if (value < 1048576) { + value = (value / 1024).toFixed(1) + 'KB'; + } else if (value >= 1048576 && value < 1073741824){ + value = (value / 1048576).toFixed(1) + 'MB'; + } else { + value = (value / 1073741824).toFixed(2) + 'GB'; + } + } + } + return value; + } + +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/number.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/number.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/number.js new file mode 100644 index 0000000..164ae96 --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/number.js @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +App.Helpers.number = { + + /** + * Convert byte size to other metrics. + * + * @param {Number} bytes to convert to string + * @param {Number} precision Number to adjust precision of return value. Default is 0. + * @param {String} parseType + * JS method name for parse string to number. Default is "parseInt". + * @param {Number} multiplyBy bytes by this number if given. This is needed + * as <code>null * 1024 = 0</null> + * @remarks The parseType argument can be "parseInt" or "parseFloat". + * @return {String} Returns converted value with abbreviation. + */ + bytesToSize: function (bytes, precision, parseType, multiplyBy) { + if (bytes === null || bytes === undefined) { + return 'n/a'; + } else { + if (arguments[2] === undefined) { + parseType = 'parseInt'; + } + if (arguments[3] === undefined) { + multiplyBy = 1; + } + var value = bytes * multiplyBy; + var sizes = [ 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB' ]; + var posttxt = 0; + while (value >= 1024) { + posttxt++; + value = value / 1024; + } + if (value === 0) { + precision = 0; + } + var parsedValue = window[parseType](value); + return parsedValue.toFixed(precision) + " " + sizes[posttxt]; + } + } + +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/string.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/string.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/string.js new file mode 100644 index 0000000..eb49c4a --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/string.js @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +App.Helpers.string = { + + /** + * Determines whether string end within another string. + * + * @method endsWith + * @param {string} str string + * @param {string} suffix substring for search + * @return {boolean} + */ + endsWith: function (str, suffix) { + return str.indexOf(suffix, this.length - suffix.length) !== -1; + }, + + /** + * Determines whether string start within another string. + * + * @method startsWith + * @param {string} str string + * @param {string} prefix substring for search + * @return {boolean} + */ + startsWith: function (str, prefix) { + return str.indexOf(prefix) == 0; + } + +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/validator.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/validator.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/validator.js new file mode 100644 index 0000000..ea564ef --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/validator.js @@ -0,0 +1,26 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +App.Helpers.validator = { + + isValidInt: function(value) { + var intRegex = /^-?\d+$/; + return intRegex.test(value); + } + +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/models/job.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/job.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/job.js new file mode 100644 index 0000000..39bfc3e --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/job.js @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +App.Job = DS.Model.extend({ + + run: DS.belongsTo('App.Run'), + + jobName: DS.attr('string'), + + workflowEntityName: DS.attr('string'), + + userName: DS.attr('string'), + + confPath: DS.attr('string'), + + submitTime: DS.attr('number'), + + maps: DS.attr('number'), + + reduces: DS.attr('number'), + + status: DS.attr('string'), + + input: DS.attr('number'), + + output: DS.attr('number'), + + elapsedTime: DS.attr('number'), + + duration: function () { + return App.Helpers.date.timingFormat(parseInt(this.get('elapsedTime'))); + }.property('elapsedTime'), + + jobTimeLine: DS.attr('string'), + + jobTaskView: DS.attr('string'), + + /** + * Sum of input bandwidth for all jobs with appropriate measure + */ + inputFormatted: function () { + return App.Helpers.misc.formatBandwidth(this.get('input')); + }.property('input'), + + /** + * Sum of output bandwidth for all jobs with appropriate measure + */ + outputFormatted: function () { + return App.Helpers.misc.formatBandwidth(this.get('output')); + }.property('output') + +}); + +App.Job.FIXTURES = []; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/abstract_job.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/abstract_job.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/abstract_job.js new file mode 100644 index 0000000..94d02ca --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/abstract_job.js @@ -0,0 +1,74 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/** + * Base class of all Jobs. + * + * This class is meant to be extended and not instantiated directly. + */ +App.AbstractJob = DS.Model.extend({ + + id : DS.attr('string'), + + name : DS.attr('string'), + + user : DS.attr('string'), + + startTime : DS.attr('number'), + + endTime : DS.attr('number'), + + startTimeDisplay : function() { + var startTime = this.get('startTime'); + return startTime > 0 ? App.Helpers.date.dateFormat(startTime) : ''; + }.property('startTime'), + + endTimeDisplay : function() { + var endTime = this.get('endTime'); + return endTime > 0 ? App.Helpers.date.dateFormat(endTime) : ''; + }.property('endTime'), + + /** + * Provides the duration of this job. If the job has not started, duration + * will be given as 0. If the job has not ended, duration will be till now. + * + * @return {Number} Duration in milliseconds. + */ + duration : function() { + var startTime = this.get('startTime'); + var endTime = this.get('endTime'); + if(endTime < startTime || endTime == undefined) { + endTime = App.dateTime(); + } + return dateUtils.duration(startTime, endTime); + }.property('startTime', 'endTime'), + + durationDisplay : function() { + return App.Helpers.date.timingFormat(this.get('duration'), true); + }.property('duration'), + + /** + * Type of this job. Should be one of constants defined in App.JobType + */ + jobType : DS.attr('string') +}); + +App.JobType = { + HIVE : "hive" +}; + +App.AbstractJob.FIXTURES = []; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/hive_job.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/hive_job.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/hive_job.js new file mode 100644 index 0000000..146b73a --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/hive_job.js @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +App.HiveJob = App.AbstractJob.extend({ + + jobType : App.JobType.HIVE, + + queryText : DS.attr('string'), + + stages : DS.attr('array'), + + hasTezDag: DS.attr('boolean'), + + tezDag : DS.belongsTo('App.TezDag'), + + failed: DS.attr('boolean') + +}); + +App.HiveJob.FIXTURES = []; http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/tez_dag.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/tez_dag.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/tez_dag.js new file mode 100644 index 0000000..b8e13a3 --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/jobs/tez_dag.js @@ -0,0 +1,209 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +App.TezDag = DS.Model.extend({ + + id : DS.attr('string'), + + /** + * When DAG is actually running on server, a unique ID is assigned. + */ + instanceId : DS.attr('string'), + + name : DS.attr('string'), + + yarnApplicationId: DS.attr('string'), + + stage : DS.attr('string'), + + vertices : DS.hasMany('App.TezDagVertex'), + + edges : DS.hasMany('App.TezDagEdge') + +}); + +App.TezDagEdge = DS.Model.extend({ + + id : DS.attr('string'), + + instanceId : DS.attr('string'), + + fromVertex : DS.belongsTo('App.TezDagVertex'), + + toVertex : DS.belongsTo('App.TezDagVertex'), + + /** + * Type of this edge connecting vertices. Should be one of constants defined + * in 'App.TezDagEdgeType'. + */ + edgeType : DS.attr('string') +}); + +App.TezDagVertex = DS.Model.extend({ + + id : DS.attr('string'), + /** + * When DAG vertex is actually running on server, a unique ID is assigned. + */ + instanceId : DS.attr('string'), + + name : DS.attr('string'), + + /** + * State of this vertex. Should be one of constants defined in + * App.TezDagVertexState. + */ + state : DS.attr('string'), + + /** + * Vertex type has to be one of the types defined in 'App.TezDagVertexType' + * @return {string} + */ + type : DS.attr('string'), + + /** + * A vertex can have multiple incoming edges. + */ + incomingEdges : DS.hasMany('App.TezDagEdge'), + + /** + * This vertex can have multiple outgoing edges. + */ + outgoingEdges : DS.hasMany('App.TezDagEdge'), + + startTime : DS.attr('number'), + + endTime : DS.attr('number'), + + /** + * Provides the duration of this job. If the job has not started, duration + * will be given as 0. If the job has not ended, duration will be till now. + * + * @return {Number} Duration in milliseconds. + */ + duration : function() { + return App.Helpers.date.duration(this.get('startTime'), this.get('endTime')) + }.property('startTime', 'endTime'), + + /** + * Each Tez vertex can perform arbitrary application specific computations + * inside. The application can provide a list of operations it has provided in + * this vertex. + * + * Array of strings. [{string}] + */ + operations : DS.attr('array'), + + /** + * Provides additional information about the 'operations' performed in this + * vertex. This is shown directly to the user. + */ + operationPlan : DS.attr('string'), + + /** + * Number of actual Map/Reduce tasks in this vertex + */ + tasksCount : DS.attr('number'), + + tasksNumber: function () { + return this.get('tasksCount') ? this.get('tasksCount') : 0; + }.property('tasksCount'), + + /** + * Local filesystem usage metrics for this vertex + */ + fileReadBytes : DS.attr('number'), + + fileWriteBytes : DS.attr('number'), + + fileReadOps : DS.attr('number'), + + fileWriteOps : DS.attr('number'), + + /** + * Spilled records + */ + spilledRecords : DS.attr('number'), + + /** + * HDFS usage metrics for this vertex + */ + hdfsReadBytes : DS.attr('number'), + + hdfsWriteBytes : DS.attr('number'), + + hdfsReadOps : DS.attr('number'), + + hdfsWriteOps : DS.attr('number'), + + /** + * Record metrics for this vertex + */ + recordReadCount : DS.attr('number'), + + recordWriteCount : DS.attr('number'), + + totalReadBytes : function() { + return this.get('fileReadBytes') + this.get('hdfsReadBytes'); + }.property('fileReadBytes', 'hdfsReadBytes'), + + totalWriteBytes : function() { + return this.get('fileWriteBytes') + this.get('hdfsWriteBytes'); + }.property('fileWriteBytes', 'hdfsWriteBytes'), + + totalReadBytesDisplay : function() { + return App.Helpers.number.bytesToSize(this.get('totalReadBytes')); + }.property('totalReadBytes'), + + totalWriteBytesDisplay : function() { + return App.Helpers.number.bytesToSize(this.get('totalWriteBytes')); + }.property('totalWriteBytes'), + + durationDisplay : function() { + return App.Helpers.date.timingFormat(this.get('duration'), true); + }.property('duration') + +}); + +App.TezDagVertexState = { + NEW : "NEW", + INITIALIZING : "INITIALIZING", + INITED : "INITED", + RUNNING : "RUNNING", + SUCCEEDED : "SUCCEEDED", + FAILED : "FAILED", + KILLED : "KILLED", + ERROR : "ERROR", + TERMINATING : "TERMINATING", + JOBFAILED: "JOB FAILED" +}; + +App.TezDagVertexType = { + MAP: 'MAP', + REDUCE: 'REDUCE', + UNION: 'UNION' +}; + +App.TezDagEdgeType = { + SCATTER_GATHER : "SCATTER_GATHER", + BROADCAST : "BROADCAST", + CONTAINS: "CONTAINS" +}; + +App.TezDag.FIXTURES = []; +App.TezDagEdge.FIXTURES = []; +App.TezDagVertex.FIXTURES = []; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/64a65149/contrib/views/jobs/src/main/resources/ui/app/scripts/models/run.js ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/run.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/run.js new file mode 100644 index 0000000..a8422cb --- /dev/null +++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/run.js @@ -0,0 +1,121 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +App.Run = DS.Model.extend({ + + appName: DS.attr('string'), + + userName:DS.attr('string'), + + numJobsTotal: DS.attr('number'), + + numJobsCompleted: DS.attr('number'), + + startTime:DS.attr('string'), + + elapsedTime:DS.attr('string'), + + workflowContext:DS.attr('string'), + + input: DS.attr('number'), + + output: DS.attr('number'), + + loadAllJobs : false, + + isStared: false, + + isFiltered: false, + + /** + * runId short part + */ + idFormatted: function() { + return this.get('id').substr(0, 20); + }.property('id'), + + /** + * Jobs in the current run + */ + jobs: function() { + return App.Job.find().filterProperty('run.id', this.get('id')); + }.property('loadAllJobs'), + + /** + * Run duration + */ + duration: function() { + return App.Helpers.date.timingFormat(parseInt(this.get('elapsedTime'))); + }.property('elapsedTime'), + + /** + * Status of running jobs + */ + isRunning: function () { + return !this.get('numJobsTotal') == this.get('numJobsCompleted'); + }.property('numJobsTotal', 'numJobsCompleted'), + + /** + * Sum of input bandwidth for all jobs with appropriate measure + */ + inputFormatted: function () { + var input = this.get('input'); + input = App.Helpers.misc.formatBandwidth(input); + return input; + }.property('input'), + + /** + * Sum of output bandwidth for all jobs with appropriate measure + */ + outputFormatted: function () { + var output = this.get('output'); + output = App.Helpers.misc.formatBandwidth(output); + return output; + }.property('output'), + + /** + * + */ + lastUpdateTime: function() { + return parseInt(this.get('startTime')) + parseInt(this.get('elapsedTime')); + }.property('elapsedTime', 'startTime'), + + /** + * + */ + lastUpdateTimeFormatted: function() { + return App.Helpers.date.dateFormat(this.get('lastUpdateTime')); + }.property('lastUpdateTime'), + + lastUpdateTimeFormattedShort: function(){ + return App.Helpers.date.dateFormatShort(this.get('lastUpdateTime')); + }.property('lastUpdateTime'), + + /** + * Type value based on first part of id + */ + type: function() { + var id = this.get('id'); + if(App.Helpers.string.startsWith(id, 'pig_')) return 'Pig'; + if(App.Helpers.string.startsWith(id, 'hive_')) return 'Hive'; + if(App.Helpers.string.startsWith(id, 'mr_')) return 'MapReduce'; + return ''; + }.property('id') +}); + +App.Run.FIXTURES = [];
