You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/01/10 21:55:13 UTC

svn commit: r1431634 [3/3] - in /incubator/ambari/trunk/ambari-web: app/ app/assets/data/apps/ app/controllers/ app/controllers/global/ app/controllers/main/host/ app/controllers/main/service/ app/controllers/wizard/ app/mappers/ app/models/ app/models...

Modified: incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js Thu Jan 10 20:55:12 2013
@@ -22,10 +22,6 @@ App.ClusterController = Em.Controller.ex
   name:'clusterController',
   cluster:null,
   isLoaded:false,
-  /**
-   * Whether we need to update statuses automatically or not
-   */
-  isWorking: false,
   updateLoadStatus:function (item) {
     var loadList = this.get('dataLoadList');
     var loaded = true;
@@ -250,57 +246,6 @@ App.ClusterController = Em.Controller.ex
       secondary : null
     });
   },
-
-  statusTimeoutId: null,
-
-  loadUpdatedStatusDelayed: function(delay){
-    delay = delay || App.componentsUpdateInterval;
-    var self = this;
-
-    this.set('statusTimeoutId',
-      setTimeout(function(){
-        self.loadUpdatedStatus();
-      }, delay)
-    );
-  },
-
-  loadUpdatedStatus: function(){
-
-    var timeoutId = this.get('statusTimeoutId');
-    if(timeoutId){
-      clearTimeout(timeoutId);
-      this.set('statusTimeoutId', null);
-    }
-
-    if(!this.get('isWorking')){
-      return false;
-    }
-
-    if(!this.get('clusterName')){
-      this.loadUpdatedStatusDelayed(this.get('componentsUpdateInterval')/2, 'error:clusterName');
-      return;
-    }
-    
-    var servicesUrl = this.getUrl('/data/dashboard/services.json', '/services?fields=components/ServiceComponentInfo,components/host_components,components/host_components/HostRoles');
-
-    var self = this;
-    App.HttpClient.get(servicesUrl, App.statusMapper, {
-      complete:function (jqXHR, textStatus) {
-        //console.log('Cluster Controller: Updated components statuses successfully!!!')
-        self.loadUpdatedStatusDelayed();
-      }
-    }, function(){
-      self.loadUpdatedStatusDelayed(null, 'error:response error');
-    });
-
-  },
-  startLoadUpdatedStatus: function(){
-    var self = this;
-    this.set('isWorking', true);
-    setTimeout(function(){
-      self.loadUpdatedStatus();
-    }, App.componentsUpdateInterval*2);
-  },
   /**
    *
    *  load all data and update load status
@@ -352,7 +297,7 @@ App.ClusterController = Em.Controller.ex
       self.updateLoadStatus('users');
     });
 
-    App.router.get('updateController').updateServiceMetric(function(){
+    App.router.get('updateController').updateServices(function(){
       self.updateLoadStatus('services');
     }, true);
 

Modified: incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js Thu Jan 10 20:55:12 2013
@@ -40,7 +40,7 @@ App.UpdateController = Em.Controller.ext
       if(timeIntervalId) return;
       this.set('timeIntervalId', setInterval(function(){
         self.updateHost();
-        self.updateServiceMetric();
+        self.updateServices();
         self.graphsUpdate();
       }, App.contentUpdateInterval));
     } else {
@@ -74,11 +74,11 @@ App.UpdateController = Em.Controller.ext
   },
   
   /**
-   * Updates the services information. 
+   * Updates the services and their components information.
    * 
    * @param isInitialLoad  If true, only basic information is loaded.
    */
-  updateServiceMetric: function (callback, isInitialLoad) {
+  updateServices: function (callback, isInitialLoad) {
     var self = this;
     self.set('isUpdated', false);
     var servicesUrl = isInitialLoad ? 

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main.js Thu Jan 10 20:55:12 2013
@@ -63,11 +63,9 @@ App.MainController = Em.Controller.exten
   startPolling: function(){
     App.router.get('updateController').set('isWorking', true);
     App.router.get('backgroundOperationsController').set('isWorking', true);
-    App.router.get('clusterController').startLoadUpdatedStatus();
   },
   stopPolling: function(){
     App.router.get('updateController').set('isWorking', false);
     App.router.get('backgroundOperationsController').set('isWorking', false);
-    App.router.get('clusterController').set('isWorking', false);
   }
 })
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/host/add_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/host/add_controller.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/host/add_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/host/add_controller.js Thu Jan 10 20:55:12 2013
@@ -88,6 +88,7 @@ App.AddHostController = App.WizardContro
         name: _host.name,
         cpu: _host.cpu,
         memory: _host.memory,
+        disk_info: _host.disk_info,
         bootStatus: _host.bootStatus,
         isInstalled: false
       };
@@ -360,7 +361,9 @@ App.AddHostController = App.WizardContro
     App.db.setServiceConfigProperties(serviceConfigProperties);
     this.set('content.serviceConfigProperties', serviceConfigProperties);
 
