Browse Source

AMBARI-4602. Mirroring: Manage Clusters Dialog integration with API. (akovalenko)

Aleksandr Kovalenko 11 năm trước cách đây
mục cha
commit
776a39ebda
23 tập tin đã thay đổi với 411 bổ sung724 xóa
  1. 15 0
      ambari-web/app/assets/data/mirroring/cluster1_definition.xml
  2. 15 0
      ambari-web/app/assets/data/mirroring/cluster2_definition.xml
  3. 12 0
      ambari-web/app/assets/data/mirroring/clusters.json
  4. 0 0
      ambari-web/app/assets/data/mirroring/feeds.json
  5. 0 3
      ambari-web/app/controllers.js
  6. 147 2
      ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js
  7. 0 212
      ambari-web/app/controllers/main/mirroring/targetClusterController.js
  8. 0 155
      ambari-web/app/controllers/main/mirroring/testConnectionResults_controller.js
  9. 0 23
      ambari-web/app/controllers/main/mirroring/testConnection_controller.js
  10. 124 22
      ambari-web/app/controllers/main/mirroring_controller.js
  11. 8 31
      ambari-web/app/mappers/target_cluster_mapper.js
  12. 1 6
      ambari-web/app/messages.js
  13. 8 15
      ambari-web/app/models/target_cluster.js
  14. 6 6
      ambari-web/app/templates/main/mirroring/manage_clusters.hbs
  15. 0 57
      ambari-web/app/templates/main/mirroring/testConnection.hbs
  16. 0 74
      ambari-web/app/templates/main/mirroring/testConnectionResults.hbs
  17. 50 18
      ambari-web/app/utils/ajax.js
  18. 0 3
      ambari-web/app/views.js
  19. 24 8
      ambari-web/app/views/main/mirroring/manage_clusters_view.js
  20. 0 28
      ambari-web/app/views/main/mirroring/targetClusterView.js
  21. 0 33
      ambari-web/app/views/main/mirroring/testConnectionResults_view.js
  22. 0 27
      ambari-web/app/views/main/mirroring/testConnection_view.js
  23. 1 1
      ambari-web/app/views/main/mirroring_view.js

+ 15 - 0
ambari-web/app/assets/data/mirroring/cluster1_definition.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<cluster name="cluster1" description="" colo="default" xmlns="uri:falcon:cluster:0.1">
+    <interfaces>
+        <interface type="readonly" endpoint="hftp://c6401.ambari.apache.org:50070" version="2.2.0.2.0.6.0-76"/>
+        <interface type="write" endpoint="hdfs://c6401.ambari.apache.org:8020" version="2.2.0.2.0.6.0-76"/>
+        <interface type="execute" endpoint="c6401.ambari.apache.org:8050" version="2.2.0.2.0.6.0-76"/>
+        <interface type="workflow" endpoint="http://c6401.ambari.apache.org:11000/oozie" version="3.1.4"/>
+        <interface type="messaging" endpoint="tcp://c6401.ambari.apache.org:61616?daemon=true" version="5.1.6"/>
+    </interfaces>
+    <locations>
+        <location name="staging" path="/projects/falcon/staging"/>
+        <location name="temp" path="/tmp"/>
+        <location name="working" path="/projects/falcon/working"/>
+    </locations>
+</cluster>

+ 15 - 0
ambari-web/app/assets/data/mirroring/cluster2_definition.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<cluster name="cluster2" description="" colo="default" xmlns="uri:falcon:cluster:0.1">
+    <interfaces>
+        <interface type="readonly" endpoint="hftp://c6401.ambari.apache.org:50070" version="2.2.0.2.0.6.0-76"/>
+        <interface type="write" endpoint="hdfs://c6401.ambari.apache.org:8020" version="2.2.0.2.0.6.0-76"/>
+        <interface type="execute" endpoint="c6401.ambari.apache.org:8050" version="2.2.0.2.0.6.0-76"/>
+        <interface type="workflow" endpoint="http://c6401.ambari.apache.org:11000/oozie" version="3.1.4"/>
+        <interface type="messaging" endpoint="tcp://c6401.ambari.apache.org:61616?daemon=true" version="5.1.6"/>
+    </interfaces>
+    <locations>
+        <location name="staging" path="/projects/falcon/staging"/>
+        <location name="temp" path="/tmp"/>
+        <location name="working" path="/projects/falcon/working"/>
+    </locations>
+</cluster>

+ 12 - 0
ambari-web/app/assets/data/mirroring/clusters.json

@@ -0,0 +1,12 @@
+{
+  "entity": [
+    {
+      "name": "cluster1",
+      "type": "feed"
+    },
+    {
+      "name": "cluster2",
+      "type": "feed"
+    }
+  ]
+}

+ 0 - 0
ambari-web/app/assets/data/mirroring/datasets.json → ambari-web/app/assets/data/mirroring/feeds.json


+ 0 - 3
ambari-web/app/controllers.js

@@ -116,9 +116,6 @@ require('controllers/main/mirroring_controller');
 require('controllers/main/mirroring/edit_dataset_controller');
 require('controllers/main/mirroring/datasets_controller');
 require('controllers/main/mirroring/jobs_controller');
-require('controllers/main/mirroring/targetClusterController');
-require('controllers/main/mirroring/testConnection_controller');
-require('controllers/main/mirroring/testConnectionResults_controller');
 require('controllers/main/mirroring/manage_clusters_controller');
 require('controllers/wizard/slave_component_groups_controller');
 require('controllers/wizard/step0_controller');

+ 147 - 2
ambari-web/app/controllers/main/mirroring/manage_clusters_controller.js

