You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ak...@apache.org on 2014/02/20 21:11:50 UTC

git commit: AMBARI-4763. Mirroring: API calls for dataset status Actions dropdown. (akovalenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk b03fe24a6 -> 021b236bb


AMBARI-4763. Mirroring: API calls for dataset status Actions dropdown. (akovalenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/021b236b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/021b236b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/021b236b

Branch: refs/heads/trunk
Commit: 021b236bb38b050cbb9662699df524fda35e5af8
Parents: b03fe24
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Thu Feb 20 19:22:36 2014 +0200
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Thu Feb 20 22:09:00 2014 +0200

----------------------------------------------------------------------
 ambari-web/app/app.js                           |   8 ++
 .../app/assets/data/mirroring/clusters.json     |  12 --
 .../app/assets/data/mirroring/clusters.xml      |  11 ++
 .../data/mirroring/dataset1_definition.xml      |   2 +-
 .../data/mirroring/dataset2_definition.xml      |   2 +-
 .../data/mirroring/dataset3_definition.xml      |   2 +-
 ambari-web/app/assets/data/mirroring/feeds.json |  16 ---
 ambari-web/app/assets/data/mirroring/feeds.xml  |  22 ++++
 .../main/mirroring/edit_dataset_controller.js   |  46 +++++---
 .../main/mirroring/jobs_controller.js           |  57 ++++++++-
 .../mirroring/manage_clusters_controller.js     |  27 +++--
 .../controllers/main/mirroring_controller.js    | 116 +++++++++++++------
 ambari-web/app/mappers/target_cluster_mapper.js |  20 ++++
 ambari-web/app/models/dataset.js                |  19 +--
 .../app/templates/main/mirroring/jobs.hbs       |  10 +-
 ambari-web/app/utils/ajax.js                    | 114 +++++++++++++++---
 .../app/views/main/mirroring/datasets_view.js   |   2 +-
 .../views/main/mirroring/edit_dataset_view.js   |  14 ++-
 18 files changed, 367 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index 3516be7..1d75573 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -52,6 +52,14 @@ module.exports = Em.Application.create({
     }
     return '/stacks2/HDP/versions/' + stackVersion.replace(/HDP-/g, '');
   }.property('currentStackVersion'),
+
+  falconServerURL: function () {
+    var falconService = this.Service.find().findProperty('serviceName', 'FALCON');
+    if (falconService) {
+      return falconService.get('hostComponents').findProperty('componentName', 'FALCON_SERVER').get('host.hostName');
+    }
+  }.property().volatile(),
+
   clusterName: null,
   clockDistance:null, // server clock - client clock
   currentStackVersion: '',

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/assets/data/mirroring/clusters.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/mirroring/clusters.json b/ambari-web/app/assets/data/mirroring/clusters.json
deleted file mode 100644
index 6d5aedf..0000000
--- a/ambari-web/app/assets/data/mirroring/clusters.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "entity": [
-    {
-      "name": "cluster1",
-      "type": "feed"
-    },
-    {
-      "name": "cluster2",
-      "type": "feed"
-    }
-  ]
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/assets/data/mirroring/clusters.xml
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/mirroring/clusters.xml b/ambari-web/app/assets/data/mirroring/clusters.xml
new file mode 100644
index 0000000..3867732
--- /dev/null
+++ b/ambari-web/app/assets/data/mirroring/clusters.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<entities>
+    <entity>
+        <type>cluster</type>
+        <name>cluster1</name>
+    </entity>
+    <entity>
+        <type>cluster</type>
+        <name>cluster2</name>
+    </entity>
+</entities>

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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
index ee2bedc..d067ee0 100644
--- a/ambari-web/app/assets/data/mirroring/dataset1_definition.xml
+++ b/ambari-web/app/assets/data/mirroring/dataset1_definition.xml
@@ -8,7 +8,7 @@
 
         <cluster name="tdk" type="target">
             <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/>
-            <retention action="delete" limit="months(1)"/>-
+            <retention action="delete" limit="months(1)"/>
             <locations>
                 <location type="data" path="/backup/app-logs1"/>
             </locations>

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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
index 1c5fcb6..ff0f276 100644
--- a/ambari-web/app/assets/data/mirroring/dataset2_definition.xml
+++ b/ambari-web/app/assets/data/mirroring/dataset2_definition.xml
@@ -8,7 +8,7 @@
 
         <cluster name="tdk" type="target">
             <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/>
-            <retention action="delete" limit="months(1)"/>-
+            <retention action="delete" limit="months(1)"/>
             <locations>
                 <location type="data" path="/backup/app-logs2"/>
             </locations>

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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
index eca5343..58cde34 100644
--- a/ambari-web/app/assets/data/mirroring/dataset3_definition.xml
+++ b/ambari-web/app/assets/data/mirroring/dataset3_definition.xml
@@ -8,7 +8,7 @@
 
         <cluster name="tdk" type="target">
             <validity end="2014-12-31T00:00Z" start="2013-10-24T00:00Z"/>
-            <retention action="delete" limit="months(1)"/>-
+            <retention action="delete" limit="months(1)"/>
             <locations>
                 <location type="data" path="/backup/app-logs3"/>
             </locations>

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/assets/data/mirroring/feeds.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/mirroring/feeds.json b/ambari-web/app/assets/data/mirroring/feeds.json
deleted file mode 100644
index 6b4dd90..0000000
--- a/ambari-web/app/assets/data/mirroring/feeds.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "entity": [
-    {
-      "name": "dataset1",
-      "type": "feed"
-    },
-    {
-      "name": "dataset2",
-      "type": "feed"
-    },
-    {
-      "name": "dataset3",
-      "type": "feed"
-    }
-  ]
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/assets/data/mirroring/feeds.xml
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/mirroring/feeds.xml b/ambari-web/app/assets/data/mirroring/feeds.xml
new file mode 100644
index 0000000..d200427
--- /dev/null
+++ b/ambari-web/app/assets/data/mirroring/feeds.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<feed description="" name="dataset1" xmlns="uri:falcon:feed:0.1">
+    <frequency>minutes(10)</frequency>
+    <clusters>
+        <cluster name="mycluster" type="source">
+            <validity start="2014-02-17T06:00Z" end="2014-02-19T01:00Z"/>
+            <retention limit="days(7)" action="delete"/>
+        </cluster>
+        <cluster name="cluster1" type="target">
+            <validity start="2014-02-17T06:00Z" end="2014-02-17T06:00Z"/>
+            <retention limit="months(1)" action="delete"/>
+            <locations>
+                <location type="data" path="/backup/app-logs"/>
+            </locations>
+        </cluster>
+    </clusters>
+    <locations>
+        <location type="data" path="/app-logs"/>
+    </locations>
+    <ACL owner="hue" group="users" permission="0755"/>
+    <schema location="/none" provider="none"/>
+</feed>

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/controllers/main/mirroring/edit_dataset_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/mirroring/edit_dataset_controller.js b/ambari-web/app/controllers/main/mirroring/edit_dataset_controller.js
index 96997fb..fa5b466 100644
--- a/ambari-web/app/controllers/main/mirroring/edit_dataset_controller.js
+++ b/ambari-web/app/controllers/main/mirroring/edit_dataset_controller.js
@@ -221,20 +221,36 @@ App.MainMirroringEditDataSetController = Ember.Controller.extend({
 
     // Compose XML data, that will be sended to server
     var dataToSend = '<?xml version="1.0"?><feed description="" name="' + datasetName + '" xmlns="uri:falcon:feed:0.1"><frequency>' + repeatOptionSelected + '(' + datasetFrequency + ')' +
-        '</frequency><clusters><cluster name="' + targetCluster + '" type="source"><validity start="' + scheduleStartDateFormatted + '" end="' + scheduleEndDateFormatted +
-        '"/><retention limit="days(7)" action="delete"/></cluster><cluster name="' + targetCluster + '" type="target"><validity start="' + scheduleStartDateFormatted + '" end="' +
+        '</frequency><clusters><cluster name="' + sourceCluster + '" type="source"><validity start="' + scheduleStartDateFormatted + '" end="' + scheduleEndDateFormatted +
+        '"/><retention limit="days(7)" action="delete"/></cluster><cluster name="' + targetCluster + '" type="target"><validity start="' + scheduleStartDateFormatted + '" end="' + scheduleStartDateFormatted +
         '"/><retention limit="months(1)" action="delete"/><locations><location type="data" path="' + targetDir + '" /></locations></cluster></clusters><locations><location type="data" path="' +
         sourceDir + '" /></locations><ACL owner="hue" group="users" permission="0755" /><schema location="/none" provider="none"/></feed>';
-
-    // Send request to server to create dataset
-    App.ajax.send({
-      name: 'mirroring.create_new_dataset',
-      sender: this,
-      data: {
-        dataset: dataToSend
-      },
-      error: 'onCreateNewDatasetError'
-    });
+    if (this.get('isEdit')) {
+      App.ajax.send({
+        name: 'mirroring.update_entity',
+        sender: this,
+        data: {
+          name: datasetName,
+          type: 'feed',
+          entity: dataToSend,
+          falconServer: App.get('falconServerURL')
+        },
+        success: 'onSaveSuccess',
+        error: 'onSaveError'
+      });
+    } else {
+      // Send request to server to create dataset
+      App.ajax.send({
+        name: 'mirroring.create_new_dataset',
+        sender: this,
+        data: {
+          dataset: dataToSend,
+          falconServer: App.get('falconServerURL')
+        },
+        success: 'onSaveSuccess',
+        error: 'onSaveError'
+      });
+    }
 
     var newDataset = {
       id: datasetName,
@@ -248,7 +264,11 @@ App.MainMirroringEditDataSetController = Ember.Controller.extend({
     App.store.load(App.Dataset, newDataset);
   },
 
-  onCreateNewDatasetError: function () {
+  onSaveSuccess: function () {
+    App.router.get('mainMirroringController').loadData();
+  },
+
+  onSaveError: function () {
     console.error('Error in sending new dataset data to server.');
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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 770b03f..592a03f 100644
--- a/ambari-web/app/controllers/main/mirroring/jobs_controller.js
+++ b/ambari-web/app/controllers/main/mirroring/jobs_controller.js
@@ -47,11 +47,66 @@ App.MainDatasetJobsController = Em.Controller.extend({
   }.property('content.status'),
 
   suspend: function () {
+    App.ajax.send({
+      name: 'mirroring.suspend_entity',
+      sender: this,
+      data: {
+        name: this.get('content.name'),
+        type: 'feed',
+        falconServer: App.get('falconServerURL')
+      },
+      success: 'onSuspendSuccess',
+      error: 'onError'
+    });
+  },
+
+  onSuspendSuccess: function() {
     this.set('content.status', 'SUSPENDED');
   },
 
   schedule: function () {
-    this.set('content.status', 'SCHEDULED');
+    App.ajax.send({
+      name: 'mirroring.schedule_entity',
+      sender: this,
+      data: {
+        name: this.get('content.name'),
+        type: 'feed',
+        falconServer: App.get('falconServerURL')
+      },
+      success: 'onScheduleSuccess',
+      error: 'onError'
+    });
+  },
+
+  onScheduleSuccess: function() {
+    this.set('content.status', 'RUNNING');
+  },
+
+
+  delete: function () {
+    var self = this;
+    App.showConfirmationPopup(function () {
+      App.ajax.send({
+        name: 'mirroring.delete_entity',
+        sender: self,
+        data: {
+          name: self.get('content.name'),
+          type: 'feed',
+          falconServer: App.get('falconServerURL')
+        },
+        success: 'onDeleteSuccess',
+        error: 'onError'
+      });
+    });
+  },
+
+  onDeleteSuccess: function() {
+    this.get('content').deleteRecord();
+    App.store.commit();
+  },
+
+  onError: function () {
+    App.showAlertPopup(Em.I18n.t('common.error'), arguments[2]);
   },
 
   downloadEntity: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js b/ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js
index 6930140..e221e75 100644
--- a/ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js
+++ b/ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js
@@ -113,11 +113,12 @@ App.MainMirroringManageClustersController = Em.ArrayController.extend({
       this.get('queryErrors').clear();
       clustersToDelete.forEach(function (cluster) {
         App.ajax.send({
-          name: 'mirroring.delete_instance',
+          name: 'mirroring.delete_entity',
           sender: this,
           data: {
             name: cluster,
-            type: 'cluster'
+            type: 'cluster',
+            falconServer: App.get('falconServerURL')
           },
           success: 'onQueryResponse',
           error: 'onQueryResponse'
@@ -125,11 +126,12 @@ App.MainMirroringManageClustersController = Em.ArrayController.extend({
       }, this);
       clustersToCreate.forEach(function (cluster) {
         App.ajax.send({
-          name: 'mirroring.submit_instance',
+          name: 'mirroring.submit_entity',
           sender: this,
           data: {
             type: 'cluster',
-            instance: this.formatClusterXML(clusters.findProperty('name', cluster))
+            entity: this.formatClusterXML(clusters.findProperty('name', cluster)),
+            falconServer: App.get('falconServerURL')
           },
           success: 'onQueryResponse',
           error: 'onQueryResponse'
@@ -137,12 +139,13 @@ App.MainMirroringManageClustersController = Em.ArrayController.extend({
       }, this);
       clustersToModify.forEach(function (cluster) {
         App.ajax.send({
-          name: 'mirroring.update_instance',
+          name: 'mirroring.update_entity',
           sender: this,
           data: {
             name: cluster,
             type: 'cluster',
-            instance: this.formatClusterXML(clusters.findProperty('name', cluster))
+            entity: this.formatClusterXML(clusters.findProperty('name', cluster)),
+            falconServer: App.get('falconServerURL')
           },
           success: 'onQueryResponse',
           error: 'onQueryResponse'
@@ -176,11 +179,13 @@ App.MainMirroringManageClustersController = Em.ArrayController.extend({
    * @return {String}
    */
   formatClusterXML: function (cluster) {
-    return '<?xml version="1.0"?><cluster colo="default" description="" name="' + cluster.get('name') +
-        '" xmlns="uri:falcon:cluster:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><interfaces><interface type="readonly" endpoint="' + cluster.get('readonly') +
-        '" version="2.2.0.2.0.6.0-76" /><interface type="execute" endpoint="' + cluster.get('execute') +
-        '" version="2.2.0.2.0.6.0-76" /><interface type="workflow" endpoint="' + cluster.get('workflow') +
-        '" version="3.1.4" /></interfaces><locations><location name="staging" path="' + cluster.get('staging') +
+    return '<?xml version="1.0"?><cluster colo="local" description="" name="' + cluster.get('name') +
+        '" xmlns="uri:falcon:cluster:0.1"><interfaces><interface type="readonly" endpoint="' + cluster.get('readonly') +
+        '" version="2.2.0" /><interface type="execute" endpoint="' + cluster.get('execute') +
+        '" version="2.2.0" /><interface type="workflow" endpoint="' + cluster.get('workflow') +
+        '" version="4.0.0" />' + '<interface type="messaging" endpoint="tcp://' + App.get('falconServerURL') +':61616?daemon=true" version="5.1.6" />' +
+        '<interface type="write" endpoint="hdfs://c6401.ambari.apache.org:8020" version="2.2.0" />' +
+        '</interfaces><locations><location name="staging" path="' + cluster.get('staging') +
         '" /><location name="temp" path="' + cluster.get('temp') +
         '" /><location name="working" path="' + cluster.get('working') +
         '" /></locations></cluster>';

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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 8d7595d..02ef2c2 100644
--- a/ambari-web/app/controllers/main/mirroring_controller.js
+++ b/ambari-web/app/controllers/main/mirroring_controller.js
@@ -35,6 +35,8 @@ App.MainMirroringController = Em.ArrayController.extend({
 
   datasets: [],
 
+  selectedDataset: null,
+
   isDatasetsLoaded: false,
 
   isTargetClustersLoaded: false,
@@ -60,7 +62,8 @@ App.MainMirroringController = Em.ArrayController.extend({
       name: 'mirroring.get_all_entities',
       sender: this,
       data: {
-        type: 'feed'
+        type: 'feed',
+        falconServer: App.get('falconServerURL')
       },
       success: 'onLoadDatasetsListSuccess',
       error: 'onLoadDatasetsListError'
@@ -68,22 +71,27 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadDatasetsListSuccess: function (data) {
-    if (data && data.entity) {
-      this.set('datasetCount', data.entity.length);
-      data.entity.mapProperty('name').forEach(function (dataset) {
+    var parsedData = misc.xmlToObject(data);
+    var datasets = parsedData.entities.entity;
+    if (data && datasets) {
+      datasets = Em.isArray(datasets) ? datasets : [datasets];
+      this.set('datasetCount', datasets.length);
+      datasets.forEach(function (dataset) {
         App.ajax.send({
           name: 'mirroring.get_definition',
           sender: this,
           data: {
-            name: dataset,
-            type: 'feed'
+            name: dataset.name['#text'],
+            type: 'feed',
+            status: dataset.status['#text'],
+            falconServer: App.get('falconServerURL')
           },
           success: 'onLoadDatasetDefinitionSuccess',
           error: 'onLoadDatasetDefinitionError'
         });
       }, this);
     } else {
-      this.onLoadDatasetsListError();
+      this.set('isDatasetsLoaded', true);
     }
   },
 
@@ -106,6 +114,7 @@ App.MainMirroringController = Em.ArrayController.extend({
     this.get('datasetsData').push(
         Ember.Object.create({
           name: parsedData.feed['@attributes'].name,
+          status: arguments[2].status,
           sourceClusterName: sourceCluster['@attributes'].name,
           targetClusterName: targetCluster['@attributes'].name,
           sourceDir: parsedData.feed.locations.location['@attributes'].path,
@@ -121,7 +130,10 @@ App.MainMirroringController = Em.ArrayController.extend({
       name: 'mirroring.dataset.get_all_instances',
       sender: this,
       data: {
-        dataset: parsedData.feed['@attributes'].name
+        dataset: parsedData.feed['@attributes'].name,
+        start: sourceCluster.validity['@attributes'].start,
+        end: sourceCluster.validity['@attributes'].end,
+        falconServer: App.get('falconServerURL')
       },
       success: 'onLoadDatasetInstancesSuccess',
       error: 'onLoadDatasetsInstancesError'
@@ -133,21 +145,23 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadDatasetInstancesSuccess: function (data, sender, opts) {
-    var datasetJobs = [];
     var datasetsData = this.get('datasetsData');
-    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);
-    datasetsData.findProperty('name', opts.dataset).set('instances', datasetJobs);
+    if (data.instances) {
+      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);
+      datasetsData.findProperty('name', opts.dataset).set('instances', datasetJobs);
+    }
     this.set('datasetCount', this.get('datasetCount') - 1);
-    var sortedDatasets = [];
     if (this.get('datasetCount') < 1) {
+      var sortedDatasets = [];
       App.dataSetMapper.map(datasetsData);
       sortedDatasets = App.Dataset.find().toArray().sort(function (a, b) {
         if (a.get('name') < b.get('name'))  return -1;
@@ -172,7 +186,8 @@ App.MainMirroringController = Em.ArrayController.extend({
       name: 'mirroring.get_all_entities',
       sender: this,
       data: {
-        type: 'cluster'
+        type: 'cluster',
+        falconServer: App.get('falconServerURL')
       },
       success: 'onLoadClustersListSuccess',
       error: 'onLoadClustersListError'
@@ -180,33 +195,49 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadClustersListSuccess: function (data) {
-    if (data && data.entity) {
-      this.set('clusterCount', data.entity.length);
-      this.set('clustersData.items', [
-        {
-          name: App.get('clusterName'),
-          execute: App.HostComponent.find().findProperty('componentName', 'RESOURCEMANAGER').get('host.hostName') + ':8050',
-          readonly: 'hftp://' + App.HostComponent.find().findProperty('componentName', 'NAMENODE').get('host.hostName') + ':50070',
-          workflow: 'http://' + App.HostComponent.find().findProperty('componentName', 'OOZIE_SERVER').get('host.hostName') + ':11000/oozie',
-          staging: '',
-          working: '',
-          temp: ''
-        }
-      ]);
-      data.entity.mapProperty('name').forEach(function (cluster) {
+    var clustersData = this.get('clustersData');
+    clustersData.items = [];
+    var parsedData = misc.xmlToObject(data);
+    var clusters = parsedData.entities.entity;
+    if (data && clusters) {
+      clusters = Em.isArray(clusters) ? clusters : [clusters];
+      this.set('clusterCount', clusters.length);
+      clusters.mapProperty('name.#text').forEach(function (cluster) {
         App.ajax.send({
           name: 'mirroring.get_definition',
           sender: this,
           data: {
             name: cluster,
-            type: 'cluster'
+            type: 'cluster',
+            falconServer: App.get('falconServerURL')
           },
           success: 'onLoadClusterDefinitionSuccess',
           error: 'onLoadClusterDefinitionError'
         });
       }, this);
     } else {
-      this.onLoadClustersListError();
+      var sourceCluster = Ember.Object.create({
+        name: App.get('clusterName'),
+        execute: App.HostComponent.find().findProperty('componentName', 'RESOURCEMANAGER').get('host.hostName') + ':8050',
+        readonly: 'hftp://' + App.HostComponent.find().findProperty('componentName', 'NAMENODE').get('host.hostName') + ':50070',
+        workflow: 'http://' + App.HostComponent.find().findProperty('componentName', 'OOZIE_SERVER').get('host.hostName') + ':11000/oozie',
+        staging: '/apps/falcon/sandbox/staging',
+        working: '/apps/falcon/sandbox/working',
+        temp: '/tmp'
+      });
+      var sourceClusterData = App.router.get('mainMirroringManageClustersController').formatClusterXML(sourceCluster);
+      App.ajax.send({
+        name: 'mirroring.submit_entity',
+        sender: this,
+        data: {
+          type: 'cluster',
+          entity: sourceClusterData,
+          falconServer: App.get('falconServerURL')
+        },
+        success: 'onSourceClusterCreateSuccess',
+        error: 'onSourceClusterCreateError'
+      });
+      clustersData.items.push(sourceCluster);
     }
   },
 
@@ -214,6 +245,15 @@ App.MainMirroringController = Em.ArrayController.extend({
     console.error('Failed to load clusters list.');
   },
 
+  onSourceClusterCreateSuccess: function () {
+    App.targetClusterMapper.map(this.get('clustersData'));
+    this.set('isTargetClustersLoaded', true);
+  },
+
+  onSourceClusterCreateError: function () {
+    console.error('Error in creating source cluster entity.');
+  },
+
   onLoadClusterDefinitionSuccess: function (data) {
     var parsedData = misc.xmlToObject(data);
     var clustersData = this.get('clustersData');
@@ -251,6 +291,7 @@ App.MainMirroringController = Em.ArrayController.extend({
   }.observes('isLoaded'),
 
   manageClusters: function () {
+    var self = this;
     var manageClustersController = App.router.get('mainMirroringManageClustersController');
     var popup = App.ModalPopup.show({
       header: Em.I18n.t('mirroring.dataset.manageClusters'),
@@ -263,6 +304,7 @@ App.MainMirroringController = Em.ArrayController.extend({
         manageClustersController.save();
       },
       hide: function () {
+        self.loadData();
         App.router.send('gotoShowJobs');
         this._super();
       },

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/mappers/target_cluster_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/target_cluster_mapper.js b/ambari-web/app/mappers/target_cluster_mapper.js
index 8967181..0b6052e 100644
--- a/ambari-web/app/mappers/target_cluster_mapper.js
+++ b/ambari-web/app/mappers/target_cluster_mapper.js
@@ -28,5 +28,25 @@ App.targetClusterMapper = App.QuickDataMapper.create({
     staging: 'staging',
     working: 'working',
     temp: 'temp'
+  },
+
+  map: function (json) {
+    var model = this.get('model');
+    if (!model) {
+      return;
+    }
+
+    if (json.items) {
+      var result = [];
+      var clustersToDelete = model.find().mapProperty('name');
+      json.items.forEach(function (item) {
+        result.push(this.parseIt(item, this.config));
+        clustersToDelete = clustersToDelete.without(item.name);
+      }, this);
+      clustersToDelete.forEach(function (name) {
+        this.deleteRecord(model.find().findProperty('name', name));
+      }, this);
+      App.store.loadMany(model, result);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/models/dataset.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/dataset.js b/ambari-web/app/models/dataset.js
index 9dbce72..72e37b9 100644
--- a/ambari-web/app/models/dataset.js
+++ b/ambari-web/app/models/dataset.js
@@ -21,6 +21,7 @@ var App = require('app');
 
 App.Dataset = DS.Model.extend({
   name: DS.attr('string'),
+  status: DS.attr('string'),
   sourceClusterName: DS.attr('string'),
   targetClusterName: DS.attr('string'),
   sourceDir: DS.attr('string'),
@@ -31,19 +32,11 @@ App.Dataset = DS.Model.extend({
   scheduleEndDate: DS.attr('string'),
   datasetJobs: DS.hasMany('App.DataSetJob'),
 
-  status: function () {
-    var jobs = this.get('datasetJobs').toArray();
-    if (jobs.someProperty('status', 'RUNNING')) {
-      return 'RUNNING';
-    } else if (jobs.someProperty('status', 'SUSPENDED')) {
-      return 'SUSPENDED';
-    } else {
-      return 'SCHEDULED';
-    }
-  }.property('datasetJobs', 'datasetJobs.@each.status'),
-
   statusFormatted: function (){
-    return this.get('status').toLowerCase().capitalize();
+    var status = this.get('status');
+    if (status) {
+      return status.toLowerCase().capitalize();
+    }
   }.property('status'),
 
   isRunning: function () {
@@ -55,7 +48,7 @@ App.Dataset = DS.Model.extend({
   }.property('status'),
 
   isScheduled: function () {
-    return this.get('status') === 'SCHEDULED';
+    return this.get('status') === 'SUBMITTED';
   }.property('status'),
 
   //Last succeeded date. Will be calculated later.

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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 0ac40cf..fb01548 100644
--- a/ambari-web/app/templates/main/mirroring/jobs.hbs
+++ b/ambari-web/app/templates/main/mirroring/jobs.hbs
@@ -15,6 +15,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
+{{#if view.dataset}}
 <div class="dataset-details">
   <div class="top-left">
     <h4>{{view.dataset.name}}</h4>
@@ -43,7 +44,7 @@
         <ul class="dropdown-menu pull-right">
           {{#if view.dataset.isRunning}}
             <li>
-              <a href="javascript:void(null);">
+              <a href="javascript:void(null);" {{action suspend target="controller"}}>
                 {{t mirroring.dataset.suspendInstance}}
               </a>
             </li>
@@ -55,13 +56,13 @@
           {{else}}
             {{#if view.dataset.isSuspended}}
               <li>
-                <a href="javascript:void(null);">
+                <a href="javascript:void(null);" {{action schedule target="controller"}}>
                   {{t mirroring.dataset.schedule}}
                 </a>
               </li>
             {{else}}
               <li>
-                <a href="javascript:void(null);">
+                <a href="javascript:void(null);" {{action suspend target="controller"}}>
                   {{t mirroring.dataset.suspend}}
                 </a>
               </li>
@@ -72,7 +73,7 @@
               </a>
             </li>
             <li>
-              <a href="javascript:void(null);">
+              <a href="javascript:void(null);" {{action delete target="controller"}}>
                 {{t common.delete}}
               </a>
             </li>
@@ -85,6 +86,7 @@
   {{/if}}
   <div class="bottom-right">{{t common.download}}: <a href="javascript:void(null);" {{action downloadEntity target="controller"}}>{{t mirroring.dataset.entity}}.xml</a></div>
 </div>
+{{/if}}
 <div>
   <table class="table table-bordered table-striped">
     <thead>

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index b8ce8dd..15b86d8 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -1431,66 +1431,146 @@ var urls = {
   },
 
   'mirroring.get_all_entities': {
-    'real': '/falcon/entities/list/{type}',
-    'mock': '/data/mirroring/{type}s.json'
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/list/{type}?fields=status',
+    'mock': '/data/mirroring/{type}s.xml',
+    'apiPrefix': '',
+    'format': function () {
+      return {
+        dataType: 'xml',
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa'
+        }
+      }
+    }
   },
 
   'mirroring.get_definition': {
-    'real': '/falcon/entities/definition/{type}/{name}',
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/definition/{type}/{name}',
     'mock': '/data/mirroring/{name}_definition.xml',
+    'apiPrefix': '',
     'format': function () {
       return {
-        dataType: 'xml'
+        cache: true,
+        dataType: 'xml',
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa'
+        }
       }
     }
   },
 
   'mirroring.dataset.get_all_instances': {
-    'real': '/falcon/instance/status/feed/{dataset}',
-    'mock': '/data/mirroring/{dataset}_instances.json'
+    'real': '/proxy?url=http://{falconServer}:15000/api/instance/status/feed/{dataset}?start={start}&end={end}',
+    'mock': '/data/mirroring/{dataset}_instances.json',
+    'apiPrefix': '',
+    'format': function (data) {
+      return {
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa'
+        }
+      }
+    }
   },
 
 
   'mirroring.create_new_dataset': {
-    'real': '/falcon/entities/submitAndSchedule/feed',
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/submitAndSchedule/feed',
     'mock': '/data/mirroring/succeeded.json',
+    'apiPrefix': '',
     'type': 'POST',
     'format': function (data) {
       return {
         contentType: 'text/xml',
-        data: data.dataset
+        dataType: 'xml',
+        data: data.dataset,
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa',
+          'AmbariProxy-Content-Type': 'text/xml'
+        }
       }
     }
   },
 
-  'mirroring.submit_instance': {
-    'real': '/falcon/entities/submit/{type}',
+  'mirroring.submit_entity': {
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/submit/{type}',
     'mock': '/data/mirroring/succeeded.json',
+    'apiPrefix': '',
     'type': 'POST',
     'format': function (data) {
       return {
         contentType: 'text/xml',
-        data: data.instance
+        dataType: 'xml',
+        data: data.entity,
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa',
+          'AmbariProxy-Content-Type': 'text/xml'
+        }
       }
     }
   },
 
-  'mirroring.update_instance': {
-    'real': '/falcon/entities/update/{type}/{name}',
+  'mirroring.update_entity': {
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/update/{type}/{name}',
     'mock': '/data/mirroring/succeeded.json',
+    'apiPrefix': '',
     'type': 'POST',
     'format': function (data) {
       return {
         contentType: 'text/xml',
-        data: data.instance
+        dataType: 'xml',
+        data: data.entity,
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa',
+          'AmbariProxy-Content-Type': 'text/xml'
+        }
       }
     }
   },
 
-  'mirroring.delete_instance': {
-    'real': '/falcon/entities/delete/{type}/{name}',
+  'mirroring.delete_entity': {
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/delete/{type}/{name}',
     'mock': '/data/mirroring/succeeded.json',
-    'type': 'DELETE'
+    'apiPrefix': '',
+    'type': 'DELETE',
+    'format': function (data) {
+      return {
+        dataType: 'xml',
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa'
+        }
+      }
+    }
+  },
+
+  'mirroring.suspend_entity': {
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/suspend/{type}/{name}',
+    'mock': '/data/mirroring/succeeded.json',
+    'apiPrefix': '',
+    'type': 'POST',
+    'format': function (data) {
+      return {
+        dataType: 'xml',
+        data: data.entity,
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa'
+        }
+      }
+    }
+  },
+
+  'mirroring.schedule_entity': {
+    'real': '/proxy?url=http://{falconServer}:15000/api/entities/resume/{type}/{name}',
+    'mock': '/data/mirroring/succeeded.json',
+    'apiPrefix': '',
+    'type': 'POST',
+    'format': function (data) {
+      return {
+        dataType: 'xml',
+        headers: {
+          'AmbariProxy-Remote-user': 'ambari-qa'
+        }
+      }
+    }
   },
 
   'bulk_request.host_components': {

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/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 d00105b..dd784a0 100644
--- a/ambari-web/app/views/main/mirroring/datasets_view.js
+++ b/ambari-web/app/views/main/mirroring/datasets_view.js
@@ -65,7 +65,7 @@ App.MainDatasetsView = App.TableView.extend({
   }),
 
   statusFilterView: filters.createSelectView({
-    fieldType: 'input-medium',
+    fieldType: 'input-small',
     column: 2,
     content: ['Any', 'Scheduled', 'Suspended', 'Running'],
     onClearValue: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/021b236b/ambari-web/app/views/main/mirroring/edit_dataset_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/mirroring/edit_dataset_view.js b/ambari-web/app/views/main/mirroring/edit_dataset_view.js
index f2f7bae..694922a 100644
--- a/ambari-web/app/views/main/mirroring/edit_dataset_view.js
+++ b/ambari-web/app/views/main/mirroring/edit_dataset_view.js
@@ -31,8 +31,9 @@ App.MainMirroringEditDataSetView = Em.View.extend({
     classNames: ['target-cluster-select'],
 
     content: function () {
-      return [App.get('clusterName'), Em.I18n.t('mirroring.dataset.addTargetCluster')]
-    }.property(),
+      if (!this.get('parentView.isLoaded')) return [];
+      return App.TargetCluster.find().mapProperty('name').without(App.get('clusterName')).concat(Em.I18n.t('mirroring.dataset.addTargetCluster'));
+    }.property('parentView.isLoaded'),
 
     change: function () {
       if (this.get('selection') === Em.I18n.t('mirroring.dataset.addTargetCluster')) {
@@ -51,11 +52,14 @@ App.MainMirroringEditDataSetView = Em.View.extend({
 
   minuteOptions: ['00', '05', '10', '15', '20', '25', '30', '35', '40', '45', '50', '55'],
 
+  isLoaded: function () {
+    return App.router.get('mainMirroringController.isLoaded');
+  }.property('App.router.mainMirroringController.isLoaded'),
+
   fillForm: function () {
     var isEdit = this.get('controller.isEdit');
-    var isLoaded = App.router.get('mainMirroringController.isLoaded');
     var selectedDataset = App.router.get('mainMirroringController.selectedDataset');
-    if (isLoaded && selectedDataset && isEdit) {
+    if (this.get('isLoaded') && selectedDataset && isEdit) {
       var dataset = App.Dataset.find().findProperty('name', selectedDataset.get('id'));
       var scheduleStartDate = dataset.get('scheduleStartDate');
       var scheduleEndDate = dataset.get('scheduleEndDate');
@@ -77,7 +81,7 @@ App.MainMirroringEditDataSetView = Em.View.extend({
       formFields.set('middayPeriodForStart', startHours > 12 || startHours === '00' ? 'PM' : 'AM');
       formFields.set('middayPeriodForEnd', endHours > 12 || endHours === '00' ? 'PM' : 'AM');
     }
-  }.observes('App.router.mainMirroringController.isLoaded', 'App.router.mainMirroringController.selectedDataset', 'controller.isEdit'),
+  }.observes('isLoaded', 'App.router.mainMirroringController.selectedDataset', 'controller.isEdit'),
 
   didInsertElement: function () {
     $('.datepicker').datepicker({