-    var slaveConfigProperties = [];
+    //TODO: Uncomment below code to enable slave Configuration
+
+    /*var slaveConfigProperties = [];
     stepController.get('stepConfigs').forEach(function (_content) {
       if (_content.get('configCategories').someProperty('isForSlaveComponent', true)) {
         var slaveCategory = _content.get('configCategories').findProperty('isForSlaveComponent', true);
@@ -378,7 +381,7 @@ App.AddHostController = App.WizardContro
       }
     }, this);
     App.db.setSlaveProperties(slaveConfigProperties);
-    this.set('content.slaveGroupProperties', slaveConfigProperties);
+    this.set('content.slaveGroupProperties', slaveConfigProperties);*/
   },
 
   /**

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/service/add_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/service/add_controller.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/service/add_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/service/add_controller.js Thu Jan 10 20:55:12 2013
@@ -398,7 +398,9 @@ App.AddServiceController = App.WizardCon
     App.db.setServiceConfigProperties(serviceConfigProperties);
     this.set('content.serviceConfigProperties', serviceConfigProperties);
 
-    var slaveConfigProperties = [];
+    //TODO: Uncomment below code to enable slave Configuration
+
+    /*var slaveConfigProperties = [];
     stepController.get('stepConfigs').forEach(function (_content) {
       if (_content.get('configCategories').someProperty('isForSlaveComponent', true)) {
         var slaveCategory = _content.get('configCategories').findProperty('isForSlaveComponent', true);
@@ -416,7 +418,7 @@ App.AddServiceController = App.WizardCon
       }
     }, this);
     App.db.setSlaveProperties(slaveConfigProperties);
-    this.set('content.slaveGroupProperties', slaveConfigProperties);
+    this.set('content.slaveGroupProperties', slaveConfigProperties);*/
   },
 
   /**

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard.js Thu Jan 10 20:55:12 2013
@@ -252,6 +252,12 @@ App.WizardController = Em.Controller.ext
     var url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?ServiceInfo/state=INIT';
     var method = (App.testMode) ? 'GET' : 'PUT';
     var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
+
+    if(this.get('content.controllerName') === 'addHostController'){
+      url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INIT';
+      data = '{"HostRoles": {"state": "INSTALLED"}}';
+    }
+
     $.ajax({
       type: method,
       url: url,

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard/step8_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard/step8_controller.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard/step8_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard/step8_controller.js Thu Jan 10 20:55:12 2013
@@ -1084,10 +1084,6 @@ App.WizardStep8Controller = Em.Controlle
         console.log("STEP8: value of the global property is: " + _globalSiteObj.value);
       }
     }, this);
-    // TODO: for now, setting mapred_local_dir in global as well as tasktracker global; we'll need to handle mapred_local_dir specific to jobtracker as well
-    if(this.get('globals').findProperty('name', 'mapred_local_dir')){ //todo: remove it when hook up it correctly
-      globalSiteProperties['mapred_local_dir'] = this.get('globals').findProperty('name', 'mapred_local_dir')['value'];
-    }
     return {"type": "global", "tag": "version1", "properties": globalSiteProperties};
   },
 

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard/step9_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard/step9_controller.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard/step9_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard/step9_controller.js Thu Jan 10 20:55:12 2013
@@ -32,18 +32,20 @@ App.WizardStep9Controller = Em.Controlle
   polledData: [],
 
   status: function () {
-    if (this.hosts.length && this.hosts.everyProperty('status', 'success')) {
-      return 'success';
-    } else if (this.hosts.someProperty('status', 'failed')) {
+    if(this.get('progress') != '100') {
+      return 'info';
+    }
+
+    if (this.hosts.someProperty('status', 'failed')) {
       return 'failed';
     } else if (this.hosts.someProperty('status', 'warning')) {
       return 'warning';
-    } else {
-      return 'info';
     }
-  }.property('hosts.@each.status'),
 
-  showRetry: function(){
+    return 'success';
+  }.property('hosts.@each.status', 'progress'),
+
+  showRetry: function () {
     return this.get('status') == 'failed';
   }.property('status'),
 
@@ -107,7 +109,7 @@ App.WizardStep9Controller = Em.Controlle
       hosts.add(obj);
       console.log("TRACE: host name is: " + hostInfo[index].name);
     }
-   // return hosts;
+    // return hosts;
     return hosts.filterProperty('bootStatus', 'REGISTERED');
   },
 
@@ -223,6 +225,11 @@ App.WizardStep9Controller = Em.Controlle
     var data = '{"ServiceInfo": {"state": "STARTED"}}';
     var method = 'PUT';
 
+    if (this.get('content.controllerName') === 'addHostController') {
+      url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INSTALLED';
+      data = '{"HostRoles": {"state": "STARTED"}}';
+    }
+
     if (App.testMode) {
       url = this.get('mockDataPrefix') + '/poll_6.json';
       method = 'GET';
@@ -320,7 +327,7 @@ App.WizardStep9Controller = Em.Controlle
   // for DATANODE, JOBTRACKER, HBASE_REGIONSERVER, and GANGLIA_MONITOR, if more than 50% fail, then it's a fatal error;
   // otherwise, it's only a warning and installation/start can continue
   getSuccessFactor: function (role) {
-    return ['DATANODE','JOBTRACKER','HBASE_REGIONSERVER','GANGLIA_MONITOR'].contains(role) ? 50 : 100;
+    return ['DATANODE', 'JOBTRACKER', 'HBASE_REGIONSERVER', 'GANGLIA_MONITOR'].contains(role) ? 50 : 100;
   },
 
   isStepFailed: function (polledData) {
@@ -485,6 +492,7 @@ App.WizardStep9Controller = Em.Controlle
     this.hosts.forEach(function (_host) {
       var actionsPerHost = tasksData.filterProperty('Tasks.host_name', _host.name); // retrieved from polled Data
       if (actionsPerHost.length === 0) {
+        _host.set('message', this.t('installer.step9.host.status.nothingToInstall'));
         console.log("Error: No task is hosted on the host");
       }
       if (actionsPerHost !== null && actionsPerHost !== undefined && actionsPerHost.length !== 0) {

Modified: incubator/ambari/trunk/ambari-web/app/initialize.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/initialize.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/initialize.js (original)
+++ incubator/ambari/trunk/ambari-web/app/initialize.js Thu Jan 10 20:55:12 2013
@@ -30,7 +30,6 @@ App.timeout = 20000;
 // retry times
 App.times = 3;
 App.bgOperationsUpdateInterval = 6000;
-App.componentsUpdateInterval = 6000;
 App.contentUpdateInterval = 15000;
 
 require('messages');
@@ -45,7 +44,6 @@ require('views');
 require('router');
 
 require('mappers/server_data_mapper');
-require('mappers/status_mapper');
 require('mappers/hosts_mapper');
 require('mappers/cluster_mapper');
 require('mappers/jobs_mapper');

Modified: incubator/ambari/trunk/ambari-web/app/mappers/service_mapper.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/mappers/service_mapper.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/mappers/service_mapper.js (original)
+++ incubator/ambari/trunk/ambari-web/app/mappers/service_mapper.js Thu Jan 10 20:55:12 2013
@@ -143,146 +143,57 @@ App.servicesMapper = App.QuickDataMapper
     }
 
     if (json.items) {
-      var result = [];
+      var addArray = [];
       json.items.forEach(function (item) {
         var finalConfig = jQuery.extend({}, this.config);
-        var finalJson = [];
+        var finalJson, commonJson;
         item.host_components = [];
-        if (this.get('model').find(item.ServiceInfo.service_name).get('isLoaded')) {
-          this.update(item);
-          return;
-        }
         item.components.forEach(function (component) {
           component.host_components.forEach(function (host_component) {
             host_component.id = host_component.HostRoles.component_name + "_" + host_component.HostRoles.host_name;
             item.host_components.push(host_component.id);
           }, this)
         }, this);
-
+        commonJson = this.parseIt(item, this.config);
         if (item && item.ServiceInfo && item.ServiceInfo.service_name == "HDFS") {
           // Change the JSON so that it is easy to map
           finalJson = this.hdfsMapper(item);
-          result.push(finalJson);
-          App.store.load(App.HDFSService, finalJson);
+          this.updateServices(commonJson, finalJson, addArray, App.HDFSService);
         } else if (item && item.ServiceInfo && item.ServiceInfo.service_name == "MAPREDUCE") {
           finalJson = this.mapreduceMapper(item);
-          result.push(finalJson);
-          App.store.load(App.MapReduceService, finalJson);
+          this.updateServices(commonJson, finalJson, addArray, App.MapReduceService);
         } else if (item && item.ServiceInfo && item.ServiceInfo.service_name == "HBASE") {
           finalJson = this.hbaseMapper(item);
-          result.push(finalJson);
-          App.store.load(App.HBaseService, finalJson);
+          this.updateServices(commonJson, finalJson, addArray, App.HBaseService);
         } else {
-          result.push(this.parseIt(item, this.config));
+          finalJson = commonJson;
+          this.updateServices(commonJson, finalJson, addArray);
         }
       }, this);
 
+      addArray = this.sortByOrder(this.get('servicesSortOrder'), addArray);
+      App.store.loadMany(this.get('model'), addArray);
 
-      result = this.sortByOrder(this.get('servicesSortOrder'), result);
-      App.store.loadMany(this.get('model'), result);
-
-      result = [];
+      addArray = [];
       json.items.forEach(function (item) {
         item.components.forEach(function (component) {
-          result.push(this.parseIt(component, this.config2));
+          var finalJson = this.parseIt(component, this.config2);
+          this.updateHostsComponents(finalJson, addArray, this.get('model2'));
         }, this)
       }, this);
 
-      App.store.loadMany(this.get('model2'), result);
+      App.store.loadMany(this.get('model2'), addArray);
 
-      result = [];
+      addArray = [];
       json.items.forEach(function (item) {
         item.components.forEach(function (component) {
           component.host_components.forEach(function (host_component) {
-            result.push(this.parseIt(host_component, this.config3));
+            var finalJson = this.parseIt(component, this.config2);
+            this.updateHostsComponents(finalJson, addArray, this.get('model3'));
           }, this)
         }, this)
       }, this);
-      App.store.loadMany(this.get('model3'), result);
-    }
-  },
-  update: function (service) {
-    var finalJson;
-    switch (service.ServiceInfo.service_name) {
-      case 'HDFS':
-        finalJson = this.hdfsMapper(service);
-        App.HDFSService.find().map(function (e) {
-          e.set("version", finalJson.version);
-          e.set("nameNodeStartTime", finalJson.name_node_start_time);
-          e.set("jvmMemoryHeapCommitted", finalJson.jvm_memory_heap_committed);
-          e.set("jvmMemoryHeapUsed", finalJson.jvm_memory_heap_used);
-          e.set("capacityUsed", finalJson.capacity_used);
-          e.set("capacityTotal", finalJson.capacity_total);
-          e.set("dfsTotalBlocks", finalJson.dfs_total_blocks);
-          e.set("dfsCorruptBlocks", finalJson.dfs_corrupt_blocks);
-          e.set("dfsMissingBlocks", finalJson.dfs_missing_blocks);
-          e.set("dfsUnderReplicatedBlocks", finalJson.dfs_under_replicated_blocks);
-          e.set("dfsTotalFiles", finalJson.dfs_total_files);
-          e.set("upgradeStatus", finalJson.upgrade_status);
-          e.set("safeModeStatus", finalJson.safe_mode_status);
-          // Live data nodes
-          var dataNodes = e.get('liveDataNodes');
-          if (dataNodes) {
-            dataNodes.clear();
-            finalJson.live_data_nodes.forEach(function (ldn) {
-              dataNodes.pushObject(App.Host.find(ldn));
-            });
-          }
-          // Decommission data nodes
-          dataNodes = e.get('decommissionDataNodes');
-          if (dataNodes) {
-            dataNodes.clear();
-            finalJson.decommission_data_nodes.forEach(function (ldn) {
-              dataNodes.pushObject(App.Host.find(ldn));
-            });
-          }
-          // Dead data nodes
-          dataNodes = e.get('deadDataNodes');
-          if (dataNodes) {
-            dataNodes.clear();
-            finalJson.dead_data_nodes.forEach(function (ldn) {
-              dataNodes.pushObject(App.Host.find(ldn));
-            });
-          }
-        });
-        break;
-      case 'MAPREDUCE':
-        finalJson = this.mapreduceMapper(service);
-        App.MapReduceService.find().map(function (e) {
-          e.set("version", finalJson.version);
-          e.set("jobTrackerStartTime", finalJson.job_tracker_start_time);
-          e.set("jobTrackerHeapUsed", finalJson.job_tracker_heap_used);
-          e.set("jobTrackerHeapMax", finalJson.job_tracker_heap_max);
-          e.set("mapSlots", finalJson.map_slots);
-          e.set("reduceSlots", finalJson.reduce_slots);
-          e.set("jobsSubmitted", finalJson.jobs_submitted);
-          e.set("jobsCompleted", finalJson.jobs_completed);
-          e.set("mapSlotsOccupied", finalJson.map_slots_occupied);
-          e.set("mapSlotsReserved", finalJson.map_slots_reserved);
-          e.set("reduceSlotsOccupied", finalJson.reduce_slots_occupied);
-          e.set("reduceSlotsReserved", finalJson.reduce_slots_reserved);
-          e.set("mapsRunning", finalJson.maps_running);
-          e.set("mapsWaiting", finalJson.maps_waiting);
-          e.set("reducesRunning", finalJson.reduces_running);
-          e.set("reducesWaiting", finalJson.reduces_waiting);
-          e.set("trackersDecommissioned", finalJson.trackers_decommissioned);
-        })
-        break;
-      case 'HBASE':
-        finalJson = this.hbaseMapper(service);
-        App.HBaseService.find().map(function (e) {
-          e.set("version", finalJson.version);
-          e.set("masterStartTime", finalJson.master_start_time);
-          e.set("masterActiveTime", finalJson.master_active_time);
-          e.set("averageLoad", finalJson.average_load);
-          e.set("regionsInTransition", finalJson.regions_in_transition);
-          e.set("revision", finalJson.revision);
-          e.set("heapMemoryUsed", finalJson.heap_memory_used);
-          e.set("heapMemoryMax", finalJson.heap_memory_max);
-        })
-        break;
-      default:
-        this.otherMapper(service);
+      App.store.loadMany(this.get('model3'), addArray);
     }
   },
   otherMapper: function (item) {
@@ -423,24 +334,67 @@ App.servicesMapper = App.QuickDataMapper
     finalJson.quick_links = [13, 14, 15, 16, 17, 18];
     return finalJson;
   },
-  _update: function(model, json){
-    var content = model.find();
-    var addArray = [];
-    for(var i in json){
-      var item = json[i];
-      var oldItem = content.findProperty('id', item.id);
-      if(oldItem){
-
-        for(var field in item){ ///<--
-          if(field !== 'id'){
-            oldItem.set(field, item[field]);  //<--
+  /**
+   * update or add records for service model
+   * if model defined updates Service model  and particular model that defined
+   * @param json
+   * @param addArray
+   * @param model
+   */
+  updateServices: function (commonJson, json, addArray, model) {
+    var commonOldItem = this.get('model').find().filterProperty('id', json.id);
+    var oldItem = (model) ? model.find().filterProperty('id', json.id) : [];
+    if(commonOldItem.length){
+      for (var field in json) {
+        if (field !== 'id') {
+//          if(commonJson.hasOwnProperty(field)){
+//            (json[field] instanceof Array)? this.setHasMany(field, json[field], commonOldItem[0]) : commonOldItem[0].set(field, json[field]);
+//          }
+          if(commonJson.hasOwnProperty(field)){
+            commonOldItem[0].set(field, json[field]);
+          }
+          if(oldItem.length){
+            oldItem[0].set(field, json[field]);
           }
         }
-
-      } else {
-        addArray.push(item);
+      }
+    } else {
+      addArray.push(commonJson);
+      if(model){
+        App.store.load(model, json)
       }
     }
-    App.store.loadMany(model, addArray);
+  },
+  /**
+   * add or update records for host and component models
+   * @param json
+   * @param addArray
+   * @param model
+   */
+  updateHostsComponents: function(json, addArray, model){
+    var oldItem = model.find().filterProperty('id', json.id);
+    if(oldItem.length){
+      for (var field in json) {
+        if (field !== 'id') {
+          oldItem[0].set(field, json[field]);
+        }
+      }
+    } else {
+      addArray.push(json);
+    }
+  },
+  /**
+   * update hasMany relations in model
+   * @param key
+   * @param value
+   * @param oldItem
+   */
+  setHasMany:function(key, value, oldItem){
+    var model;
+    value.clear();
+    value.forEach(function (item) {
+      oldItem.pushObject(model.find(item));
+    }, this);
   }
