浏览代码

AMBARI-1469. Allow user to add multiple HBase masters in Install Wizard. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1448924 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 年之前
父节点
当前提交
bbf5b6b8d6

+ 3 - 0
CHANGES.txt

@@ -12,6 +12,9 @@ Trunk (unreleased changes):
 
  NEW FEATURES
 
+ AMBARI-1469. Allow user to add multiple HBase masters in Install Wizard.
+ (yusaku)
+
  AMBARI-1468. Stack Upgrade Wizard - Step 1 (show services and versions).
  (yusaku)
 

+ 119 - 126
ambari-web/app/controllers/wizard/step5_controller.js

@@ -24,31 +24,13 @@ App.WizardStep5Controller = Em.Controller.extend({
 
   hosts:[],
 
-  selectedServices:[],
   selectedServicesMasters:[],
-  zId:0,
-
-  hasHiveServer: function () {
-    return this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER');
-  }.property('selectedServicesMasters'),
-
-  updateHiveCoHosts: function () {
-    var hiveServer =  this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER');
-    var hiveMetastore = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE');
-    var webHCatServer = this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER');
-    if (hiveServer && hiveMetastore && webHCatServer) {
-      this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE').set('selectedHost', hiveServer.get('selectedHost'));
-      this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER').set('selectedHost', hiveServer.get('selectedHost'));
-    }
-  }.observes('selectedServicesMasters.@each.selectedHost'),
 
   components:require('data/service_components'),
 
   clearStep:function () {
     this.set('hosts', []);
-    this.set('selectedServices', []);
     this.set('selectedServicesMasters', []);
-    this.set('zId', 0);
   },
 
   loadStep:function () {
@@ -57,74 +39,76 @@ App.WizardStep5Controller = Em.Controller.extend({
     this.renderHostInfo();
     this.renderComponents(this.loadComponents());
 
+    this.updateComponent('ZOOKEEPER_SERVER');
+    this.updateComponent('HBASE_MASTER');
+
     if (!this.get("selectedServicesMasters").filterProperty('isInstalled', false).length) {
       console.log('no master components to add');
       App.router.send('next');
     }
   },
 
+  /**
+   * Used to set showAddControl flag for ZOOKEEPER_SERVER and HBASE_SERVER
+   */
+  updateComponent: function(componentName){
+    var component = this.last(componentName);
+    if (component) {
+      if (this.get("selectedServicesMasters").filterProperty("component_name", componentName).length < this.get("hosts.length")) {
+        component.set('showAddControl', true);
+      } else {
+        component.set('showRemoveControl', false);
+      }
+      if(componentName == 'ZOOKEEPER_SERVER'){
+        this.rebalanceZookeeperHosts();
+      }
+    }
+  },
+
   /**
    * Load active host list to <code>hosts</code> variable
    */
   renderHostInfo:function () {
 
     var hostInfo = this.get('content.hosts');
+    var result = [];
 
     for (var index in hostInfo) {
       var _host = hostInfo[index];
       if (_host.bootStatus === 'REGISTERED') {
-        var hostObj = Ember.Object.create({
+        result.push(Ember.Object.create({
           host_name:_host.name,
 
           cpu:_host.cpu,
           memory:_host.memory,
           disk_info:_host.disk_info,
           host_info: Em.I18n.t('installer.step5.hostInfo').fmt(_host.name, (_host.memory * 1024).bytesToSize(1, 'parseFloat'), _host.cpu)
-
-//          Uncomment to test sorting with random cpu, memory, host_info
-//          cpu:function () {
-//            return parseInt(2 + Math.random() * 4);
-//          }.property(),
-//          memory:function () {
-//            return parseInt((Math.random() * 4000000000) + 4000000000);
-//          }.property(),
-//
-//          host_info:function () {
-//            return "%@ (%@, %@ cores)".fmt(this.get('host_name'), (this.get('memory') * 1024).bytesToSize(1, 'parseFloat'), this.get('cpu'));
-//          }.property('cpu', 'memory')
-
-        });
-
-        this.get("hosts").pushObject(hostObj);
+        }));
       }
     }
+    this.set("hosts", result);
   },
 
   /**
    * Load services info to appropriate variable and return masterComponentHosts
-   * @return {Ember.Set}
+   * @return Array
    */
   loadComponents:function () {
 
     var services = this.get('content.services')
       .filterProperty('isSelected', true).mapProperty('serviceName'); //list of shown services
 
-    services.forEach(function (item) {
-      this.get("selectedServices").pushObject(Ember.Object.create({service_name:item}));
-    }, this);
-
-    var masterHosts = this.get('content.masterComponentHosts'); //saved to local storadge info
-
-    var resultComponents = new Ember.Set();
-
     var masterComponents = this.get('components').filterProperty('isMaster', true); //get full list from mock data
+    var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info
+
+    var resultComponents = [];
 
     var servicesLength = services.length;
     for (var index = 0; index < servicesLength; index++) {
       var componentInfo = masterComponents.filterProperty('service_name', services[index]);
 
       componentInfo.forEach(function (_componentInfo) {
-        if (_componentInfo.component_name == 'ZOOKEEPER_SERVER') {
+        if (_componentInfo.component_name == 'ZOOKEEPER_SERVER' || _componentInfo.component_name == 'HBASE_MASTER') {
           var savedComponents = masterHosts.filterProperty('component', _componentInfo.component_name);
           if (savedComponents.length) {
 
@@ -136,7 +120,8 @@ App.WizardStep5Controller = Em.Controller.extend({
               zooKeeperHost.availableHosts = [];
               zooKeeperHost.serviceId = services[index];
               zooKeeperHost.isInstalled = item.isInstalled;
-              resultComponents.add(zooKeeperHost);
+              zooKeeperHost.isHiveCoHost = false;
+              resultComponents.push(zooKeeperHost);
             })
 
           } else {
@@ -151,7 +136,7 @@ App.WizardStep5Controller = Em.Controller.extend({
               zooKeeperHost.serviceId = services[index];
               zooKeeperHost.isInstalled = false;
               zooKeeperHost.isHiveCoHost = false;
-              resultComponents.add(zooKeeperHost);
+              resultComponents.push(zooKeeperHost);
             });
 
           }
@@ -165,7 +150,7 @@ App.WizardStep5Controller = Em.Controller.extend({
           componentObj.serviceId = services[index];
           componentObj.availableHosts = [];
           componentObj.isHiveCoHost = ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(_componentInfo.component_name);
-          resultComponents.add(componentObj);
+          resultComponents.push(componentObj);
         }
       }, this);
     }
@@ -178,39 +163,45 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @param masterComponents
    */
   renderComponents:function (masterComponents) {
-    var zookeeperComponent = null, componentObj = null;
-    var services = this.get('selectedServicesMasters').slice(0);
-    if (services.length) {
-      this.set('selectedServicesMasters', []);
-    }
-
     var countZookeeper = masterComponents.filterProperty('display_name', 'ZooKeeper').length;
+    var countHbaseMaster = masterComponents.filterProperty('component_name', 'HBASE_MASTER').length;
+    var zid = 1;
+    var hid = 1;
+    var result = [];
 
     masterComponents.forEach(function (item) {
-      //add the zookeeper component at the end if exists
+
+      var componentObj = Ember.Object.create(item);
       console.log("TRACE: render master component name is: " + item.component_name);
-      if (item.display_name === "ZooKeeper") {
-        if (services.length) {
-          services.forEach(function (_service) {
-            this.get('selectedServicesMasters').pushObject(_service);
-          }, this);
-        }
-        this.set('zId', parseInt(this.get('zId')) + 1);
-        zookeeperComponent = Ember.Object.create(item);
-        zookeeperComponent.set('zId', this.get('zId'));
-        zookeeperComponent.set("showRemoveControl", countZookeeper > 1);
-        zookeeperComponent.set("availableHosts", this.get("hosts").slice(0));
-        this.get("selectedServicesMasters").pushObject(zookeeperComponent);
 
-      } else {
-        componentObj = Ember.Object.create(item);
-        componentObj.set("availableHosts", this.get("hosts").slice(0));
-        this.get("selectedServicesMasters").pushObject(componentObj);
+      if (item.display_name === "ZooKeeper") {
+        componentObj.set('zId', zid++);
+        componentObj.set("showRemoveControl", countZookeeper > 1);
+      } else if(item.component_name === "HBASE_MASTER"){
+        componentObj.set('zId', hid++);
+        componentObj.set("showRemoveControl", countHbaseMaster > 1);
       }
+      componentObj.set("availableHosts", this.get("hosts"));
+      result.push(componentObj);
     }, this);
 
+    this.set("selectedServicesMasters", result);
   },
 
+  hasHiveServer: function () {
+    return !!this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER');
+  }.property('selectedServicesMasters'),
+
+  updateHiveCoHosts: function () {
+    var hiveServer =  this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER');
+    var hiveMetastore = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE');
+    var webHCatServer = this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER');
+    if (hiveServer && hiveMetastore && webHCatServer) {
+      this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE').set('selectedHost', hiveServer.get('selectedHost'));
+      this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER').set('selectedHost', hiveServer.get('selectedHost'));
+    }
+  }.observes('selectedServicesMasters.@each.selectedHost'),
+
   getKerberosServer:function (noOfHosts) {
     var hosts = this.get('hosts');
     if (noOfHosts === 1) {
@@ -382,7 +373,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       case 'JOBTRACKER':
         return this.getJobTracker(noOfHosts).host_name;
       case 'HBASE_MASTER':
-        return this.getHBaseMaster(noOfHosts).host_name;
+        return [this.getHBaseMaster(noOfHosts).host_name];
       case 'OOZIE_SERVER':
         return this.getOozieServer(noOfHosts).host_name;
       case 'HIVE_SERVER':
@@ -429,52 +420,51 @@ App.WizardStep5Controller = Em.Controller.extend({
     return (this.get("hosts.length") - this.get("masterHostMapping.length"));
   }.property("selectedServicesMasters.@each.selectedHost"),
 
-  hasZookeeper:function () {
-    return this.selectedServices.findProperty("service_name", "ZooKeeper");
-  }.property("selectedServices"),
-
   //methods
   getAvailableHosts:function (componentName) {
-    var assignableHosts = [],
-      zookeeperHosts = null;
-
-    if (componentName === "ZooKeeper") {
-      zookeeperHosts = this.get("selectedServicesMasters").filterProperty("display_name", "ZooKeeper").mapProperty("selectedHost").uniq();
-      this.get("hosts").forEach(function (item) {
-        if (!(zookeeperHosts.contains(item.get("host_name")))) {
-          assignableHosts.pushObject(item);
-        }
-      }, this);
-      return assignableHosts;
+    var selectedHosts = this.get("selectedServicesMasters").filterProperty("component_name", componentName).mapProperty("selectedHost").uniq();
+
+    return this.get('hosts').filter(function(item){
+      return !selectedHosts.contains(item.get("host_name"));
+    });
 
-    } else {
-      return this.get("hosts");
-    }
   },
 
-  assignHostToMaster:function (masterService, selectedHost, zId) {
-    if (selectedHost && masterService) {
-      if ((masterService === "ZooKeeper") && zId) {
-        this.get('selectedServicesMasters').findProperty("zId", zId).set("selectedHost", selectedHost);
+  /**
+   * On change callback for selects
+   * @param componentName
+   * @param selectedHost
+   * @param zId
+   */
+  assignHostToMaster:function (componentName, selectedHost, zId) {
+    if (selectedHost && componentName) {
+      if ((componentName === "ZOOKEEPER_SERVER") && zId) {
+        this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("selectedHost", selectedHost);
         this.rebalanceZookeeperHosts();
-      }
-      else {
-        this.get('selectedServicesMasters').findProperty("display_name", masterService).set("selectedHost", selectedHost);
+      } else if(zId){ //Hbase
+        this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("selectedHost", selectedHost);
+      } else {
+        this.get('selectedServicesMasters').findProperty("component_name", componentName).set("selectedHost", selectedHost);
       }
 
     }
   },
 
-  lastZooKeeper:function () {
-    var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("display_name", "ZooKeeper");
-    if (currentZooKeepers) {
-      return currentZooKeepers.get("lastObject");
-    }
-
-    return null;
+  /**
+   * Returns last component of selected type
+   * @param componentName
+   * @return {*}
+   */
+  last: function(componentName){
+    return this.get("selectedServicesMasters").filterProperty("component_name", componentName).get("lastObject");
   },
 
-  addZookeepers:function () {
+  /**
+   * Add new component to ZooKeeper Server and Hbase master
+   * @param componentName
+   * @return {Boolean}
+   */
+  addComponent:function (componentName) {
     /*
      *Logic: If ZooKeeper service is selected then there can be
      * minimum 1 ZooKeeper master in total, and
@@ -482,25 +472,22 @@ App.WizardStep5Controller = Em.Controller.extend({
      */
 
     var maxNumZooKeepers = this.get("hosts.length"),
-      currentZooKeepers = this.get("selectedServicesMasters").filterProperty("display_name", "ZooKeeper"),
+      currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", componentName),
       newZookeeper = null,
       zookeeperHosts = null,
       suggestedHost = null,
       i = 0,
       lastZoo = null;
-    console.log('hosts legth is: ' + maxNumZooKeepers);
-    //work only if the Zookeeper service is selected in previous step
-    if (!this.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
+
+    if (!currentZooKeepers.length) {
       console.log('ALERT: Zookeeper service was not selected');
       return false;
     }
 
     if (currentZooKeepers.get("length") < maxNumZooKeepers) {
-      console.log('currentZookeeper length less than maximum. Its: ' + currentZooKeepers.get("length"))
+
       currentZooKeepers.set("lastObject.showAddControl", false);
-      if (currentZooKeepers.get("length") >= 1) {
-        currentZooKeepers.set("lastObject.showRemoveControl", true);
-      }
+      currentZooKeepers.set("lastObject.showRemoveControl", true);
 
       //create a new zookeeper based on an existing one
       newZookeeper = Ember.Object.create({});
@@ -508,7 +495,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       newZookeeper.set("display_name", lastZoo.get("display_name"));
       newZookeeper.set("component_name", lastZoo.get("component_name"));
       newZookeeper.set("selectedHost", lastZoo.get("selectedHost"));
-      newZookeeper.set("availableHosts", this.getAvailableHosts("ZooKeeper"));
+      newZookeeper.set("availableHosts", this.getAvailableHosts(componentName));
 
       if (currentZooKeepers.get("length") === (maxNumZooKeepers - 1)) {
         newZookeeper.set("showAddControl", false);
@@ -529,31 +516,36 @@ App.WizardStep5Controller = Em.Controller.extend({
 
       newZookeeper.set("selectedHost", suggestedHost);
       newZookeeper.set("zId", (currentZooKeepers.get("lastObject.zId") + 1));
-      this.set('zId', parseInt(this.get('zId')) + 1);
 
-      this.get("selectedServicesMasters").pushObject(newZookeeper);
+      this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastZoo) + 1, newZookeeper);
 
-      this.rebalanceZookeeperHosts();
+      if(componentName == 'ZOOKEEPER_SERVER'){
+        this.rebalanceZookeeperHosts();
+      }
 
       return true;
     }
     return false;//if no more zookeepers can be added
   },
 
-  removeZookeepers:function (zId) {
-    var currentZooKeepers;
+  /**
+   * Remove component from ZooKeeper server or Hbase Master
+   * @param componentName
+   * @param zId
+   * @return {Boolean}
+   */
+  removeComponent:function (componentName, zId) {
+    var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", componentName)
 
     //work only if the Zookeeper service is selected in previous step
-    if (!this.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
+    if (!currentZooKeepers.length) {
       return false;
     }
 
-    currentZooKeepers = this.get("selectedServicesMasters").filterProperty("display_name", "ZooKeeper");
-
     if (currentZooKeepers.get("length") > 1) {
-      this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(this.get("selectedServicesMasters").findProperty("zId", zId)));
+      this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(currentZooKeepers.findProperty("zId", zId)));
 
-      currentZooKeepers = this.get("selectedServicesMasters").filterProperty("display_name", "ZooKeeper");
+      currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
       if (currentZooKeepers.get("length") < this.get("hosts.length")) {
         currentZooKeepers.set("lastObject.showAddControl", true);
       }
@@ -561,8 +553,9 @@ App.WizardStep5Controller = Em.Controller.extend({
       if (currentZooKeepers.get("length") === 1) {
         currentZooKeepers.set("lastObject.showRemoveControl", false);
       }
-      this.set('zId', parseInt(this.get('zId')) - 1);
-      this.rebalanceZookeeperHosts();
+      if(componentName == 'ZOOKEEPER_SERVER'){
+        this.rebalanceZookeeperHosts();
+      }
 
       return true;
     }

+ 6 - 2
ambari-web/app/controllers/wizard/step8_controller.js

@@ -605,8 +605,12 @@ App.WizardStep8Controller = Em.Controller.extend({
   },
 
   loadMasterValue: function (hbaseMaster) {
-    var hbaseHostName = this.get('content.masterComponentHosts').findProperty('display_name', 'HBase Master');
-    hbaseMaster.set('component_value', hbaseHostName.hostName);
+    var hbaseHostName = this.get('content.masterComponentHosts').filterProperty('display_name', 'HBase Master');
+    if(hbaseHostName.length == 1){
+      hbaseMaster.set('component_value', hbaseHostName[0].hostName);
+    } else {
+      hbaseMaster.set('component_value', hbaseHostName[0].hostName + Em.I18n.t('installer.step8.other').format(hbaseHostName.length - 1));
+    }
   },
 
   loadRegionServerValue: function (rsComponent) {

+ 3 - 3
ambari-web/app/data/config_properties.js

@@ -67,11 +67,11 @@ module.exports =
     {
       "id": "puppet var",
       "name": "hbasemaster_host",
-      "displayName": "HBase Master host",
+      "displayName": "HBase Master hosts",
       "value": "",
       "defaultValue": "",
       "description": "The host that has been assigned to run HBase Master",
-      "displayType": "masterHost",
+      "displayType": "masterHosts",
       "isVisible": true,
       "domain": "global",
       "serviceName": "HBASE",
@@ -2195,7 +2195,7 @@ module.exports =
       "value": "",
       "defaultValue": "",
       "description": "The host that has been assigned to run ZooKeeper Server",
-      "displayType": "slaveHosts",
+      "displayType": "masterHosts",
       "isVisible": true,
       "isRequired": false,
       "serviceName": "ZOOKEEPER",

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

@@ -309,6 +309,7 @@ Em.I18n.translations = {
   'installer.step8.deployPopup.message':'Preparing to Deploy: {0} of {1} tasks completed.',
   'installer.step8.hosts':' hosts',
   'installer.step8.host':' host',
+  'installer.step8.other':' and {0} other hosts',
 
   'installer.step9.header':'Install, Start and Test',
   'installer.step9.body':'Please wait while the selected services are installed and started.',

+ 1 - 1
ambari-web/app/models/service_config.js

@@ -150,7 +150,7 @@ App.ServiceConfigProperty = Ember.Object.extend({
         this.set('value', slaveComponentHostsInDB.findProperty('componentName', 'TASKTRACKER').hosts.mapProperty('hostName'));
         break;
       case 'hbasemaster_host':
-        this.set('value', masterComponentHostsInDB.findProperty('component', 'HBASE_MASTER').hostName);
+        this.set('value', masterComponentHostsInDB.filterProperty('component', 'HBASE_MASTER').mapProperty('hostName'));
         break;
       case 'regionserver_hosts':
         this.set('value', slaveComponentHostsInDB.findProperty('componentName', 'HBASE_REGIONSERVER').hosts.mapProperty('hostName'));

+ 3 - 7
ambari-web/app/templates/wizard/step5.hbs

@@ -40,19 +40,15 @@
             optionValuePath="content.host_name"
             optionLabelPath="content.host_info"
             selectedHostBinding="selectedHost"
-            serviceNameBinding="display_name"
+            componentNameBinding="component_name"
             zIdBinding="zId"
             disabledBinding="isInstalled"
           }}
           {{#if showAddControl}}
-          {{view App.AddControlView
-            componentNameBinding="display_name"
-          }}
+            {{view App.AddControlView componentNameBinding="component_name"}}
           {{/if}}
           {{#if showRemoveControl}}
-          {{view App.RemoveControlView
-            zIdBinding="zId"
-          }}
+            {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
           {{/if}}
         </div>
         {{/if}}

+ 2 - 2
ambari-web/app/views/wizard/controls_view.js

@@ -270,11 +270,11 @@ App.ServiceConfigMultipleHostsDisplay = Ember.Mixin.create(App.ServiceConfigHost
   }.property('value'),
 
   hasOneHost: function () {
-    return this.get('value').length > 0;
+    return this.get('value').length === 1;
   }.property('value'),
 
   hasMultipleHosts: function () {
-    return (this.get('value').length > 1 && typeof(this.get('value')) == 'object');
+    return this.get('value').length > 1;
   }.property('value'),
 
   otherLength: function () {

+ 7 - 20
ambari-web/app/views/wizard/step5_view.js

@@ -24,17 +24,7 @@ App.WizardStep5View = Em.View.extend({
   templateName:require('templates/wizard/step5'),
 
   didInsertElement:function () {
-    var controller = this.get('controller');
-    controller.loadStep();
-
-    if (controller.lastZooKeeper()) {
-      if (controller.get("selectedServicesMasters").filterProperty("display_name", "ZooKeeper").length < controller.get("hosts.length")) {
-        controller.lastZooKeeper().set('showAddControl', true);
-      } else {
-        controller.lastZooKeeper().set('showRemoveControl', false);
-      }
-      controller.rebalanceZookeeperHosts();
-    }
+    this.get('controller').loadStep();
   }
 
 });
@@ -43,7 +33,7 @@ App.SelectHostView = Em.Select.extend({
   content:[],
   zId:null,
   selectedHost:null,
-  serviceName:null,
+  componentName:null,
   attributeBindings:['disabled'],
 
   filterContent:function () {
@@ -75,16 +65,12 @@ App.SelectHostView = Em.Select.extend({
 
   }.observes('content'),
 
-  init:function () {
-    this._super();
-    this.propertyDidChange('content');
-  },
-
   change:function () {
-    this.get('controller').assignHostToMaster(this.get("serviceName"), this.get("value"), this.get("zId"));
+    this.get('controller').assignHostToMaster(this.get("componentName"), this.get("value"), this.get("zId"));
   },
 
   didInsertElement:function () {
+    this.filterContent();
     this.set("value", this.get("selectedHost"));
   }
 });
@@ -96,17 +82,18 @@ App.AddControlView = Em.View.extend({
   template:Ember.Handlebars.compile('+'),
 
   click:function () {
-    this.get('controller').addZookeepers();
+    this.get('controller').addComponent(this.get('componentName'));
   }
 });
 
 App.RemoveControlView = Em.View.extend({
   zId:null,
+  componentName:null,
   tagName:"span",
   classNames:["badge", "badge-important"],
   template:Ember.Handlebars.compile('-'),
 
   click:function () {
-    this.get('controller').removeZookeepers(this.get("zId"));
+    this.get('controller').removeComponent(this.get('componentName'), this.get("zId"));
   }
 });