Updated Branches: refs/heads/trunk ab0c39c07 -> 88ddc9222
AMBARI-4289. Mirroring: datasets loading integration with API. (akovalenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/88ddc922 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/88ddc922 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/88ddc922 Branch: refs/heads/trunk Commit: 88ddc9222a4629f0f6f798fdae0305ac48648e2b Parents: ab0c39c Author: Aleksandr Kovalenko <[email protected]> Authored: Tue Jan 14 20:25:31 2014 +0200 Committer: Aleksandr Kovalenko <[email protected]> Committed: Tue Jan 14 20:25:31 2014 +0200 ---------------------------------------------------------------------- .../data/mirroring/dataset1_definition.xml | 23 ++ .../data/mirroring/dataset1_instances.json | 42 ++++ .../data/mirroring/dataset2_definition.xml | 23 ++ .../data/mirroring/dataset2_instances.json | 42 ++++ .../data/mirroring/dataset3_definition.xml | 23 ++ .../data/mirroring/dataset3_instances.json | 1 + .../app/assets/data/mirroring/datasets.json | 16 ++ .../controllers/global/cluster_controller.js | 25 --- .../main/mirroring/jobs_controller.js | 16 +- .../controllers/main/mirroring_controller.js | 112 +++++++++- ambari-web/app/mappers/dataset_mapper.js | 210 +++---------------- ambari-web/app/models/dataset.js | 53 +---- ambari-web/app/models/dataset_job.js | 28 +-- ambari-web/app/routes/main.js | 11 - .../app/templates/main/mirroring/datasets.hbs | 46 ++-- .../app/templates/main/mirroring/jobs.hbs | 12 +- ambari-web/app/utils/ajax.js | 20 ++ ambari-web/app/utils/misc.js | 39 +++- .../app/views/main/mirroring/datasets_view.js | 14 +- .../app/views/main/mirroring/jobs_view.js | 61 +----- ambari-web/app/views/main/mirroring_view.js | 7 +- 21 files changed, 453 insertions(+), 371 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/dataset1_definition.xml ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/dataset1_definition.xml b/ambari-web/app/assets/data/mirroring/dataset1_definition.xml new file mode 100644 index 0000000..2b0c4d8 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/dataset1_definition.xml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<feed xmlns="uri:falcon:feed:0.1" name="dataset1" description=""><frequency>hours(1)</frequency> + <clusters> + <cluster name="source-cluster" type="source"> + <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/> + <retention action="delete" limit="days(7)"/> + </cluster> + + <cluster name="target-cluster1" type="target"> + <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/> + <retention action="delete" limit="months(1)"/>- + <locations> + <location type="data" path="/backup/app-logs1"/> + </locations> + </cluster> + </clusters> + + <locations> + <location type="data" path="/app-logs1"/> + </locations> + <ACL permission="0755" group="users" owner="hue"/> + <schema provider="none" location="/none"/> +</feed> http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/dataset1_instances.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/dataset1_instances.json b/ambari-web/app/assets/data/mirroring/dataset1_instances.json new file mode 100644 index 0000000..bc748e8 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/dataset1_instances.json @@ -0,0 +1,42 @@ +{"status": "SUCCEEDED", "message": "default/STATUS\n", "requestId": "default/a7463898-4d2a-4857-866d-15fdf65da84f\n", "instances": [ + { + "instance": "2013-10-24T00:00Z", + "status": "KILLED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000004-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-14T06:23:33Z", + "endTime": "2014-01-09T06:24:29Z", + "details": "" + }, + { + "instance": "2013-10-24T01:00Z", + "status": "KILLED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000005-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:25:35Z", + "endTime": "2014-01-09T06:26:02Z", + "details": "" + }, + { + "instance": "2013-10-24T02:00Z", + "status": "KILLED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000006-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:30:35Z", + "endTime": "2014-01-07T06:31:03Z", + "details": "" + }, + { + "instance": "2013-10-24T03:00Z", + "status": "KILLED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000007-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:35:35Z", + "endTime": "2014-01-02T06:36:03Z", + "details": "" + } +]} http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/dataset2_definition.xml ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/dataset2_definition.xml b/ambari-web/app/assets/data/mirroring/dataset2_definition.xml new file mode 100644 index 0000000..a9e4c25 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/dataset2_definition.xml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<feed xmlns="uri:falcon:feed:0.1" name="dataset2" description=""><frequency>hours(1)</frequency> + <clusters> + <cluster name="source-cluster" type="source"> + <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/> + <retention action="delete" limit="days(7)"/> + </cluster> + + <cluster name="target-cluster1" type="target"> + <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/> + <retention action="delete" limit="months(1)"/>- + <locations> + <location type="data" path="/backup/app-logs2"/> + </locations> + </cluster> + </clusters> + + <locations> + <location type="data" path="/app-logs2"/> + </locations> + <ACL permission="0755" group="users" owner="hue"/> + <schema provider="none" location="/none"/> +</feed> http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/dataset2_instances.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/dataset2_instances.json b/ambari-web/app/assets/data/mirroring/dataset2_instances.json new file mode 100644 index 0000000..efa8d88 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/dataset2_instances.json @@ -0,0 +1,42 @@ +{"status": "SUCCEEDED", "message": "default/STATUS\n", "requestId": "default/a7463898-4d2a-4857-866d-15fdf65da84f\n", "instances": [ + { + "instance": "2012-10-24T00:00Z", + "status": "RUNNING", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000004-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:23:33Z", + "endTime": "2014-01-09T06:24:29Z", + "details": "" + }, + { + "instance": "2012-10-24T01:00Z", + "status": "SUCCEEDED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000005-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:25:35Z", + "endTime": "2014-01-09T06:26:02Z", + "details": "" + }, + { + "instance": "2012-10-24T02:00Z", + "status": "FAILED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000006-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:30:35Z", + "endTime": "2014-01-09T06:31:03Z", + "details": "" + }, + { + "instance": "2012-10-24T03:00Z", + "status": "SUSPENDED", + "logFile": "http://c6407.ambari.apache.org:11000/oozie?job=0000007-140108205147729-oozie-oozi-W", + "cluster": "mcluster-bcp", + "sourceCluster": "mcluster", + "startTime": "2014-01-09T06:35:35Z", + "endTime": "2014-01-09T06:36:03Z", + "details": "" + } +]} http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/dataset3_definition.xml ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/dataset3_definition.xml b/ambari-web/app/assets/data/mirroring/dataset3_definition.xml new file mode 100644 index 0000000..6c94071 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/dataset3_definition.xml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<feed xmlns="uri:falcon:feed:0.1" name="dataset3" description=""><frequency>hours(1)</frequency> + <clusters> + <cluster name="source-cluster" type="source"> + <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/> + <retention action="delete" limit="days(7)"/> + </cluster> + + <cluster name="target-cluster2" type="target"> + <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/> + <retention action="delete" limit="months(1)"/>- + <locations> + <location type="data" path="/backup/app-logs3"/> + </locations> + </cluster> + </clusters> + + <locations> + <location type="data" path="/app-logs3"/> + </locations> + <ACL permission="0755" group="users" owner="hue"/> + <schema provider="none" location="/none"/> +</feed> http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/dataset3_instances.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/dataset3_instances.json b/ambari-web/app/assets/data/mirroring/dataset3_instances.json new file mode 100644 index 0000000..6d4afd5 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/dataset3_instances.json @@ -0,0 +1 @@ +{"status": "SUCCEEDED", "message": "default/STATUS\n", "requestId": "default/a7463898-4d2a-4857-866d-15fdf65da84f\n", "instances": []} http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/assets/data/mirroring/datasets.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/datasets.json b/ambari-web/app/assets/data/mirroring/datasets.json new file mode 100644 index 0000000..6b4dd90 --- /dev/null +++ b/ambari-web/app/assets/data/mirroring/datasets.json @@ -0,0 +1,16 @@ +{ + "entity": [ + { + "name": "dataset1", + "type": "feed" + }, + { + "name": "dataset2", + "type": "feed" + }, + { + "name": "dataset3", + "type": "feed" + } + ] +} http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index caca14b..98f6b68 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -59,8 +59,6 @@ App.ClusterController = Em.Controller.extend({ 'racks':false, 'alerts':false, 'users':false, - 'datasets':false, - 'targetclusters':false, 'status': false, 'componentConfigs': false }), @@ -332,29 +330,6 @@ App.ClusterController = Em.Controller.extend({ '&minimal_response=true'; var usersUrl = App.testMode ? '/data/users/users.json' : App.apiPrefix + '/users/?fields=*'; var racksUrl = "/data/racks/racks.json"; - var dataSetUrl = "/data/mirroring/all_datasets.json"; - var targetClusterUrl = "/data/mirroring/target_clusters.json"; - - if (App.supports.mirroring) { - App.HttpClient.get(targetClusterUrl, App.targetClusterMapper, { - complete: function (jqXHR, textStatus) { - self.updateLoadStatus('targetclusters'); - } - }, function (jqXHR, textStatus) { - self.updateLoadStatus('targetclusters'); - }); - - App.HttpClient.get(dataSetUrl, App.dataSetMapper, { - complete: function (jqXHR, textStatus) { - self.updateLoadStatus('datasets'); - } - }, function (jqXHR, textStatus) { - self.updateLoadStatus('datasets'); - }); - } else { - self.updateLoadStatus('targetclusters'); - self.updateLoadStatus('datasets'); - } App.HttpClient.get(racksUrl, App.racksMapper, { complete:function (jqXHR, textStatus) { http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/controllers/main/mirroring/jobs_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/mirroring/jobs_controller.js b/ambari-web/app/controllers/main/mirroring/jobs_controller.js index 01fd720..603cfb1 100644 --- a/ambari-web/app/controllers/main/mirroring/jobs_controller.js +++ b/ambari-web/app/controllers/main/mirroring/jobs_controller.js @@ -20,14 +20,16 @@ var App = require('app'); App.MainJobsController = Em.Controller.extend({ name: 'mainJobsController', + + isLoaded: function () { + return App.router.get('mainMirroringController.isLoaded'); + }.property('App.router.mainMirroringController.isLoaded'), + jobs: function () { - var jobs = App.DataSetJob.find().filterProperty('dataset', this.get('content')).sort( - function(a, b) { - return a.get('id') < b.get('id'); - } - ); - return jobs; - }.property('content'), + var mainMirroringController = App.router.get('mainMirroringController'); + return (this.get('isLoaded')) ? + mainMirroringController.get('datasets').findProperty('name', this.get('content.id')).get('datasetJobs') : []; + }.property('content', 'isLoaded'), actionDesc: function () { var dataset_status = this.get('content.status'); http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/controllers/main/mirroring_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/mirroring_controller.js b/ambari-web/app/controllers/main/mirroring_controller.js index 459b43f..fb66899 100644 --- a/ambari-web/app/controllers/main/mirroring_controller.js +++ b/ambari-web/app/controllers/main/mirroring_controller.js @@ -17,13 +17,118 @@ */ var App = require('app'); +var misc = require('utils/misc'); App.MainMirroringController = Em.ArrayController.extend({ name: 'mainMirroringController', - datasets: function () { - return App.Dataset.find(); - }.property(), + datasetsData: [], + + datasetCount: 0, + + datasets: [], + + isLoaded: false, + + loadDatasets: function () { + this.set('isLoaded', false); + this.get('datasetsData').clear(); + this.set('datasetCount', 0); + this.set('datasets', []); + App.ajax.send({ + name: 'mirroring.get_all_datasets', + sender: this, + success: 'onLoadDatasetsListSuccess', + error: 'onLoadDatasetsListError' + }); + }, + + onLoadDatasetsListSuccess: function (data) { + if (data && data.entity) { + this.set('datasetCount', data.entity.length); + data.entity.mapProperty('name').forEach(function (dataset) { + App.ajax.send({ + name: 'mirroring.get_dataset_definition', + sender: this, + data: { + dataset: dataset + }, + success: 'onLoadDatasetDefinitionSuccess', + error: 'onLoadDatasetDefinitionError' + }); + }, this); + } else { + this.onLoadDatasetsListError(); + } + }, + + onLoadDatasetsListError: function () { + console.error('Failed to load datasets list.'); + }, + + onLoadDatasetDefinitionSuccess: function (data) { + var parsedData = misc.xmlToObject(data); + var clusters = parsedData.feed.clusters; + var targetCluster, sourceCluster; + + if (clusters.cluster[0].locations) { + targetCluster = clusters.cluster[0]; + sourceCluster = clusters.cluster[1]; + } else { + targetCluster = clusters.cluster[1]; + sourceCluster = clusters.cluster[0]; + } + this.get('datasetsData').push( + Ember.Object.create({ + name: parsedData.feed['@attributes'].name, + sourceClusterName: sourceCluster['@attributes'].name, + targetClusterName: targetCluster['@attributes'].name, + sourceDir: parsedData.feed.locations.location['@attributes'].path, + targetDir: targetCluster.locations.location['@attributes'].path, + instances: [] + }) + ); + App.ajax.send({ + name: 'mirroring.dataset.get_all_instances', + sender: this, + data: { + dataset: parsedData.feed['@attributes'].name + }, + success: 'onLoadDatasetInstancesSuccess', + error: 'onLoadDatasetsInstancesError' + }); + }, + + onLoadDatasetDefinitionError: function () { + console.error('Failed to load dataset definition.'); + }, + + onLoadDatasetInstancesSuccess: function (data, sender, opts) { + var datasetJobs = []; + data.instances.forEach(function (instance) { + datasetJobs.push({ + dataset: opts.dataset, + id: instance.instance, + status: instance.status, + endTime: new Date(instance.endTime).getTime(), + startTime: new Date(instance.startTime).getTime() + }); + }, this); + this.get('datasetsData').findProperty('name', opts.dataset).set('instances', datasetJobs); + this.set('datasetCount', this.get('datasetCount') - 1); + if (this.get('datasetCount') < 1) { + App.Dataset.find().clear(); + App.dataSetMapper.map(this.get('datasetsData')); + this.set('datasets', App.Dataset.find().toArray().sort(function(a,b){ + return a.get('name') - b.get('name'); + })); + this.set('isLoaded', true); + } + }, + + onLoadDatasetsInstancesError: function () { + console.error('Failed to load dataset instances.'); + }, targetClusters: function () { return App.TargetCluster.find(); @@ -46,5 +151,4 @@ App.MainMirroringController = Em.ArrayController.extend({ } }); } - }); http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/mappers/dataset_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/dataset_mapper.js b/ambari-web/app/mappers/dataset_mapper.js index c542039..7495a51 100644 --- a/ambari-web/app/mappers/dataset_mapper.js +++ b/ambari-web/app/mappers/dataset_mapper.js @@ -22,197 +22,45 @@ App.dataSetMapper = App.QuickDataMapper.create({ model: App.Dataset, Jobs_model: App.DataSetJob, config: { - id: 'id', // approach 2 : to be calculated (TBC1) - name: 'Feeds.name', // from json - status: 'Feeds.status', // from json - source_cluster_name: 'Feeds.clusters.cluster[0].name', // approach1 : from json - $target_cluster: 'none', // will be loaded outside parser ( TBC2 ), - source_dir: 'Feeds.locations.location.path', - $schedule_id: 'none', // will be loaded outside parser - dataset_jobs: 'dataset_jobs', // TBC3 ( set of ids will be added ) - - // all below are unknown at present and may be blank - last_failed_date: 'last_failed_date', // TBC4 - last_succeeded_date: 'last_succeeded_date', // TBC5 - last_duration: 'last_duration', // TBC6 - avg_data: 'avg_data', // TBC7 - created_date: 'created_date', // TBC8 - target_dir: 'target_dir' - + id: 'name', + name: 'name', + status: 'status', + source_cluster_name: 'sourceClusterName', + target_cluster_name: 'targetClusterName', + source_dir: 'sourceDir', + target_dir: 'targetDir', + dataset_jobs_key: 'instances', + dataset_jobs_type: 'array', + dataset_jobs: { + item: 'id' + } }, jobs_config: { - $dataset_id: 'none', // will be loaded outside parser - id: 'Instances.id', - status : 'Instances.status', - start_date: 'start_date', - end_date: 'end_date', - duration: 'duration' - //data: 'Instances.details' - }, - - schedule_config: { - $dataset_id: 'none', // will be loaded outside parser id: 'id', - start_date : 'start_date', - end_date : 'end_date', - start_time : 'start_time', - end_time : 'end_time', - timezone : 'timezone', - frequency : 'frequency' - }, - - loadSchedule: function (datasetItemFromJson) { - App.store.load(App.Dataset.Schedule, this.parseSchedule(datasetItemFromJson)); - }, - - parseSchedule: function(datasetItemFromJson) { - var schedule = {}; - schedule.id = datasetItemFromJson.id; - var source_cluster = datasetItemFromJson.Feeds.clusters.cluster.findProperty("type", "source"); - var start_date = new Date(source_cluster.validity.start); - var end_date = new Date(source_cluster.validity.end); - - var d = new Date(); - var start_mm = start_date.getMonth() + 1; // In future may consider using getUTCMonth() - var start_dd = start_date.getDay(); - var start_yyyy = start_date.getFullYear(); - var end_mm = end_date.getMonth() + 1; - var end_dd = end_date.getDay(); - var end_yyyy = end_date.getFullYear(); - - schedule.start_date = start_mm + "/" + start_dd + "/" + start_yyyy; - schedule.end_date = end_mm + "/" + end_dd + "/" + end_yyyy; - - var start_hh = start_date.getHours(); - var start_mi = start_date.getMinutes(); - var start_ampm = (start_hh < 12 ? 'AM' : 'PM'); - var end_hh = end_date.getHours(); - var end_mi = end_date.getMinutes(); - var end_ampm = (end_hh < 12 ? 'AM' : 'PM'); - - if (start_hh) { - start_hh %= 12; - } - - if (end_hh) { - end_hh %= 12; - } - - schedule.start_time = start_hh + ":" + start_mi + ":" + start_ampm; - schedule.end_time = end_hh + ":" + end_mi + ":" + end_ampm; - - schedule.frequency = datasetItemFromJson.Feeds.frequency; - schedule.timezone = datasetItemFromJson.Feeds.timezone; - schedule.dataset_id = datasetItemFromJson.id; - return schedule; + name: 'id', + status : 'status', + start_date: 'startTime', + end_date: 'endTime', + dataset_id: 'dataset' }, map: function (json) { if (!this.get('model')) { return; } - if (json && json.items && json.items.length > 0) { - var dataset_results = []; - json.items.forEach(function (item) { - - try { - // TBC1 - item.id = this.getId(item.Feeds.name); - - // TBC3 - item.dataset_jobs = []; - - var last_failed_date = null; - var last_succeeded_date = null; - var last_end_date = null; - item.instances.forEach(function (job) { - var end_date = new Date(job.Instances.end); - - if (!last_end_date) { - last_end_date = end_date; - item.last_job = job; - } - else if (end_date > last_end_date) { - last_end_date = end_date; - item.last_job = job; - } - if (job.Instances.status === 'FAILED') { - if (last_failed_date == null || last_failed_date < end_date) { - item.last_failed_date = end_date.getTime(); - last_failed_date = end_date; - } - } - else if (job.Instances.status === 'SUCCESSFUL') { - if (last_succeeded_date == null || last_succeeded_date < end_date) { - item.last_succeeded_date = end_date.getTime(); - last_succeeded_date = end_date; - } - } - - item.dataset_jobs.push(job.Instances.id); - }); - - // calculate last_duration - - var last_end_date = new Date(item.last_job.Instances.end); - var last_start_date = new Date(item.last_job.Instances.start); - item.last_duration = last_end_date - last_start_date; - - - item.avg_data = ''; - item.created_date = ''; - item.target_dir = ''; - - var newitem = this.parseIt(item, this.config); - - // TBC2 - but shd be loaded after parsing - var target_cluster_name = (item.Feeds.clusters.cluster.findProperty("type", "target")).name; - var target_cluster_id = (item.Feeds.clusters.cluster.findProperty("type", "target")).name; - - newitem.target_cluster_id = this.getId(target_cluster_id); - - newitem.schedule_id = newitem.id; - - this.loadSchedule(item); - - dataset_results.push(newitem); - } catch (ex) { - console.debug('Exception occured : ' + ex); - } - }, this); - - App.store.loadMany(this.get('model'), dataset_results); - - try { - // Child records - var dataset_job_results = []; - json.items.forEach(function (item) { - item.instances.forEach(function (instance) { - instance.Instances.start = new Date(instance.Instances.start); // neeed to be calulated end -start - instance.Instances.end = new Date(instance.Instances.end); // neeed to be calulated end -start - instance.duration = instance.Instances.end - instance.Instances.start; - instance.start_date = instance.Instances.start; - instance.end_date = instance.Instances.end; - - var result = this.parseIt(instance, this.jobs_config); - result.dataset_id = item.id; - dataset_job_results.push(result); - - - }, this) + if (json && json.length > 0) { + var datasetResults = []; + var dataSetJobResults = []; + json.forEach(function (item) { + item.instances.forEach(function (job) { + var newInstance = this.parseIt(job, this.get('jobs_config')); + dataSetJobResults.push(newInstance); }, this); - - App.store.loadMany(this.get('Jobs_model'), dataset_job_results); - } - catch (ex) { - console.debug('Exception occured : ' + ex); - } + var newitem = this.parseIt(item, this.get('config')); + datasetResults.push(newitem); + }, this); + App.store.loadMany(this.get('Jobs_model'), dataSetJobResults); + App.store.loadMany(this.get('model'), datasetResults); } - }, - - getId: function(n) { - var re = new RegExp(" ", "g"); - return n.replace(re, "_"); } - }); http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/models/dataset.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/dataset.js b/ambari-web/app/models/dataset.js index a48c77e..89e9e99 100644 --- a/ambari-web/app/models/dataset.js +++ b/ambari-web/app/models/dataset.js @@ -20,31 +20,24 @@ var App = require('app'); App.Dataset = DS.Model.extend({ - id: DS.attr('string'), name: DS.attr('string'), status: DS.attr('string'), sourceClusterName: DS.attr('string'), - targetCluster: DS.belongsTo('App.TargetCluster'), + targetClusterName: DS.attr('string'), sourceDir: DS.attr('string'), targetDir: DS.attr('string'), - schedule: DS.belongsTo('App.Dataset.Schedule'), - lastSucceededDate: DS.attr('number'), - lastFailedDate: DS.attr('number'), - lastDuration: DS.attr('number'), - avgData: DS.attr('string'), - createdDate: DS.attr('string'), datasetJobs: DS.hasMany('App.DataSetJob'), + //Last succeeded date. Will be calculated later. + lastSucceededDate: function () { + return ''; + }.property(), + //Next instance to run. Will be calculated later. nextInstance: function () { return ''; }.property(), - //Name of target cluster related to dataset - cluster: function () { - return this.get('targetCluster.clusterName'); - }.property('targetCluster.clusterName'), - //Class name for dataset health status indicator healthClass: function () { var jobs = this.get('datasetJobs').toArray(); @@ -56,36 +49,4 @@ App.Dataset = DS.Model.extend({ }.property('datasetJobs', '[email protected]') }); - -App.Dataset.Schedule = DS.Model.extend({ - id: DS.attr('string'), - startDate: DS.attr('string'), - endDate: DS.attr('string'), - startTime: DS.attr('string'), - endTime: DS.attr('string'), - timezone: DS.attr('string'), - frequency: DS.attr('string'), - dataset: DS.belongsTo('App.Dataset') -}); - -App.Dataset.FIXTURES = [/* - { - id: 1, - cluster_name: 'cluster1', - stack_name: 'HDP', - hosts: [1, 2, 3, 4], - racks: [1, 2, 3, 4, 5, 6], - max_hosts_per_rack: 10 - }*/ -]; - -App.Dataset.Schedule.FIXTURES = [/* - { - id: 1, - cluster_name: 'cluster1', - stack_name: 'HDP', - hosts: [1, 2, 3, 4], - racks: [1, 2, 3, 4, 5, 6], - max_hosts_per_rack: 10 - }*/ -]; \ No newline at end of file +App.Dataset.FIXTURES = []; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/models/dataset_job.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/dataset_job.js b/ambari-web/app/models/dataset_job.js index 5ad698d..156ca80 100644 --- a/ambari-web/app/models/dataset_job.js +++ b/ambari-web/app/models/dataset_job.js @@ -21,28 +21,28 @@ var App = require('app'); var date = require('utils/date'); App.DataSetJob = DS.Model.extend({ + name: DS.attr('string'), dataset: DS.belongsTo('App.Dataset'), status: DS.attr('string'), startDate: DS.attr('number'), endDate: DS.attr('number'), - duration: DS.attr('number'), - startDateFormatted: function () { - return date.dateFormatShort(this.get('startDate')); + + startFormatted: function () { + if (this.get('startDate')) { + return $.timeago(this.get('startDate')); + } }.property('startDate'), - //data : DS.attr('string') + + endFormatted: function () { + if (this.get('endDate')) { + return $.timeago(this.get('endDate')); + } + }.property('endDate'), + healthClass: function () { return this.get('status') === 'FAILED' ? 'health-status-DEAD-RED' : 'health-status-LIVE'; }.property('status') }); -App.DataSetJob.FIXTURES = [/* - { - id: 1, - cluster_name: 'cluster1', - stack_name: 'HDP', - hosts: [1, 2, 3, 4], - racks: [1, 2, 3, 4, 5, 6], - max_hosts_per_rack: 10 - }*/ -]; +App.DataSetJob.FIXTURES = []; http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index 8062583..bcefd43 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -114,22 +114,11 @@ module.exports = Em.Route.extend({ route: '/mirroring', index: Ember.Route.extend({ route: '/', - enter: function () { - this.setupController() - }, - setupController: function () { - var controller = App.router.get('mainMirroringController'); - var datasets = App.Dataset.find(); - controller.set('datasets', datasets); - }, connectOutlets: function (router, context) { router.get('mainController').connectOutlet('mainMirroring'); } }), - gotoMirroringHome: function (router) { - router.transitionTo('mirroring/index'); - }, addNewDataset: function (router) { router.transitionTo('addNewDatasetRoute'); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/templates/main/mirroring/datasets.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/mirroring/datasets.hbs b/ambari-web/app/templates/main/mirroring/datasets.hbs index 2c8c3d5..23f8ef1 100644 --- a/ambari-web/app/templates/main/mirroring/datasets.hbs +++ b/ambari-web/app/templates/main/mirroring/datasets.hbs @@ -62,30 +62,38 @@ </tr> </thead> <tbody> - {{#if view.pageContent}} - {{#each dataset in view.pageContent}} - {{#view view.DatasetView contentBinding="dataset"}} - <td class="first"> - <span {{bindAttr class="dataset.healthClass"}}></span> + {{#if controller.isLoaded}} + {{#if view.pageContent}} + {{#each dataset in view.pageContent}} + {{#view view.DatasetView contentBinding="dataset"}} + <td class="first"> + <span {{bindAttr class="dataset.healthClass"}}></span> + </td> + <td class="name"> + <a title="{{unbound dataset.name}}" href="#" {{action "gotoShowJobs" dataset}}>{{unbound dataset.name}}</a> + </td> + <td>{{dataset.sourceDir}}</td> + <td>{{dataset.targetDir}}</td> + <td>{{dataset.targetClusterName}}</td> + <td>{{view.lastSucceededDateFormatted}}</td> + <td>{{dataset.nextInstance}}</td> + {{/view}} + {{/each}} + {{else}} + <tr> + <td class="first"></td> + <td colspan="6"> + {{t mirroring.table.noDatasets}} </td> - <td class="name"> - <a title="{{unbound dataset.name}}" href="#" {{action "gotoShowJobs" dataset}}>{{unbound dataset.name}}</a> - </td> - <td>{{dataset.sourceDir}}</td> - <td>{{dataset.targetDir}}</td> - <td>{{dataset.cluster}}</td> - <td>{{view.lastSucceededDateFormatted}}</td> - <td>{{dataset.nextInstance}}</td> - {{/view}} - {{/each}} + </tr> + {{/if}} {{else}} <tr> - <td class="first"></td> - <td colspan="6"> - {{t mirroring.table.noDatasets}} + <td colspan="7"> + <div class="spinner"></div> </td> </tr> - {{/if}} + {{/if}} </tbody> </table> http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/templates/main/mirroring/jobs.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/mirroring/jobs.hbs b/ambari-web/app/templates/main/mirroring/jobs.hbs index bed8ae3..8c937cf 100644 --- a/ambari-web/app/templates/main/mirroring/jobs.hbs +++ b/ambari-web/app/templates/main/mirroring/jobs.hbs @@ -75,6 +75,7 @@ </tr> </thead> <tbody> + {{#if controller.isLoaded}} {{#if view.pageContent}} {{#each job in view.pageContent}} {{#view view.JobView contentBinding="job"}} @@ -84,8 +85,8 @@ </td> <td>{{unbound job.id}}</td> - <td>{{view.startFormatted}}</td> - <td>{{view.endFormatted}}</td> + <td>{{unbound job.startFormatted}}</td> + <td>{{unbound job.endFormatted}}</td> {{/view}} {{/each}} {{else}} @@ -96,6 +97,13 @@ </td> </tr> {{/if}} + {{else}} + <tr> + <td colspan="7"> + <div class="spinner"></div> + </td> + </tr> + {{/if}} </tbody> </table> http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/utils/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js index 9b98a3b..fcb0d11 100644 --- a/ambari-web/app/utils/ajax.js +++ b/ambari-web/app/utils/ajax.js @@ -1342,6 +1342,26 @@ var urls = { }) } } + }, + + 'mirroring.get_all_datasets': { + 'real': 'falcon/entities/list/feed', + 'mock': '/data/mirroring/datasets.json' + }, + + 'mirroring.get_dataset_definition': { + 'real': 'falcon/entities/definition/feed/{dataset}', + 'mock': '/data/mirroring/{dataset}_definition.xml', + 'format': function (data) { + return { + dataType: 'xml' + } + } + }, + + 'mirroring.dataset.get_all_instances': { + 'real': 'falcon/instance/status/feed/{dataset}', + 'mock': '/data/mirroring/{dataset}_instances.json' } }; /** http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/utils/misc.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/misc.js b/ambari-web/app/utils/misc.js index 008345b..994397d 100644 --- a/ambari-web/app/utils/misc.js +++ b/ambari-web/app/utils/misc.js @@ -63,6 +63,43 @@ module.exports = { } } return sorted; + }, + + /** + * Convert XML document to Object + * @param xml + * @return {Object} + */ + xmlToObject: function (xml) { + var obj = {}; + if (xml.nodeType == 1) { + if (xml.attributes.length > 0) { + obj["@attributes"] = {}; + for (var j = 0; j < xml.attributes.length; j++) { + var attribute = xml.attributes.item(j); + obj["@attributes"][attribute.nodeName] = attribute.nodeValue; + } + } + } else if (xml.nodeType == 3) { + obj = xml.nodeValue; + } + if (xml.hasChildNodes()) { + for (var i = 0; i < xml.childNodes.length; i++) { + var item = xml.childNodes.item(i); + var nodeName = item.nodeName; + if (typeof (obj[nodeName]) == "undefined") { + obj[nodeName] = this.xmlToObject(item); + } else { + if (typeof (obj[nodeName].push) == "undefined") { + var old = obj[nodeName]; + obj[nodeName] = []; + obj[nodeName].push(old); + } + obj[nodeName].push(this.xmlToObject(item)); + } + } + } + return obj; } - + }; http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/views/main/mirroring/datasets_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/mirroring/datasets_view.js b/ambari-web/app/views/main/mirroring/datasets_view.js index 52edcaa..9af9a40 100644 --- a/ambari-web/app/views/main/mirroring/datasets_view.js +++ b/ambari-web/app/views/main/mirroring/datasets_view.js @@ -55,17 +55,17 @@ App.MainDatasetsView = App.TableView.extend({ }), sourceSort: sort.fieldView.extend({ - name: 'source', + name: 'sourceDir', displayName: Em.I18n.t('mirroring.table.datasetSource') }), targetSort: sort.fieldView.extend({ - name: 'target', + name: 'targetDir', displayName: Em.I18n.t('mirroring.table.datasetTarget') }), clusterSort: sort.fieldView.extend({ - name: 'cluster', + name: 'targetClusterName', displayName: Em.I18n.t('common.cluster') }), @@ -112,7 +112,7 @@ App.MainDatasetsView = App.TableView.extend({ fieldType: 'input-medium', column: 4, content: function () { - return ['Any'].concat(this.get('parentView.content').mapProperty('targetCluster.clusterName')); + return ['Any'].concat(this.get('parentView.content').mapProperty('targetClusterName').uniq()); }.property('this.parentView.content'), onClearValue: function () { if (this.get('value') === '') { @@ -176,9 +176,9 @@ App.MainDatasetsView = App.TableView.extend({ colPropAssoc: function () { var associations = []; associations[1] = 'name'; - associations[2] = 'source'; - associations[3] = 'target'; - associations[4] = 'cluster'; + associations[2] = 'sourceDir'; + associations[3] = 'targetDir'; + associations[4] = 'targetClusterName'; associations[5] = 'lastSucceededDate'; associations[6] = 'nextInstance'; return associations; http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/views/main/mirroring/jobs_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/mirroring/jobs_view.js b/ambari-web/app/views/main/mirroring/jobs_view.js index bd9579c..7a97cf4 100644 --- a/ambari-web/app/views/main/mirroring/jobs_view.js +++ b/ambari-web/app/views/main/mirroring/jobs_view.js @@ -27,7 +27,10 @@ App.MainJobsView = App.TableView.extend({ }.property('controller.jobs'), didInsertElement: function () { - this.set('content', this.get('controller.jobs')); + var mainMirroringController = App.router.get('mainMirroringController'); + if (!mainMirroringController.get('isLoaded')) { + mainMirroringController.loadDatasets(); + } }, dataset: function () { @@ -36,9 +39,9 @@ App.MainJobsView = App.TableView.extend({ sortView: sort.wrapperView, idSort: sort.fieldView.extend({ - name: 'id', + name: 'name', displayName: Em.I18n.t('mirroring.table.jobId'), - type: 'number' + type: 'string' }), startSort: sort.fieldView.extend({ name: 'startDate', @@ -50,16 +53,6 @@ App.MainJobsView = App.TableView.extend({ displayName: Em.I18n.t('mirroring.table.end'), type: 'number' }), - durationSort: sort.fieldView.extend({ - name: 'duration', - displayName: Em.I18n.t('mirroring.table.duration'), - type: 'number' - }), - dataSort: sort.fieldView.extend({ - name: 'data', - displayName: Em.I18n.t('mirroring.table.data'), - type: 'number' - }), /** * Filter view for name column @@ -91,22 +84,6 @@ App.MainJobsView = App.TableView.extend({ } }), - durationFilterView: filters.createTextView({ - fieldType: 'input-medium', - column: 4, - onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'duration'); - } - }), - - dataFilterView: filters.createTextView({ - fieldType: 'input-small', - column: 5, - onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'ambari-bandwidth'); - } - }), - JobView: Em.View.extend({ content: null, tagName: 'tr', @@ -187,27 +164,7 @@ App.MainJobsView = App.TableView.extend({ break; } }); - }, - - durationFormatted: function () { - var milliseconds = this.get('content.duration'); - var h = Math.floor(milliseconds / 3600000); - var m = Math.floor((milliseconds % 3600000) / 60000); - var s = Math.floor(((milliseconds % 360000) % 60000) / 1000); - return (h == 0 ? '' : h + 'hr ') + (m == 0 ? '' : m + 'mins ') + (s == 0 ? '' : s + 'secs '); - }.property('content.duration'), - - startFormatted: function () { - if (this.get('content.startDate')) { - return $.timeago(this.get('content.startDate')); - } - }.property('content.startDate'), - - endFormatted: function () { - if (this.get('content.endDate')) { - return $.timeago(this.get('content.endDate')); - } - }.property('content.endDate') + } }), /** @@ -215,11 +172,9 @@ App.MainJobsView = App.TableView.extend({ */ colPropAssoc: function () { var associations = []; - associations[1] = 'id'; + associations[1] = 'name'; associations[2] = 'startDate'; associations[3] = 'endDate'; - associations[4] = 'duration'; - associations[5] = 'data'; return associations; }.property() http://git-wip-us.apache.org/repos/asf/ambari/blob/88ddc922/ambari-web/app/views/main/mirroring_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/mirroring_view.js b/ambari-web/app/views/main/mirroring_view.js index 76e5a9b..8c465f0 100644 --- a/ambari-web/app/views/main/mirroring_view.js +++ b/ambari-web/app/views/main/mirroring_view.js @@ -20,5 +20,10 @@ var App = require('app'); App.MainMirroringView = Em.View.extend({ - templateName: require('templates/main/mirroring') + templateName: require('templates/main/mirroring'), + + didInsertElement: function () { + var controller = this.get('controller'); + controller.loadDatasets(); + } });