@@ -21,15 +21,60 @@ var App = require('app');
 App.MainMirroringManageClustersController = Em.ArrayController.extend({
   name: 'mainMirroringManageClustersController',
 
+  // link to popup object
+  popup: null,
+
   clusters: [],
 
+  // array of original clusters to compare with changed ones
+  originalClusters: [],
+
+  queriesCount: 0,
+
+  // array of error messages
+  queryErrors: [],
+
+  isLoaded: function () {
+    return App.router.get('mainMirroringController.isLoaded');
+  }.property('App.router.mainMirroringController.isLoaded'),
+
+  onLoad: function () {
+    if (this.get('isLoaded')) {
+      var clusters = [];
+      var originalClusters = [];
+      App.TargetCluster.find().forEach(function (cluster) {
+        var newCluster = {
+          name: cluster.get('name'),
+          execute: cluster.get('execute'),
+          workflow: cluster.get('workflow'),
+          readonly: cluster.get('readonly'),
+          staging: cluster.get('staging'),
+          working: cluster.get('working'),
+          temp: cluster.get('temp')
+        };
+        clusters.push(Ember.Object.create(newCluster));
+        originalClusters.push(Ember.Object.create(newCluster));
+      }, this);
+      this.set('clusters', clusters);
+      this.set('originalClusters', originalClusters);
+    }
+  }.observes('isLoaded'),
+
   selectedCluster: null,
 
   addCluster: function () {
     var self = this;
     App.showPromptPopup(Em.I18n.t('mirroring.manageClusters.specifyName'),
         function (clusterName) {
-          self.get('clusters').pushObject(clusterName);
+          self.get('clusters').pushObject(Ember.Object.create({
+            name: clusterName,
+            execute: '',
+            workflow: '',
+            readonly: '',
+            staging: '',
+            working: '',
+            temp: ''
+          }));
         }
     );
   },
@@ -38,6 +83,106 @@ App.MainMirroringManageClustersController = Em.ArrayController.extend({
     var self = this;
     App.showConfirmationPopup(function () {
       self.set('clusters', self.get('clusters').without(self.get('selectedCluster')));
-    })
+    });
+  },
+
+  save: function () {
+    // define clusters need to be deleted, modified or created
+    var clusters = this.get('clusters');
+    var originalClusters = this.get('originalClusters');
+    var originalClustersNames = originalClusters.mapProperty('name');
+    var clustersToModify = [];
+    var clustersToCreate = [];
+    clusters.forEach(function (cluster) {
+      var clusterName = cluster.get('name');
+      if (originalClustersNames.contains(clusterName)) {
+        if (JSON.stringify(cluster) !== JSON.stringify(originalClusters.findProperty('name', clusterName))) {
+          clustersToModify.push(clusterName);
+        }
+        originalClustersNames = originalClustersNames.without(clusterName);
+      } else {
+        clustersToCreate.push(clusterName);
+      }
+    }, this);
+    var clustersToDelete = originalClustersNames;
+    var queriesCount = clustersToCreate.length + clustersToDelete.length + clustersToModify.length;
+    this.set('queriesCount', queriesCount);
+
+    // send request to delete, modify or create cluster
+    if (queriesCount) {
+      this.get('queryErrors').clear();
+      clustersToDelete.forEach(function (cluster) {
+        App.ajax.send({
+          name: 'mirroring.delete_instance',
+          sender: this,
+          data: {
+            name: cluster,
+            type: 'cluster'
+          },
+          success: 'onQueryResponse',
+          error: 'onQueryResponse'
+        });
+      }, this);
+      clustersToCreate.forEach(function (cluster) {
+        App.ajax.send({
+          name: 'mirroring.submit_instance',
+          sender: this,
+          data: {
+            type: 'cluster',
+            instance: this.formatClusterXML(clusters.findProperty('name', cluster))
+          },
+          success: 'onQueryResponse',
+          error: 'onQueryResponse'
+        });
+      }, this);
+      clustersToModify.forEach(function (cluster) {
+        App.ajax.send({
+          name: 'mirroring.update_instance',
+          sender: this,
+          data: {
+            name: cluster,
+            type: 'cluster',
+            instance: this.formatClusterXML(clusters.findProperty('name', cluster))
+          },
+          success: 'onQueryResponse',
+          error: 'onQueryResponse'
+        });
+      }, this);
+    } else {
+      this.get('popup').hide();
+    }
+  },
+
+  // close popup after getting response from all queries or show popup with errors
+  onQueryResponse: function () {
+    var queryErrors = this.get('queryErrors');
+    if (arguments.length === 4) {
+      queryErrors.push(arguments[2]);
+    }
+    var queriesCount = this.get('queriesCount');
+    this.set('queriesCount', --queriesCount);
+    if (queriesCount < 1) {
+      if (queryErrors.length) {
+        App.showAlertPopup(Em.I18n.t('common.error'), Em.I18n.t('mirroring.manageClusters.error') + ': ' + queryErrors.join(', '));
+      } else {
+        this.get('popup').hide();
+      }
+    }
+  },
+
+  /**
+   * Return XML-formatted string made from cluster object
+   * @param {Object} cluster - object with cluster data
+   * @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') +
+        '" /><location name="temp" path="' + cluster.get('temp') +
+        '" /><location name="working" path="' + cluster.get('working') +
+        '" /></locations></cluster>';
   }
 });

+ 0 - 212
ambari-web/app/controllers/main/mirroring/targetClusterController.js

@@ -1,212 +0,0 @@
-/**
- * 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.MainMirroringTargetClusterController = Ember.Controller.extend({
-  name: 'mainMirroringTargetClusterController',
-  model: Ember.Object.create({
-    targetCluster: null,
-    originalRecord: null,
-    isPopupForEdit: false, // set the default to add scenario
-    isNameNodeWebUrlError: function (key, value) {
-      if (value) {
-        return value;
-      }
-      var controller = App.router.get('mainMirroringTargetClusterController');
-      return controller.checkNameNodeWebUrlErrors();
-    }.property('targetCluster.nameNodeWebUrl', 'model.targetCluster.nameNodeWebUrl'),
-    isNameNodeRpcUrlError: function (key, value) {
-      if (value) {
-        return value;
-      }
-      var controller = App.router.get('mainMirroringTargetClusterController');
-      return controller.checkNameNodeRpcUrlErrors();
-    }.property('targetCluster.nameNodeRpcUrl', 'model.targetCluster.nameNodeRpcUrl'),
-
-    isOozieServerUrlError: function (key, value) {
-      if (value) {
-        return value;
-      }
-      var controller = App.router.get('mainMirroringTargetClusterController');
-      return controller.checkOozieServerUrlErrors();
-    }.property('targetCluster.oozieServerUrl', 'model.targetCluster.oozieServerUrl'),
-
-    isClusterNameError: function (key, value) {
-      if (value) {
-        return value;
-      }
-      var controller = App.router.get('mainMirroringTargetClusterController');
-      return controller.checkClusterNameErrors();
-    }.property('targetCluster.clusterName', 'model.targetCluster.clusterName'),
-
-    nameNodeWebUrlErrorMessage: null,
-    nameNodeRpcUrlErrorMessage: null,
-    oozieServerUrlErrorMessage: null,
-    clusterNameErrorMessage: null
-  }),
-
-  isSubmitted1: null,
-  isSubmitted2: null,
-
-  validate1: function () {
-    var isNameNodeWebUrlError = this.checkNameNodeWebUrlErrors();
-    var isNameNodeRpcUrlError = this.checkNameNodeRpcUrlErrors();
-    var isOozieServerUrlError = this.checkOozieServerUrlErrors();
-
-    return !(isNameNodeWebUrlError || isNameNodeRpcUrlError || isOozieServerUrlError);
-  },
-
-  validate2: function () {
-    return !this.checkClusterNameErrors();
-  },
-
-  checkNameNodeWebUrlErrors: function () {
-    if (!this.get('isSubmitted1')){
-      this.set('model.nameNodeWebUrlErrorMessage', "");
-      return false;
-    }
-    var nameNodeWebUrl = this.get('model.targetCluster.nameNodeWebUrl');
-    if (!nameNodeWebUrl || nameNodeWebUrl.trim() === "") {
-      this.set('model.isNameNodeWebUrlError', true);
-      this.set('model.nameNodeWebUrlErrorMessage', Em.I18n.t('mirroring.required.error'));
-      return true;
-    }
-    else {
-      this.set('model.nameNodeWebUrlErrorMessage', "");
-      return false;
-    }
-
-  },
-
-  checkNameNodeRpcUrlErrors: function () {
-    if (!this.get('isSubmitted1')){
-      this.set('model.nameNodeRpcUrlErrorMessage', "");
-      return false;
-    }
-    var nameNodeRpcUrl = this.get('model.targetCluster.nameNodeRpcUrl');
-    if (!nameNodeRpcUrl || nameNodeRpcUrl.trim() === "") {
-      this.set('model.isNameNodeRpcUrlError', true);
-      this.set('model.nameNodeRpcUrlErrorMessage', Em.I18n.t('mirroring.required.error'));
-      return true;
-    }
-    else {
-      this.set('model.nameNodeRpcUrlErrorMessage', "");
-      return false;
-    }
-
-  },
-
-  checkOozieServerUrlErrors: function () {
-    if (!this.get('isSubmitted1')){
-      this.set('model.oozieServerUrlErrorMessage', "");
-      return false;
-    }
-    var oozieServerUrl = this.get('model.targetCluster.oozieServerUrl');
-    if (!oozieServerUrl || oozieServerUrl.trim() === "") {
-      this.set('model.isOozieServerUrlError', true);
-      this.set('model.oozieServerUrlErrorMessage', Em.I18n.t('mirroring.required.error'));
-      return true;
-    }
-    else {
-      this.set('model.oozieServerUrlErrorMessage', "");
-      return false;
-    }
-
-  },
-
-  checkClusterNameErrors: function () {
-    if (!this.get('isSubmitted1')){
-      this.set('model.clusterNameErrorMessage', "");
-      return false;
-    }
-    var clusterName = this.get('model.targetCluster.clusterName');
-    if (!clusterName || clusterName.trim() === "") {
-      this.set('model.isClusterNameError', true);
-      this.set('model.clusterNameErrorMessage', Em.I18n.t('mirroring.required.error'));
-      return true;
-    }
-    else {
-      this.set('model.clusterNameErrorMessage', "");
-      return false;
-    }
-
-  },
-
-  setOriginalRecord: function (targetClusterRecord) {
-    this.set('model.originalRecord', targetClusterRecord);
-  },
-
-  setTargetCluster: function (targetClusterRecord) {
-    var targetCluster = Ember.Object.create({
-      id: targetClusterRecord.get('id'),
-      clusterName: targetClusterRecord.get('clusterName'),
-      nameNodeWebUrl: targetClusterRecord.get('nameNodeWebUrl'),
-      nameNodeRpcUrl: targetClusterRecord.get('nameNodeRpcUrl'),
-      oozieServerUrl: targetClusterRecord.get('oozieServerUrl')
-    });
-
-    this.set('model.targetCluster', targetCluster);
-  },
-
-
-  createTargetCluster: function () {
-    var targetCluster = Ember.Object.create({
-      clusterName: null,
-      nameNodeWebUrl: null,
-      nameNodeRpcUrl: null,
-      oozieServerUrl: null
-    });
-    this.set('model.targetCluster', targetCluster);
-    return targetCluster;
-
-    /* For future (but on record objects , not on pojos):
-     targetCluster.on('didUpdate', function() {
-     console.log("------Updated!");
-     });
-     targetCluster.on('didDelete', function() {
-     console.log("------Deleted!");
-     });
-     targetCluster.on('didCreate', function() {
-     console.log("------Created!");
-     });
-     */
-
-  },
-  getTargetCluster: function () {
-    return this.get('content.targetCluster');
-  },
-
-  popup: null,
-
-  /**
-   * "Delete" button handler.
-   * A DataSet
-   */
-  deleteTargetCluster: function () {
-    var self = this;
-    App.showConfirmationPopup(function () {
-      var originalRecord = self.get('model.originalRecord');
-      originalRecord.deleteRecord();
-      originalRecord.get("transaction").commit();
-      self.get('popup').hide();
-      App.router.transitionTo('main.mirroring.index');
-    });
-  }
-
-
-
-});