+
 });
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/messages.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/messages.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/messages.js (original)
+++ incubator/ambari/trunk/ambari-web/app/messages.js Thu Jan 10 20:55:12 2013
@@ -140,7 +140,8 @@ Em.I18n.translations = {
   'installer.step9.host.status.success':'Success',
   'installer.step9.host.status.warning':'Warnings encountered',
   'installer.step9.host.status.failed':'Failures encountered',
-  'installer.step9.hostLog.popup.header':'Tasks executed on ',
+  'installer.step9.host.status.nothingToInstall':'Nothing to install',
+  'installer.step9.hostLog.popup.header':'Tasks. executed on ',
 
   'installer.step10.header':'Summary',
   'installer.step10.body':'Here is the summary of the cluster install process.',

Modified: incubator/ambari/trunk/ambari-web/app/models/host.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/host.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/host.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/host.js Thu Jan 10 20:55:12 2013
@@ -65,12 +65,18 @@ App.Host = DS.Model.extend({
     return this.get('diskTotal') - this.get('diskFree');
   }.property('diskFree', 'diskTotal'),
   /**
-   * Format diskUsed value to float with 2 digits
+   * Format diskUsed value to float with 2 digits (also convert to GB)
    */
   diskUsedFormatted: function() {
-    return Math.round(this.get('diskUsed') * Math.pow(10, 2)) / Math.pow(10, 2);
+    return Math.round(this.get('diskUsed') / (1024*1024) * Math.pow(10, 2)) / Math.pow(10, 2) + 'GB';
   }.property('diskUsed'),
   /**
+   * Format diskTotal value to float with 2 digits (also convert to GB)
+   */
+  diskTotalFormatted: function() {
+    return Math.round(this.get('diskTotal') / (1024*1024) * Math.pow(10, 2)) / Math.pow(10, 2) + 'GB';
+  }.property('diskTotal'),
+  /**
    * Percent value of used disk space
    */
   diskUsage: function() {

Modified: incubator/ambari/trunk/ambari-web/app/models/service/hbase.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/service/hbase.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/service/hbase.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/service/hbase.js Thu Jan 10 20:55:12 2013
@@ -18,6 +18,7 @@
 var App = require('app');
 
 App.HBaseService = App.Service.extend({
+  serviceName: DS.attr('string'),
   version: DS.attr('string'),
   master: DS.belongsTo('App.Host'),
   regionServers: DS.hasMany('App.Host'),

Modified: incubator/ambari/trunk/ambari-web/app/models/service/hdfs.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/service/hdfs.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/service/hdfs.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/service/hdfs.js Thu Jan 10 20:55:12 2013
@@ -18,6 +18,7 @@
 var App = require('app');
 
 App.HDFSService = App.Service.extend({
+  serviceName: DS.attr('string'),
   version: DS.attr('string'),
   nameNode: DS.belongsTo('App.Host'),
   snameNode: DS.belongsTo('App.Host'),

Modified: incubator/ambari/trunk/ambari-web/app/models/service/mapreduce.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/service/mapreduce.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/service/mapreduce.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/service/mapreduce.js Thu Jan 10 20:55:12 2013
@@ -18,6 +18,7 @@
 var App = require('app');
 
 App.MapReduceService = App.Service.extend({
+  serviceName: DS.attr('string'),
   version: DS.attr('string'),
   jobTracker: DS.belongsTo('App.Host'),
   taskTrackers: DS.hasMany('App.Host'),

Modified: incubator/ambari/trunk/ambari-web/app/models/service_config.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/service_config.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/service_config.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/service_config.js Thu Jan 10 20:55:12 2013
@@ -188,6 +188,18 @@ App.ServiceConfigProperty = Ember.Object
     var masterComponentHostsInDB = App.db.getMasterComponentHosts();
     var slaveComponentHostsInDB = App.db.getSlaveComponentHosts();
     var hostsInfo = App.db.getHosts(); // which we are setting in installerController in step3.
+    App.Host.find().forEach(function(item){
+      if(!hostsInfo[item.get('id')]){
+        hostsInfo[item.get('id')] = {
+          name: item.get('id'),
+          cpu: item.get('cpu'),
+          memory: item.get('memory'),
+          disk_info: item.get('diskInfo'),
+          bootStatus: "REGISTERED",
+          isInstalled: true
+        };
+      }
+    });
     var temp = '';
     var setOfHostNames = [];
     switch (this.get('name')) {

Modified: incubator/ambari/trunk/ambari-web/app/routes/add_host_routes.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/routes/add_host_routes.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/routes/add_host_routes.js (original)
+++ incubator/ambari/trunk/ambari-web/app/routes/add_host_routes.js Thu Jan 10 20:55:12 2013
@@ -215,7 +215,7 @@ module.exports = Em.Route.extend({
       var wizardStep9Controller = router.get('wizardStep9Controller');
       if (!wizardStep9Controller.get('isSubmitDisabled')) {
         if (wizardStep9Controller.get('content.cluster.status') !== 'START FAILED') {
-        addHostController.installServices();
+        addHostController.installServices(true);
         addHostController.setInfoForStep9();
         } else {
           wizardStep9Controller.set('content.cluster.isCompleted', false);

Modified: incubator/ambari/trunk/ambari-web/app/styles/application.less
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/styles/application.less?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/styles/application.less (original)
+++ incubator/ambari/trunk/ambari-web/app/styles/application.less Thu Jan 10 20:55:12 2013
@@ -448,17 +448,6 @@ a:focus {
 @rack-state-plus: url("/img/rack-state-plus.png");
 @rack-state-minus: url("/img/rack-state-minus.png");
 
-/*Install Task Logs images*/
-@task-state-timedout: url("/img/task-log-timedout.png");
-@task-state-cancelled: url("/img/task-log-cancelled.png");
-@task-state-success: url("/img/task-log-success.png");
-@task-state-failed: url("/img/task-log-fail.png");
-@task-state-progress: url("/img/task-log-progress.png");
-@task-state-pending: url("/img/task-log-pending.png");
-@task-show-details: url("/img/task-log-show-detail.png");
-@task-detail-copy: url("/img/task-log-copy.png");
-@task-detail-open-dialog: url("/img/task-detail-open-dialog.png");
-
 /*****start styles for boxes*****/
 .box {
   border: 1px solid #D4D4D4;
@@ -503,23 +492,26 @@ a:focus {
 
 /*****start styles for install tasks logs*****/
 .task-list-main-warp, .task-detail-info {
+  i {
+    font-size: 20px;
+    vertical-align: middle;
+  }
   .pending, .queued{
-    background: @task-state-pending left center no-repeat;
+    color: #999999;
   }
   .in_progress{
-    background: @task-state-progress left center no-repeat;
+    color: #367FE6;
   }
   .completed{
-    background: @task-state-success left center no-repeat;
+    color: #0EA31C;
   }
   .failed {
-    background: @task-state-failed left center no-repeat;
+    color: #DF5F5F;
   }
   .aborted{
-    background: @task-state-cancelled left center no-repeat;
   }
   .timedout{
-    background: @task-state-timedout left center no-repeat;
+    color: #FF9C09;
   }
 }
 .task-list-main-warp{
@@ -548,11 +540,13 @@ a:focus {
       border-bottom: 1px solid #CCC;
 
       .show-details{
-        width:16px;
-        height:16px;
         float: right;
         cursor: pointer;
-        background: @task-show-details no-repeat center ;
+        font-size: 16px;
+
+        i{
+          color: #333;
+        }
       }
 
     }
@@ -584,32 +578,26 @@ a:focus {
       top: 0;
     }
     .task-detail-status-ico{
-      width:24px;
-      height: 24px;
-      background-position: center;
       content: "";
       margin-top: -4px;
       box-shadow: none;
       margin-bottom: 0px;
+      font-size:24px;
     }
 
     .task-detail-ico-wrap{
-
+      font-size: 24px;
       float:right;
       margin-top:-26px;
 
       div{
-        width: 24px;
-        height: 24px;
         cursor: pointer;
       }
       .task-detail-copy{
         margin-right: 12px;
-        background: @task-detail-copy no-repeat center;
         float: left;
       }
       .task-detail-open-dialog{
-        background: @task-detail-open-dialog no-repeat center;
         float: right;
       }
     }
@@ -2177,6 +2165,11 @@ ul.inline li {
   background-color: #666666;
 }
 
+.dropdown-menu li > a:hover, .dropdown-menu li > a:focus, .dropdown-submenu:hover > a {
+  background-color: #666666;
+  background-image: linear-gradient(to bottom, #666666, #555555);
+}
+
 .alert-info {
   background-color: #E6F1F6;
   border-color: #D2D9DD;

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/apps.hbs Thu Jan 10 20:55:12 2013
@@ -95,4 +95,3 @@
     </tbody>
   </table>
 </div>
-

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/host.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/host.hbs?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/host.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/host.hbs Thu Jan 10 20:55:12 2013
@@ -69,7 +69,7 @@
       <td>{{host.cpu}}</td>
       <td>{{host.memoryFormatted}}</td>
       <td>
-        <div class="progress progress-info" title="{{unbound host.diskUsedFormatted}} / {{unbound host.diskTotal}} ({{unbound host.diskUsageFormatted}} used)">
+        <div class="progress progress-info" title="{{unbound host.diskUsedFormatted}} / {{unbound host.diskTotalFormatted}} ({{unbound host.diskUsageFormatted}} used)">
           <div class="bar" {{bindAttr style="view.usageStyle"}}></div>
         </div>
       </td>

Modified: incubator/ambari/trunk/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs Thu Jan 10 20:55:12 2013
@@ -31,11 +31,12 @@
   <div id="host-log">
     {{#each role in view.roles}}
     {{#each taskInfo in role.taskInfos}}
-    <div {{bindAttr class="taskInfo.isVisible::hidden :log-list-wrap taskInfo.status"}}>
+    <div {{bindAttr class="taskInfo.isVisible::hidden :log-list-wrap"}}>
+      <i {{bindAttr class="taskInfo.status taskInfo.icon"}}></i>
       <a href="#" class="" {{action toggleTaskLog taskInfo}}>
         {{{role.roleName}} {{taskInfo.command}}
       </a>
-      <div {{action toggleTaskLog taskInfo}} class="show-details"></div>
+      <div {{action toggleTaskLog taskInfo}} class="show-details"><i class="icon-caret-right"></i></div>
     </div>
     {{/each}}
     {{/each}}
@@ -44,15 +45,16 @@
 
 <div {{bindAttr class="view.isLogWrapHidden:hidden :task-detail-info"}}>
   <div class="task-top-wrap">
-  <a class="task-detail-back" href="javascript:void(null)" {{action backToTaskList}} ><i class="icon-arrow-left"></i>&nbsp;Tasks</a>
-   <div>
-      <img src="data:image/png;base64,R0lGODlhFAAUAIAAAP///wAAACH5BAEAAAAALAAAAAAUABQAAAIRhI+py+0Po5y02ouz3rz7rxUAOw==" class="task-detail-status-ico" />
+    <a class="task-detail-back" href="javascript:void(null)" {{action backToTaskList}} ><i class="icon-arrow-left"></i>&nbsp;Tasks</a>
+    <div>
+      <!--<img src="data:image/png;base64,R0lGODlhFAAUAIAAAP///wAAACH5BAEAAAAALAAAAAAUABQAAAIRhI+py+0Po5y02ouz3rz7rxUAOw==" class="task-detail-status-ico" />-->
+      <i class="task-detail-status-ico"></i>
       <span class="task-detail-log-rolename" ></span>
     </div>
-  <div class="task-detail-ico-wrap">
-    <div {{action "textTrigger" taskInfo target="view"}} class="task-detail-copy"></div>
-    <div {{action openTaskLogInDialog}} class="task-detail-open-dialog"></div>
-  </div>
+    <div class="task-detail-ico-wrap">
+      <div {{action "textTrigger" taskInfo target="view"}} class="task-detail-copy"><i class="icon-copy"></i></div>
+      <div {{action openTaskLogInDialog}} class="task-detail-open-dialog"><i class="icon-external-link"></i></div>
+    </div>
   </div>
   <div class="task-detail-log-info">
     <div class="content-area" >

Modified: incubator/ambari/trunk/ambari-web/app/views/main/apps/item/dag_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/main/apps/item/dag_view.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/main/apps/item/dag_view.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/main/apps/item/dag_view.js Thu Jan 10 20:55:12 2013
@@ -34,11 +34,12 @@ App.MainAppsItemDagView = Em.View.extend
     var result = [];
     c.forEach(function(item, index){
       result[index] = new Object({
-        'name' : item.get('workflowEntityName'),
-        'status' : item.get('status') == 'COMPLETE',
+        'name' : item.get('id'),
+        'entityName' : item.get('workflowEntityName'),
+        'status' : item.get('status') == 'SUCCESS',
         'info' : [],
-        'input' : 2,
-        'output' : 3
+        'input' : item.get('inputBytes'),
+        'output' : item.get('outputBytes')
       })
     });
     return result;

Modified: incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/main/apps_view.js Thu Jan 10 20:55:12 2013
@@ -63,7 +63,7 @@ App.MainAppsView = Em.View.extend({
   /**
    * Count of filtered runs
    */
-  filtered:null,
+  filtered: null,
   /**
    * Flag for avgData
    */

Modified: incubator/ambari/trunk/ambari-web/app/views/main/service/info/summary.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/main/service/info/summary.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/main/service/info/summary.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/main/service/info/summary.js Thu Jan 10 20:55:12 2013
@@ -35,7 +35,7 @@ App.MainServiceInfoSummaryView = Em.View
     var result = [];
     var service = this.get('controller.content');
     if (service.get("id") == "OOZIE" || service.get("id") == "ZOOKEEPER") {
-      var clients = service.get('components').filterProperty('isClient');
+      var clients = service.get('hostComponents').filterProperty('isClient');
       if (clients.length > 0) {
         result = [{
           'displayName': clients[0].get('displayName'),
@@ -67,7 +67,7 @@ App.MainServiceInfoSummaryView = Em.View
     var result = [];
     var service = this.get('controller.content');
     if (service.get("id") == "ZOOKEEPER") {
-      var servers = service.get('components').filterProperty('isMaster');
+      var servers = service.get('hostComponents').filterProperty('isMaster');
       if (servers.length > 0) {
         result = [{
           'host': servers[0].get('displayName'),
@@ -99,7 +99,7 @@ App.MainServiceInfoSummaryView = Em.View
     var result = '';
     var service = this.get('controller.content');
     if (service.get("id") == "GANGLIA") {
-      var monitors = service.get('components').filterProperty('isMaster', false);
+      var monitors = service.get('hostComponents').filterProperty('isMaster', false);
       if (monitors.length) {
         result = monitors.length - 1 ? monitors.length + ' hosts running monitor' : '1 host running monitor';
       }
@@ -160,25 +160,25 @@ App.MainServiceInfoSummaryView = Em.View
     }
   },
   gangliaServer:function(){
-    var tmp=this.get('controller.content');
-    if(tmp.get("id") == "GANGLIA"){
-      return tmp.get("components").objectAt(0).get("host").get("publicHostName");
+    var service=this.get('controller.content');
+    if(service.get("id") == "GANGLIA"){
+      return service.get("components").findProperty('isMaster', true).get("host").get("publicHostName");
     }else{
       return "";
     }
   }.property('controller.content'),
   nagiosServer:function(){
-    var tmp=this.get('controller.content');
-    if(tmp.get("id") == "NAGIOS"){
-      return tmp.get("components").objectAt(0).get("host").get("publicHostName");
+    var service=this.get('controller.content');
+    if(service.get("id") == "NAGIOS"){
+      return service.get("components").findProperty('isMaster', true).get("host").get("publicHostName");
     }else{
       return "";
     }
   }.property('controller.content'),
   oozieServer:function(){
-    var tmp=this.get('controller.content');
-    if(tmp.get("id") == "OOZIE"){
-      return tmp.get("components").objectAt(0).get("host").get("publicHostName");
+    var service=this.get('controller.content');
+    if(service.get("id") == "OOZIE"){
+      return service.get("components").findProperty('isMaster', true).get("host").get("publicHostName");
     }else{
       return "";
     }

Modified: incubator/ambari/trunk/ambari-web/app/views/wizard/step9_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/views/wizard/step9_view.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/views/wizard/step9_view.js (original)
+++ incubator/ambari/trunk/ambari-web/app/views/wizard/step9_view.js Thu Jan 10 20:55:12 2013
@@ -241,6 +241,20 @@ App.HostStatusView = Em.View.extend({
                 taskInfo.set('url', _task.href);
                 taskInfo.set('roleName', roleObj.roleName);
                 taskInfo.set('isVisible', true);
+                taskInfo.set('icon', '');
+                if (taskInfo.get('status') == 'pending' || taskInfo.get('status') == 'queued') {
+                  taskInfo.set('icon', 'icon-cog');
+                } else if (taskInfo.get('status') == 'in_progress') {
+                  taskInfo.set('icon', 'icon-cogs');
+                } else if (taskInfo.get('status') == 'completed') {
+                  taskInfo.set('icon', ' icon-ok');
+                } else if (taskInfo.get('status') == 'failed') {
+                  taskInfo.set('icon', 'icon-exclamation-sign');
+                } else if (taskInfo.get('status') == 'aborted') {
+                  taskInfo.set('icon', 'icon-remove');
+                } else if (taskInfo.get('status') == 'timedout') {
+                  taskInfo.set('icon', 'icon-time');
+                }
                 taskInfos.pushObject(taskInfo);
               }, this);
               roleObj.taskInfos = taskInfos;
@@ -280,7 +294,7 @@ App.HostStatusView = Em.View.extend({
 
             $(".task-detail-status-ico")
                 .removeClass()
-                .addClass("task-detail-status-ico " + taskInfo.status);
+                .addClass(taskInfo.status + " task-detail-status-ico " + taskInfo.icon);
 
             var url = (App.testMode) ? '/data/wizard/deploy/task_log.json' : taskInfo.url;
             $.ajax({
@@ -333,5 +347,4 @@ App.HostStatusView = Em.View.extend({
     });
   }
 
-});
-
+});
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/vendor/scripts/workflow_visualization.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/vendor/scripts/workflow_visualization.js?rev=1431634&r1=1431633&r2=1431634&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/vendor/scripts/workflow_visualization.js (original)
+++ incubator/ambari/trunk/ambari-web/vendor/scripts/workflow_visualization.js Thu Jan 10 20:55:12 2013
@@ -372,7 +372,7 @@ DagViewer.prototype.setData = function (
   var jobData = (jobData) ? jobData : new Array();
   // iterate through job data
   for (var i = 0; i < jobData.length; i++) {
-    this._addNode(existingNodes, jobData[i].name, jobData[i]);
+    this._addNode(existingNodes, jobData[i].entityName, jobData[i]);
   }
   var dag = eval('(' + wfData + ')').dag;
   // for each source node in the context, create links between it and its target nodes