+ 0 - 155
ambari-web/app/controllers/main/mirroring/testConnectionResults_controller.js

@@ -1,155 +0,0 @@
-/**
- * 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.TestConnectionResultsController = Ember.Controller.extend({
-  name: 'testConnectionResultsController',
-
-  connectStatuses: [
-    Ember.Object.create({
-      type: 'readonly',
-      isConnectionSuccess: false
-    }),
-    Ember.Object.create({
-      type: 'write',
-      isConnectionSuccess: false
-    }),
-    Ember.Object.create({
-      type: 'workflow',
-      isConnectionSuccess: false
-    })
-
-  ],
-
-  isNameNodeWebUIConnected: function () {
-    var connectStatus = this.get('connectStatuses').findProperty('type', 'readonly');
-    return connectStatus.get('isConnectionSuccess');
-  }.property('connectStatuses.@each.isConnectionSuccess'),
-
-  isNameNodeRpcConnected: function () {
-    var connectStatus = this.get('connectStatuses').findProperty('type', 'write');
-    return connectStatus.get('isConnectionSuccess');
-  }.property('connectStatuses.@each.isConnectionSuccess'),
-
-  isOozieServerConnected: function () {
-    var connectStatus = this.get('connectStatuses').findProperty('type', 'workflow');
-    return connectStatus.get('isConnectionSuccess');
-  }.property('connectStatuses.@each.isConnectionSuccess'),
-
-  isConnectionSuccessful: function () {
-    return this.get('isNameNodeWebUIConnected') && this.get('isNameNodeRpcConnected') && this.get('isOozieServerConnected');
-  }.property('isNameNodeWebUIConnected', 'isNameNodeRpcConnected', 'isOozieServerConnected'),
-
-  shouldBeDisabled: function () {
-    return !this.get('isConnectionSuccessful');
-  }.property('isConnectionSuccessful'),
-
-  mockDataPrefix: '/data/mirroring/poll/',
-
-  tryConnecting: function () {
-    var types = ["readonly", "write", "workflow"];
-    var arrayOfPollData = ["testConnection_poll1", "testConnection_poll2", "testConnection_poll3", "testConnection_poll4"];
-
-    var shouldContinuePolling = true;
-
-    var poll_count = 0;
-
-    var interval_id = 0;
-
-    var self = this;
-
-    var connect = function () {
-      var method = 'GET';
-      console.debug('poll_count : ' + poll_count);
-      var url = self.get('mockDataPrefix') + arrayOfPollData[poll_count++] + ".json";
-      $.ajax({
-        type: method,
-        url: url,
-        async: true, // shd be chnaged to true
-        data: null, // temporarily .this depends upon what the api is expecting.
-        dataType: 'text',
-        timeout: App.timeout,
-        success: function (data) {
-          var jsonData = jQuery.parseJSON(data);
-          var connectStatuses = self.get('connectStatuses');
-          jsonData.tasks.forEach(function (task) {
-            var type = task.Tasks.type;
-            var status = task.Tasks.status;
-            var connectStatus = connectStatuses.findProperty("type", type);
-            connectStatus.set('isConnectionSuccess', status === "SUCCESS");
-          });
-
-          var totalNum = connectStatuses.length;
-          var succeededStatuses = connectStatuses.filterProperty("isConnectionSuccess", true);
-          var succeededNum = succeededStatuses.length;
-
-          if (totalNum == succeededNum) {
-            clearInterval(interval_id);
-            console.debug('Cleared function id ' + interval_id);
-          }
-          else {
-            clearInterval(interval_id);
-            console.debug('Cleared function id ' + interval_id + "totalNum : " + totalNum + ', succeededNum : ' + succeededNum);
-            interval_id = setInterval(connect, 100);
-            console.debug('Generated function id ' + interval_id);
-          }
-
-        }
-      });
-    };
-
-    connect();
-  },
-
-  saveClusterName: function () {
-    var targetCluster = this.get('content.targetCluster');
-    var isEditing = this.get('content.isPopupForEdit');
-    if (isEditing) {
-      var targetClusterRecord = this.get('content.originalRecord');
-      var targetClusterEdited = this.get('content.targetCluster');
-
-      targetClusterRecord.set('id', targetClusterEdited.get('id'));
-      targetClusterRecord.set('clusterName', targetClusterEdited.get('clusterName'));
-      targetClusterRecord.set('nameNodeWebUrl', targetClusterEdited.get('nameNodeRpcUrl'));
-      targetClusterRecord.set('nameNodeRpcUrl', targetClusterEdited.get('id'));
-      targetClusterRecord.set('oozieServerUrl', targetClusterEdited.get('oozieServerUrl'));
-
-
-    } else {
-      var targetClusterRecord = App.TargetCluster.createRecord(targetCluster);
-
-      // refresh main page model
-      var mainMirroringController = App.router.get('mainMirroringController');
-      mainMirroringController.notifyPropertyChange("targetClusters");
-
-      // refresh add/edit dataset model
-      var addDataSetController = App.router.get('mainMirroringEditDataSetController');
-      var dataSet = addDataSetController.get('model.newDataSet');
-      if (dataSet)  // this may be undefined or null if we try to add cluster from main page. Hence the if check.
-        dataSet.set('targetCluster', targetClusterRecord);
-    }
-
-    var popup = this.get('controllers.mainMirroringTargetClusterController.popup');
-    popup.hide();
-  }
-
-
-
-
-
-
-});

+ 0 - 23
ambari-web/app/controllers/main/mirroring/testConnection_controller.js

@@ -1,23 +0,0 @@
-/**
- * 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.TestConnectionController = Ember.Controller.extend({
-  name:'testConnectionController'
-
-
-});

+ 124 - 22
ambari-web/app/controllers/main/mirroring_controller.js

@@ -24,20 +24,44 @@ App.MainMirroringController = Em.ArrayController.extend({
 
   datasetsData: [],
 
+  // formatted data for targetClusterMapper
+  clustersData: {},
+
+  // counter for datasets load queries
   datasetCount: 0,
 
+  // counter for target cluster load queries
+  clusterCount: 0,
+
   datasets: [],
 
-  isLoaded: false,
+  isDatasetsLoaded: false,
 
-  loadDatasets: function () {
-    this.set('isLoaded', false);
+  isTargetClustersLoaded: false,
+
+  isLoaded: function () {
+    return this.get('isDatasetsLoaded') && this.get('isTargetClustersLoaded');
+  }.property('isDatasetsLoaded', 'isTargetClustersLoaded'),
+
+  loadData: function () {
+    this.set('isDatasetsLoaded', false);
+    this.set('isTargetClustersLoaded', false);
     this.get('datasetsData').clear();
+    this.set('clustersData', {});
     this.set('datasetCount', 0);
+    this.set('clusterCount', 0);
     this.set('datasets', []);
+    this.loadDatasets();
+    this.loadClusters();
+  },
+
+  loadDatasets: function () {
     App.ajax.send({
-      name: 'mirroring.get_all_datasets',
+      name: 'mirroring.get_all_entities',
       sender: this,
+      data: {
+        type: 'feed'
+      },
       success: 'onLoadDatasetsListSuccess',
       error: 'onLoadDatasetsListError'
     });
@@ -48,10 +72,11 @@ App.MainMirroringController = Em.ArrayController.extend({
       this.set('datasetCount', data.entity.length);
       data.entity.mapProperty('name').forEach(function (dataset) {
         App.ajax.send({
-          name: 'mirroring.get_dataset_definition',
+          name: 'mirroring.get_definition',
           sender: this,
           data: {
-            dataset: dataset
+            name: dataset,
+            type: 'feed'
           },
           success: 'onLoadDatasetDefinitionSuccess',
           error: 'onLoadDatasetDefinitionError'
@@ -109,6 +134,7 @@ 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,
@@ -118,26 +144,22 @@ App.MainMirroringController = Em.ArrayController.extend({
         startTime: new Date(instance.startTime).getTime()
       });
     }, this);
-    this.get('datasetsData').findProperty('name', opts.dataset).set('instances', datasetJobs);
+    datasetsData.findProperty('name', opts.dataset).set('instances', datasetJobs);
     this.set('datasetCount', this.get('datasetCount') - 1);
     var sortedDatasets = [];
     if (this.get('datasetCount') < 1) {
-      App.dataSetMapper.map(this.get('datasetsData'));
+      App.dataSetMapper.map(datasetsData);
       sortedDatasets = App.Dataset.find().toArray().sort(function (a, b) {
         if (a.get('name') < b.get('name'))  return -1;
         if (a.get('name') > b.get('name'))  return 1;
         return 0;
       });
       this.set('datasets', sortedDatasets);
-      this.set('isLoaded', true);
+      this.set('isDatasetsLoaded', true);
       var selectedDataset = this.get('selectedDataset');
       if (!selectedDataset) {
         this.set('selectedDataset', sortedDatasets[0]);
       }
-      var routerState = App.router.get('currentState.name');
-      if (routerState === 'index') {
-        App.router.send('gotoShowJobs');
-      }
     }
   },
 
@@ -145,30 +167,110 @@ App.MainMirroringController = Em.ArrayController.extend({
     console.error('Failed to load dataset instances.');
   },
 
-  targetClusters: function () {
-    return App.TargetCluster.find();
-  }.property(),
+  loadClusters: function () {
+    App.ajax.send({
+      name: 'mirroring.get_all_entities',
+      sender: this,
+      data: {
+        type: 'cluster'
+      },
+      success: 'onLoadClustersListSuccess',
+      error: 'onLoadClustersListError'
+    });
+  },
+
+  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) {
+        App.ajax.send({
+          name: 'mirroring.get_definition',
+          sender: this,
+          data: {
+            name: cluster,
+            type: 'cluster'
+          },
+          success: 'onLoadClusterDefinitionSuccess',
+          error: 'onLoadClusterDefinitionError'
+        });
+      }, this);
+    } else {
+      this.onLoadClustersListError();
+    }
+  },
+
+  onLoadClustersListError: function () {
+    console.error('Failed to load clusters list.');
+  },
+
+  onLoadClusterDefinitionSuccess: function (data) {
+    var parsedData = misc.xmlToObject(data);
+    var clustersData = this.get('clustersData');
+    var interfaces = parsedData.cluster.interfaces.interface;
+    var locations = parsedData.cluster.locations.location;
+    var staging = locations.findProperty('@attributes.name', 'staging');
+    var working = locations.findProperty('@attributes.name', 'working');
+    var temp = locations.findProperty('@attributes.name', 'temp');
+    clustersData.items.push(
+        {
+          name: parsedData.cluster['@attributes'].name,
+          execute: interfaces.findProperty('@attributes.type', 'execute')['@attributes'].endpoint,
+          readonly: interfaces.findProperty('@attributes.type', 'readonly')['@attributes'].endpoint,
+          workflow: interfaces.findProperty('@attributes.type', 'workflow')['@attributes'].endpoint,
+          staging: staging && staging['@attributes'].path,
+          working: working && working['@attributes'].path,
+          temp: temp && temp['@attributes'].path
+        }
+    );
+    this.set('clusterCount', this.get('clusterCount') - 1);
+    if (this.get('clusterCount') < 1) {
+      App.targetClusterMapper.map(clustersData);
+      this.set('isTargetClustersLoaded', true);
+    }
+  },
+
+  onLoadClusterDefinitionError: function () {
+    console.error('Failed to load cluster definition.');
+  },
+
+  onDataLoad: function () {
+    if (this.get('isLoaded') && App.router.get('currentState.name') === 'index') {
+      App.router.send('gotoShowJobs');
+    }
+  }.observes('isLoaded'),
 
   manageClusters: function () {
-    App.ModalPopup.show({
+    var manageClustersController = App.router.get('mainMirroringManageClustersController');
+    var popup = App.ModalPopup.show({
       header: Em.I18n.t('mirroring.dataset.manageClusters'),
       bodyClass: App.MainMirroringManageClusterstView.extend({
-        controllerBinding: 'App.router.mainMirroringManageClustersController'
+        controller: manageClustersController
       }),
       primary: Em.I18n.t('common.save'),
       secondary: null,
       onPrimary: function () {
-        this.hide();
-        App.router.send('gotoShowJobs');
+        manageClustersController.save();
       },
-      onClose: function () {
-        this.hide();
+      hide: function () {
         App.router.send('gotoShowJobs');
+        this._super();
       },
       didInsertElement: function () {
         this._super();
         this.fitHeight();
       }
     });
+    manageClustersController.set('popup', popup);
   }
 });

+ 8 - 31
ambari-web/app/mappers/target_cluster_mapper.js

@@ -20,36 +20,13 @@
 App.targetClusterMapper = App.QuickDataMapper.create({
   model: App.TargetCluster,
   config: {
-    id: 'id',
-    cluster_name: 'Clusters.name',
-    name_node_web_url: 'name_node_web_url',
-    name_node_rpc_url: 'name_node_rpc_url',
-    oozie_server_url: 'oozie_server_url'
-  },
-  map: function (json) {
-    if (!this.get('model')) {
-      return;
-    }
-    if (json && json.items && json.items.length > 0) {
-      var target_cluster_results = [];
-      json.items.forEach(function (item) {
-        try {
-          item.name_node_web_url = (item.Clusters.interfaces.interface.findProperty("type", "readonly")).endpoint;
-          item.name_node_rpc_url = (item.Clusters.interfaces.interface.findProperty("type", "write")).endpoint;
-          item.oozie_server_url = (item.Clusters.interfaces.interface.findProperty("type","workflow")).endpoint;
-          item.id = item.Clusters.name;
-
-          var re = new RegExp(" ", "g");
-          item.id = item.id.replace(re, "_");
-
-
-          item = this.parseIt(item, this.config);
-          target_cluster_results.push(item);
-        } catch (ex) {
-          console.error('Exception occurred: ' + ex);
-        }
-      }, this);
-      App.store.loadMany(this.get('model'), target_cluster_results);
-    }
+    id: 'name',
+    name: 'name',
+    execute: 'execute',
+    workflow: 'workflow',
+    readonly: 'readonly',
+    staging: 'staging',
+    working: 'working',
+    temp: 'temp'
   }
 });

+ 1 - 6
ambari-web/app/messages.js

@@ -1798,12 +1798,7 @@ Em.I18n.translations = {
   'mirroring.manageClusters.staging':'Staging',
   'mirroring.manageClusters.working':'Working',
   'mirroring.manageClusters.temp':'Temp',
-
-  'mirroring.targetcluster.nameNodeWebUrl':'NameNode Web UI',
-  'mirroring.targetcluster.nameNodeRpcUrl':'NameNode RPC',
-  'mirroring.targetcluster.oozieServerUrl':'Oozie Server',
-  'mirroring.targetcluster.addCluster':'Add Cluster',
-  'mirroring.targetcluster.enterClusterName':'Name of the Target Cluster',
+  'mirroring.manageClusters.error' :'Error in saving changes',
 
   'mirroring.table.noDatasets':'No datasets to display',
   'mirroring.table.datasetStatus':'Status',

+ 8 - 15
ambari-web/app/models/target_cluster.js

@@ -20,20 +20,13 @@
 var App = require('app');
 
 App.TargetCluster = DS.Model.extend({
-  id: DS.attr('string'),
-  clusterName: DS.attr('string'),
-  nameNodeWebUrl: DS.attr('string'),
-  nameNodeRpcUrl: DS.attr('string'),
-  oozieServerUrl: DS.attr('string')
+  name: DS.attr('string'),
+  execute: DS.attr('string'),
+  workflow: DS.attr('string'),
+  readonly: DS.attr('string'),
+  staging: DS.attr('string'),
+  working: DS.attr('string'),
+  temp: DS.attr('string')
 });
 
-App.TargetCluster.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.TargetCluster.FIXTURES = [];

+ 6 - 6
ambari-web/app/templates/main/mirroring/manage_clusters.hbs

@@ -30,15 +30,15 @@
           <div style="margin-bottom: 15px">{{t mirroring.manageClusters.interfaces}}</div>
           <div class="control-group">
             <label class="control-label-manage-clusters">{{t mirroring.manageClusters.execute}}</label>
-            {{view Ember.TextField class="span8"}}
+            {{view Ember.TextField class="span8" valueBinding="controller.selectedCluster.execute"}}
           </div>
           <div class="control-group">
             <label class="control-label-manage-clusters">{{t mirroring.manageClusters.readonly}}</label>
-            {{view Ember.TextField class="span8"}}
+            {{view Ember.TextField class="span8" valueBinding="controller.selectedCluster.readonly"}}
           </div>
           <div class="control-group">
             <label class="control-label-manage-clusters">{{t mirroring.manageClusters.workflow}}</label>
-            {{view Ember.TextField class="span8"}}
+            {{view Ember.TextField class="span8" valueBinding="controller.selectedCluster.workflow"}}
           </div>
         </div>
         <div class="accordion control-group" id="advanced-fields">
@@ -52,15 +52,15 @@
               <div class="accordion-inner">
                 <div class="control-group">
                   <label class="control-label-manage-clusters">{{t mirroring.manageClusters.staging}}</label>
-                  {{view Ember.TextField class="span8"}}
+                  {{view Ember.TextField class="span8" valueBinding="controller.selectedCluster.staging"}}
                 </div>
                 <div class="control-group">
                   <label class="control-label-manage-clusters">{{t mirroring.manageClusters.working}}</label>
-                  {{view Ember.TextField class="span8"}}
+                  {{view Ember.TextField class="span8" valueBinding="controller.selectedCluster.working"}}
                 </div>
                 <div class="control-group">
                   <label class="control-label-manage-clusters">{{t mirroring.manageClusters.temp}}</label>
-                  {{view Ember.TextField class="span8"}}
+                  {{view Ember.TextField class="span8" valueBinding="controller.selectedCluster.temp"}}
                 </div>
               </div>
             </div>

+ 0 - 57
ambari-web/app/templates/main/mirroring/testConnection.hbs

@@ -1,57 +0,0 @@
-{{!
-* 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.
-}}
-
-<form class="form-horizontal" autocomplete="off">
-    <div class="add-cluster-1">
-        <div class="add-cluster-1-1">
-            <h4>Enter the URLs for the following</h4>
-
-            <div {{bindAttr class=" :each-row content.isNameNodeWebUrlError:error"}}>
-              {{t mirroring.targetcluster.nameNodeWebUrl}}
-            </div>
-            <div {{bindAttr class=" :each-row content.isNameNodeWebUrlError:error"}}>
-              {{view Ember.TextField valueBinding="content.targetCluster.nameNodeWebUrl" class="span4" placeholder="http://[NameNode Web UI Server]:50070"}}
-                <span class="help-inline">{{content.nameNodeWebUrlErrorMessage}}</span>
-            </div>
-
-            <div {{bindAttr class=" :each-row content.isNameNodeRpcUrlError:error"}}>
-              {{t mirroring.targetcluster.nameNodeRpcUrl}}
-            </div>
-            <div {{bindAttr class=" :each-row content.isNameNodeRpcUrlError:error"}}>
-              {{view Ember.TextField valueBinding="content.targetCluster.nameNodeRpcUrl" class="span4" placeholder="http://[NameNode RPC Server]:8020"}}
-                <span class="help-inline">{{content.nameNodeRpcUrlErrorMessage}}</span>
-            </div>
-            <div {{bindAttr class=" :each-row content.isOozieServerUrlError:error"}}>
-              {{t mirroring.targetcluster.oozieServerUrl}}
-            </div>
-            <div {{bindAttr class=" :each-row content.isOozieServerUrlError:error"}}>
-              {{view Ember.TextField valueBinding="content.targetCluster.oozieServerUrl" class="span4" placeholder="http://[Oozie server]:11000"}}
-                <span class="help-inline">{{content.oozieServerUrlErrorMessage}}</span>
-            </div>
-        </div>
-      {{#if view.parentView.parentView.controller.model.isPopupForEdit}}
-          <div class="add-cluster-1-3">
-              <div class="each-row pull-right">
-                  <a {{action deleteTargetCluster target="view.parentView.parentView.controller"}}
-                          class="btn btn-danger">{{t common.delete}}</a>
-              </div>
-          </div>
-      {{/if}}
-
-    </div>
-</form>

+ 0 - 74
ambari-web/app/templates/main/mirroring/testConnectionResults.hbs

@@ -1,74 +0,0 @@
-{{!
-* 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.
-}}
-
-<form class="form-horizontal" autocomplete="off">
-    <div class="add-cluster-2">
-
-        <table>
-            <tr>
-                <td>NameNode Web UI..50070</td>
-                <td>
-                  {{#if isNameNodeWebUIConnected}}
-                      <i class="icon-ok"></i>
-                  {{else}}
-                      Connecting...
-                  {{/if}}
-                </td>
-            </tr>
-            <tr class="spacer">
-                <td colspan="2"></td>
-            </tr>
-            <tr>
-                <td>NameNode RPC..8020</td>
-                <td>
-                  {{#if isNameNodeRpcConnected}}
-                      <i class="icon-ok"></i>
-                  {{else}}
-                      Connecting...
-                  {{/if}}
-                </td>
-            </tr>
-            <tr class="spacer">
-                <td colspan="2"></td>
-            </tr>
-            <tr>
-                <td>Oozie server..11000</td>
-                <td>
-                  {{#if isOozieServerConnected}}
-                      <i class="icon-ok"></i>
-                  {{else}}
-                      Connecting...
-                  {{/if}}
-                </td>
-            </tr>
-            <tr class="spacer">
-                <td colspan="2"></td>
-            </tr>
-            <tr {{bindAttr class="content.isClusterNameError:error"}}>
-                <td>{{t mirroring.targetcluster.enterClusterName}}</td>
-                <td>{{view Ember.TextField valueBinding="content.targetCluster.clusterName" disabledBinding="shouldBeDisabled" }}
-                    <span class="help-inline">{{content.clusterNameErrorMessage}}</span>
-                </td>
-            </tr>
-            <tr class="spacer">
-                <td colspan="2"></td>
-            </tr>
-        </table>
-    </div>
-
-</form>

+ 50 - 18
ambari-web/app/utils/ajax.js

@@ -1438,14 +1438,14 @@ var urls = {
     }
   },
 
-  'mirroring.get_all_datasets': {
-    'real': 'falcon/entities/list/feed',
-    'mock': '/data/mirroring/datasets.json'
+  'mirroring.get_all_entities': {
+    'real': '/falcon/entities/list/{type}',
+    'mock': '/data/mirroring/{type}s.json'
   },
 
-  'mirroring.get_dataset_definition': {
-    'real': 'falcon/entities/definition/feed/{dataset}',
-    'mock': '/data/mirroring/{dataset}_definition.xml',
+  'mirroring.get_definition': {
+    'real': '/falcon/entities/definition/{type}/{name}',
+    'mock': '/data/mirroring/{name}_definition.xml',
     'format': function () {
       return {
         dataType: 'xml'
@@ -1454,10 +1454,53 @@ var urls = {
   },
 
   'mirroring.dataset.get_all_instances': {
-    'real': 'falcon/instance/status/feed/{dataset}',
+    'real': '/falcon/instance/status/feed/{dataset}',
     'mock': '/data/mirroring/{dataset}_instances.json'
   },
 
+
+  'mirroring.create_new_dataset': {
+    'real': '/falcon/entities/submitAndSchedule/feed',
+    'mock': '/data/mirroring/succeeded.json',
+    'type': 'POST',
+    'format': function (data) {
+      return {
+        contentType: 'text/xml',
+        data: data.dataset
+      }
+    }
+  },
+
+  'mirroring.submit_instance': {
+    'real': '/falcon/entities/submit/{type}',
+    'mock': '/data/mirroring/succeeded.json',
+    'type': 'POST',
+    'format': function (data) {
+      return {
+        contentType: 'text/xml',
+        data: data.instance
+      }
+    }
+  },
+
+  'mirroring.update_instance': {
+    'real': '/falcon/entities/update/{type}/{name}',
+    'mock': '/data/mirroring/succeeded.json',
+    'type': 'POST',
+    'format': function (data) {
+      return {
+        contentType: 'text/xml',
+        data: data.instance
+      }
+    }
+  },
+
+  'mirroring.delete_instance': {
+    'real': '/falcon/entities/delete/{type}/{name}',
+    'mock': '/data/mirroring/succeeded.json',
+    'type': 'DELETE'
+  },
+
   'bulk_request.host_components': {
     'real': '/clusters/{clusterName}/host_components',
     'mock': '',
@@ -1561,17 +1604,6 @@ var urls = {
     }
   },
 
-  'mirroring.create_new_dataset': {
-    'real': '/falcon/entities/submitAndSchedule/feed',
-    'mock': '/data/mirroring/succeeded.json',
-    'type': 'POST',
-    'format': function (data) {
-      return {
-        contentType: 'text/xml',
-        data: data.dataset
-      }
-    }
-  },
   'jobs.tezDag.NametoID': {
     'real': '/proxy?url=http://{historyServerHostName}:8188/ws/v1/apptimeline/TEZ_DAG_ID?primaryFilter=dagName:{tezDagName}',
     'mock': '/data/jobs/tezDag-name-to-id.json'

+ 0 - 3
ambari-web/app/views.js

@@ -224,9 +224,6 @@ require('views/main/mirroring_view');
 require('views/main/mirroring/edit_dataset_view');
 require('views/main/mirroring/datasets_view');
 require('views/main/mirroring/jobs_view');
-require('views/main/mirroring/targetClusterView');
-require('views/main/mirroring/testConnection_view');
-require('views/main/mirroring/testConnectionResults_view');
 require('views/main/mirroring/manage_clusters_view');
 require('views/installer');
 require('views/wizard/controls_view');

+ 24 - 8
ambari-web/app/views/main/mirroring/manage_clusters_view.js

@@ -26,10 +26,10 @@ App.MainMirroringManageClusterstView = Em.View.extend({
     classNames: ['cluster-select'],
     multiple: true,
     content: function () {
-      var clusters = this.get('controller.clusters').slice();
-      clusters.unshift(App.get('clusterName'));
-      return clusters;
-    }.property('controller.clusters.@each', 'App.clusterName'),
+      return this.get('controller.clusters');
+    }.property('controller.clusters.@each'),
+
+    optionLabelPath: 'content.name',
 
     onSelect: function () {
       if (this.get('selection.length')) {
@@ -39,15 +39,31 @@ App.MainMirroringManageClusterstView = Em.View.extend({
           this.set('selection', [this.get('controller.selectedCluster')]);
         }
       } else {
-        this.set('controller.selectedCluster', null);
+        this.set('selection', [this.get('content')[0]]);
+      }
+    }.observes('selection'),
+
+    // set selected option in Cluster Select after adding or removing an option
+    onContentChange: function () {
+      if (this.get('controller.isLoaded')) {
+        var content = this.get('content');
+        if (content.length < this.get('element.options.length')) {
+          this.set('selection', [content[0]]);
+        } else {
+          this.set('selection', [content[content.length - 1]]);
+        }
       }
-    }.observes('selection')
+    }.observes('content.length', 'controller.isLoaded')
   }),
 
   removeDisabled: function () {
     var selectedCluster = this.get('controller.selectedCluster');
-    return !selectedCluster || selectedCluster === App.get('clusterName');
-  }.property('controller.selectedCluster', 'App.clusterName')
+    return !selectedCluster || selectedCluster.get('name') === App.get('clusterName');
+  }.property('controller.selectedCluster', 'App.clusterName'),
+
+  didInsertElement: function () {
+    this.get('controller').onLoad();
+  }
 });
 
 

+ 0 - 28
ambari-web/app/views/main/mirroring/targetClusterView.js

@@ -1,28 +0,0 @@
-/**
- * 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.
- */
-
-var App = require('app');
-var filters = require('views/common/filter_view');
-var sort = require('views/common/sort_view');
-var date = require('utils/date');
-
-App.MainMirroringAddTargetClusterView = Em.View.extend({
-  name : 'mainMirroringAddTargetClusterView',
-  templateName:require('templates/main/mirroring/addTargetCluster')
-
-});

+ 0 - 33
ambari-web/app/views/main/mirroring/testConnectionResults_view.js

@@ -1,33 +0,0 @@
-/**
- * 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.
- */
-
-var App = require('app');
-var filters = require('views/common/filter_view');
-var sort = require('views/common/sort_view');
-var date = require('utils/date');
-
-App.TestConnectionResultsView = Em.View.extend({
-  templateName: require('templates/main/mirroring/testConnectionResults'),
-
-  name: 'testConnectionResultsView',
-
-  didInsertElement: function () {
-    var controller = this.get('controller');
-    controller.tryConnecting();
-  }
-});

+ 0 - 27
ambari-web/app/views/main/mirroring/testConnection_view.js

@@ -1,27 +0,0 @@
-/**
- * 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.
- */
-
-var App = require('app');
-var filters = require('views/common/filter_view');
-var sort = require('views/common/sort_view');
-var date = require('utils/date');
-
-App.TestConnectionView = Em.View.extend({
-  name : 'testConnectionView',
-  templateName:require('templates/main/mirroring/testConnection')
-});

+ 1 - 1
ambari-web/app/views/main/mirroring_view.js

@@ -24,6 +24,6 @@ App.MainMirroringView = Em.View.extend({
 
   didInsertElement: function () {
     var controller = this.get('controller');
-    controller.loadDatasets();
+    controller.loadData();
   }
 });