You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2017/06/19 12:57:38 UTC
ambari git commit: AMBARI-21278 Integrate cluster topology updates
with websocket events. (atkach)
Repository: ambari
Updated Branches:
refs/heads/branch-3.0-perf 94fed5503 -> d986503ca
AMBARI-21278 Integrate cluster topology updates with websocket events. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d986503c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d986503c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d986503c
Branch: refs/heads/branch-3.0-perf
Commit: d986503ca0fb4301e5b01595299162da3453f41c
Parents: 94fed55
Author: Andrii Tkach <at...@apache.org>
Authored: Mon Jun 19 15:25:44 2017 +0300
Committer: Andrii Tkach <at...@apache.org>
Committed: Mon Jun 19 15:25:44 2017 +0300
----------------------------------------------------------------------
ambari-web/app/app.js | 1 +
ambari-web/app/assets/test/tests.js | 1 +
.../controllers/global/cluster_controller.js | 1 +
.../app/controllers/global/update_controller.js | 3 +
ambari-web/app/controllers/main/host/details.js | 14 --
ambari-web/app/mappers.js | 3 +-
.../app/mappers/socket/topology_mapper.js | 163 +++++++++++++++
ambari-web/app/models/host_component.js | 9 +
ambari-web/app/utils/ajax/ajax.js | 4 +-
ambari-web/app/views/main/menu.js | 2 +-
.../global/cluster_controller_test.js | 6 +-
.../global/update_controller_test.js | 2 +
.../test/controllers/main/host/details_test.js | 45 -----
.../test/mappers/socket/topology_mapper_test.js | 201 +++++++++++++++++++
14 files changed, 391 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index c667992..8d5dd58 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -180,6 +180,7 @@ module.exports = Em.Application.create({
return false;
}.property('router.clusterController.isLoaded'),
+ clusterId: null,
clusterName: null,
clockDistance: null, // server clock - client clock
currentStackVersion: '',
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 23d9f66..567539b 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -167,6 +167,7 @@ var files = [
'test/mappers/configs/service_config_version_mapper_test',
'test/mappers/configs/themes_mapper_test',
'test/mappers/socket_events_mapper_test',
+ 'test/mappers/socket/topology_mapper_test',
'test/mixins/common/configs/enhanced_configs_test',
'test/mixins/common/configs/config_recommendations_test',
'test/mixins/common/configs/config_recommendation_parser_test',
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index 29c979e..b13cc8b 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -134,6 +134,7 @@ App.ClusterController = Em.Controller.extend(App.ReloadPopupMixin, {
this._super();
if (data.items && data.items.length > 0) {
App.setProperties({
+ clusterId: data.items[0].Clusters.cluster_id,
clusterName: data.items[0].Clusters.cluster_name,
currentStackVersion: data.items[0].Clusters.version,
isKerberosEnabled: data.items[0].Clusters.security_type === 'KERBEROS'
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index e7ed53f..d9c882f 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -191,6 +191,7 @@ App.UpdateController = Em.Controller.extend({
//TODO limit updates by location
App.StompClient.subscribe('/events/hostcomponents', socket.applyHostComponentStatusEvents.bind(socket));
App.StompClient.subscribe('/events/alerts', socket.applyAlertDefinitionSummaryEvents.bind(socket));
+ App.StompClient.subscribe('/events/topologies', App.topologyMapper.map.bind(App.topologyMapper));
App.updater.run(this, 'updateServices', 'isWorking');
App.updater.run(this, 'updateHost', 'isWorking');
@@ -210,6 +211,7 @@ App.UpdateController = Em.Controller.extend({
} else {
App.StompClient.unsubscribe('/events/hostcomponents');
App.StompClient.unsubscribe('/events/alerts');
+ App.StompClient.unsubscribe('/events/topologies');
}
}.observes('isWorking', 'App.router.mainAlertInstancesController.isUpdating'),
@@ -581,6 +583,7 @@ App.UpdateController = Em.Controller.extend({
},
updateAlertDefinitionSummary: function(callback) {
+ //TODO move to clusterController
var testUrl = '/data/alerts/alert_summary.json';
var realUrl = '/alerts?format=groupedSummary';
var url = this.getUrl(testUrl, realUrl);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index def75d6..aba8ed5 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -630,7 +630,6 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
*/
_doDeleteHostComponentSuccessCallback: function (response, request, data) {
this.set('_deletedHostComponentResult', null);
- this.removeHostComponentModel(data.componentName, data.hostName);
},
/**
@@ -645,19 +644,6 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
},
/**
- * Remove host component data from App.HostComponent model.
- *
- * @param {String} componentName
- * @param {String} hostName
- */
- removeHostComponentModel: function (componentName, hostName) {
- var component = App.HostComponent.find().filterProperty('componentName', componentName).findProperty('hostName', hostName);
- var serviceInCache = App.cache['services'].findProperty('ServiceInfo.service_name', component.get('service.serviceName'));
- serviceInCache.host_components = serviceInCache.host_components.without(component.get('id'));
- App.serviceMapper.deleteRecord(component);
- },
-
- /**
* Send command to server to upgrade selected host component
* @param {object} event
* @method upgradeComponent
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/mappers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js
index d77c834..6cba547 100644
--- a/ambari-web/app/mappers.js
+++ b/ambari-web/app/mappers.js
@@ -45,4 +45,5 @@ require('mappers/root_service_mapper');
require('mappers/widget_mapper');
require('mappers/widget_layout_mapper');
require('mappers/stack_upgrade_history_mapper');
-require('mappers/socket_events_mapper');
\ No newline at end of file
+require('mappers/socket_events_mapper');
+require('mappers/socket/topology_mapper');
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/mappers/socket/topology_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/socket/topology_mapper.js b/ambari-web/app/mappers/socket/topology_mapper.js
new file mode 100644
index 0000000..d46fa5e
--- /dev/null
+++ b/ambari-web/app/mappers/socket/topology_mapper.js
@@ -0,0 +1,163 @@
+/**
+ * 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 stringUtils = require('utils/string_utils');
+
+App.topologyMapper = App.QuickDataMapper.create({
+
+ /**
+ *
+ * @param {object} event
+ */
+ map: function(event) {
+ if (event.clusters[App.get('clusterId')].components) {
+ this.applyComponentTopologyChanges(event.clusters[App.get('clusterId')].components, event.eventType);
+ }
+ if (event.clusters[App.get('clusterId')].hosts) {
+ //TODO test hosts add/remove when hosts registration will be fixed
+ App.router.get('updateController').updateHost(Em.K, null, true);
+ }
+ },
+
+ /**
+ *
+ * @param {Array} components
+ * @param {string} eventType
+ */
+ applyComponentTopologyChanges: function(components, eventType) {
+ components.forEach((component) => {
+ component.hostNames.forEach((hostName, index) => {
+ if (eventType === 'UPDATE' && component.version === 'UNKNOWN') {
+ this.addServiceIfNew(component.serviceName);
+ this.createHostComponent(component, hostName, component.publicHostNames[index]);
+ } else if (eventType === 'DELETE') {
+ this.deleteHostComponent(component, hostName);
+ this.deleteServiceIfHasNoComponents(component.serviceName);
+ }
+ });
+ });
+ },
+
+ /**
+ *
+ * @param {string} serviceName
+ */
+ addServiceIfNew: function(serviceName) {
+ if (!App.Service.find(serviceName).get('isLoaded')) {
+ App.store.safeLoad(App.Service, {
+ id: serviceName,
+ service_name: serviceName,
+ work_status: 'INIT',
+ passive_state: 'OFF',
+ host_components: []
+ });
+ }
+ },
+
+ /**
+ *
+ * @param {string} serviceName
+ */
+ deleteServiceIfHasNoComponents: function(serviceName) {
+ if (App.Service.find(serviceName).get('isLoaded') &&
+ App.Service.find(serviceName).get('hostComponents.length') === 0) {
+ this.deleteRecord(App.Service.find(serviceName));
+ }
+ },
+
+ /**
+ *
+ * @param {object} component
+ * @param {string} hostName
+ */
+ deleteHostComponent: function(component, hostName) {
+ const id = App.HostComponent.getId(component.componentName, hostName);
+ if (!App.HostComponent.find(id).get('isLoaded')) {
+ //App.HostComponent does not contain all host-components of cluster
+ return;
+ }
+ this.deleteRecord(App.HostComponent.find(id));
+ const host = App.Host.find(hostName);
+ this.updateHostComponentsOfHost(host, host.get('hostComponents').rejectProperty('id', id).mapProperty('id'));
+
+ const service = App.Service.find(component.serviceName);
+ this.updateHostComponentsOfService(service, service.get('hostComponents').rejectProperty('id', id).mapProperty('id'));
+ },
+
+ /**
+ *
+ * @param {object} component
+ * @param {string} hostName
+ * @param {string} publicHostName
+ */
+ createHostComponent: function(component, hostName, publicHostName) {
+ const id = App.HostComponent.getId(component.componentName, hostName);
+ if (!App.Host.find(hostName).get('isLoaded')) {
+ //App.Host does not contain all hosts of cluster
+ return;
+ }
+ App.store.safeLoad(App.HostComponent, {
+ id: id,
+ host_id: hostName,
+ display_name: component.displayName,
+ service_id: component.serviceName,
+ host_name: hostName,
+ passive_state: 'OFF',
+ work_status: 'INIT',
+ public_host_name: publicHostName,
+ component_name: component.componentName
+ });
+ const host = App.Host.find(hostName);
+ this.updateHostComponentsOfHost(host, host.get('hostComponents').mapProperty('id').concat(id));
+
+ const service = App.Service.find(component.serviceName);
+ this.updateHostComponentsOfService(service, service.get('hostComponents').mapProperty('id').concat(id));
+ },
+
+ /**
+ *
+ * @param {Em.Object} host
+ * @param {Array} hostComponents
+ */
+ updateHostComponentsOfHost: function(host, hostComponents) {
+ const updatedHost = {};
+ for (let i in App.hostsMapper.config) {
+ if (host.get(stringUtils.underScoreToCamelCase(i)) !== undefined) {
+ updatedHost[i] = host.get(stringUtils.underScoreToCamelCase(i));
+ }
+ }
+ updatedHost.host_components = hostComponents;
+ App.store.safeLoad(App.Host, updatedHost);
+ },
+
+ /**
+ *
+ * @param {Em.Object} service
+ * @param {Array} hostComponents
+ */
+ updateHostComponentsOfService: function(service, hostComponents) {
+ const updatedService = {};
+ for (let i in App.serviceMapper.config) {
+ if (service.get(stringUtils.underScoreToCamelCase(i)) !== undefined) {
+ updatedService[i] = service.get(stringUtils.underScoreToCamelCase(i));
+ }
+ }
+ updatedService.host_components = hostComponents;
+ App.store.safeLoad(App.Service, updatedService);
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/models/host_component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/host_component.js b/ambari-web/app/models/host_component.js
index cdcf991..7217dbf 100644
--- a/ambari-web/app/models/host_component.js
+++ b/ambari-web/app/models/host_component.js
@@ -195,6 +195,15 @@ App.HostComponent.getCount = function (componentName, type) {
}
};
+/**
+ * @param {string} componentName
+ * @param {string} hostName
+ * @returns {string}
+ */
+App.HostComponent.getId = function(componentName, hostName) {
+ return componentName + '_' + hostName;
+};
+
App.HostComponentStatus = {
started: "STARTED",
starting: "STARTING",
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 5d7108f..e6dbc06 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -1351,7 +1351,7 @@ var urls = {
}
},
'cluster.load_cluster_name': {
- 'real': '/clusters?fields=Clusters/security_type',
+ 'real': '/clusters?fields=Clusters/security_type,Clusters/cluster_id',
'mock': '/data/clusters/info.json'
},
'cluster.load_last_upgrade': {
@@ -2287,7 +2287,7 @@ var urls = {
mock: '/data/users/privileges_{userName}.json'
},
'router.login.clusters': {
- 'real': '/clusters?fields=Clusters/provisioning_state,Clusters/security_type',
+ 'real': '/clusters?fields=Clusters/provisioning_state,Clusters/security_type,Clusters/cluster_id',
'mock': '/data/clusters/info.json'
},
'router.login.message': {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/app/views/main/menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/menu.js b/ambari-web/app/views/main/menu.js
index 6e79aba..d423402 100644
--- a/ambari-web/app/views/main/menu.js
+++ b/ambari-web/app/views/main/menu.js
@@ -156,7 +156,7 @@ App.SideNavServiceMenuView = Em.CollectionView.extend({
return App.router.get('mainServiceController.content').filter(function (item) {
return !this.get('disabledServices').contains(item.get('id'));
}, this);
- }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
+ }.property('App.router.mainServiceController.content.length').volatile(),
didInsertElement:function () {
App.router.location.addObserver('lastSetURL', this, 'renderOnRoute');
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/test/controllers/global/cluster_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/global/cluster_controller_test.js b/ambari-web/test/controllers/global/cluster_controller_test.js
index 170ed78..4dc8a19 100644
--- a/ambari-web/test/controllers/global/cluster_controller_test.js
+++ b/ambari-web/test/controllers/global/cluster_controller_test.js
@@ -122,7 +122,9 @@ describe('App.clusterController', function () {
{
"Clusters": {
"cluster_name": "tdk",
- "version": "HDP-1.3.0"
+ "version": "HDP-1.3.0",
+ "security_type": "KERBEROS",
+ "cluster_id": 1
}
}
]
@@ -130,6 +132,8 @@ describe('App.clusterController', function () {
it('Check cluster', function () {
controller.reloadSuccessCallback(testData);
expect(App.get('clusterName')).to.equal('tdk');
+ expect(App.get('clusterId')).to.equal(1);
+ expect(App.get('isKerberosEnabled')).to.be.true;
expect(App.get('currentStackVersion')).to.equal('HDP-1.3.0');
});
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/test/controllers/global/update_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/global/update_controller_test.js b/ambari-web/test/controllers/global/update_controller_test.js
index eafa032..0725944 100644
--- a/ambari-web/test/controllers/global/update_controller_test.js
+++ b/ambari-web/test/controllers/global/update_controller_test.js
@@ -71,6 +71,7 @@ describe('App.UpdateController', function () {
expect(App.updater.run.called).to.equal(false);
expect(App.StompClient.unsubscribe.calledWith('/events/hostcomponents')).to.be.true;
expect(App.StompClient.unsubscribe.calledWith('/events/alerts')).to.be.true;
+ expect(App.StompClient.unsubscribe.calledWith('/events/topologies')).to.be.true;
});
it('isWorking = true', function () {
@@ -78,6 +79,7 @@ describe('App.UpdateController', function () {
expect(App.updater.run.callCount).to.equal(12);
expect(App.StompClient.subscribe.calledWith('/events/hostcomponents')).to.be.true;
expect(App.StompClient.subscribe.calledWith('/events/alerts')).to.be.true;
+ expect(App.StompClient.subscribe.calledWith('/events/topologies')).to.be.true;
});
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/test/controllers/main/host/details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js
index c7e1808..7827eb7 100644
--- a/ambari-web/test/controllers/main/host/details_test.js
+++ b/ambari-web/test/controllers/main/host/details_test.js
@@ -2539,22 +2539,13 @@ describe('App.MainHostDetailsController', function () {
};
beforeEach(function () {
- sinon.stub(controller, 'removeHostComponentModel', Em.K);
controller.set('_deletedHostComponentResult', {});
controller._doDeleteHostComponentSuccessCallback({}, {}, data);
});
- afterEach(function () {
- controller.removeHostComponentModel.restore();
- });
-
it('should reset `_deletedHostComponentResult`', function () {
expect(controller.get('_deletedHostComponentResult')).to.be.null;
});
-
- it('should call `removeHostComponentModel` with correct params', function () {
- expect(controller.removeHostComponentModel.calledWith('COMPONENT', 'h1')).to.be.true;
- });
});
describe('#upgradeComponentSuccessCallback()', function () {
@@ -3328,42 +3319,6 @@ describe('App.MainHostDetailsController', function () {
});
- describe("#removeHostComponentModel()", function () {
-
- beforeEach(function () {
- App.cache.services = [
- {
- ServiceInfo: {
- service_name: 'S1'
- },
- host_components: ['C1_host1']
- }
- ];
- sinon.stub(App.HostComponent, 'find').returns([
- Em.Object.create({
- id: 'C1_host1',
- componentName: 'C1',
- hostName: 'host1',
- service: Em.Object.create({
- serviceName: 'S1'
- })
- })
- ]);
- sinon.stub(App.serviceMapper, 'deleteRecord', Em.K);
- controller.removeHostComponentModel('C1', 'host1');
- });
- afterEach(function () {
- App.HostComponent.find.restore();
- App.serviceMapper.deleteRecord.restore();
- });
- it("App.cache is updated", function () {
- expect(App.cache.services[0].host_components).to.be.empty;
- });
- it('Record is deleted', function () {
- expect(App.serviceMapper.deleteRecord.calledOnce).to.be.true;
- });
- });
-
describe("#parseNnCheckPointTime", function () {
var tests = [
{
http://git-wip-us.apache.org/repos/asf/ambari/blob/d986503c/ambari-web/test/mappers/socket/topology_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/socket/topology_mapper_test.js b/ambari-web/test/mappers/socket/topology_mapper_test.js
new file mode 100644
index 0000000..7ebaf75
--- /dev/null
+++ b/ambari-web/test/mappers/socket/topology_mapper_test.js
@@ -0,0 +1,201 @@
+/**
+ * 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');
+
+require('mappers/socket/topology_mapper');
+
+describe('App.topologyMapper', function () {
+ const mapper = App.topologyMapper;
+
+
+ describe('#map', function () {
+ const mockCtrl = {
+ updateHost: sinon.spy()
+ };
+ beforeEach(function () {
+ sinon.stub(mapper, 'applyComponentTopologyChanges');
+ sinon.stub(App.router, 'get').returns(mockCtrl);
+ App.set('clusterId', 1);
+ });
+ afterEach(function() {
+ mapper.applyComponentTopologyChanges.restore();
+ App.router.get.restore();
+ });
+ it('applyComponentTopologyChanges should be called', function () {
+ mapper.map({clusters: {1: {components: []}}, eventType: 'UPDATE'});
+ expect(mapper.applyComponentTopologyChanges.calledWith([], 'UPDATE')).to.be.true;
+ });
+ it('updateHost should be called', function () {
+ mapper.map({clusters: {1: {hosts: []}}, eventType: 'UPDATE'});
+ expect(mockCtrl.updateHost.calledWith(Em.K, null, true)).to.be.true;
+ });
+ });
+
+ describe('#applyComponentTopologyChanges', function () {
+ beforeEach(function () {
+ sinon.stub(mapper, 'addServiceIfNew');
+ sinon.stub(mapper, 'createHostComponent');
+ sinon.stub(mapper, 'deleteHostComponent');
+ sinon.stub(mapper, 'deleteServiceIfHasNoComponents');
+ });
+ afterEach(function() {
+ mapper.addServiceIfNew.restore();
+ mapper.createHostComponent.restore();
+ mapper.deleteHostComponent.restore();
+ mapper.deleteServiceIfHasNoComponents.restore();
+ });
+ it('CREATE component event', function () {
+ const components = [
+ {
+ hostNames: ['host1'],
+ serviceName: 'S1',
+ version: 'UNKNOWN',
+ publicHostNames: ['public1']
+ }
+ ];
+ mapper.applyComponentTopologyChanges(components, 'UPDATE');
+ expect(mapper.addServiceIfNew.calledWith('S1')).to.be.true;
+ expect(mapper.createHostComponent.calledWith(components[0], 'host1', 'public1')).to.be.true;
+ });
+
+ it('DELETE component event', function () {
+ const components = [
+ {
+ hostNames: ['host1'],
+ serviceName: 'S1'
+ }
+ ];
+ mapper.applyComponentTopologyChanges(components, 'DELETE');
+ expect(mapper.deleteHostComponent.calledWith(components[0], 'host1')).to.be.true;
+ expect(mapper.deleteServiceIfHasNoComponents.calledWith('S1')).to.be.true;
+ });
+ });
+
+ describe('#addServiceIfNew', function () {
+ beforeEach(function () {
+ sinon.stub(App.Service, 'find').returns(Em.Object.create({isLoaded: false}));
+ sinon.stub(App.store, 'safeLoad');
+ });
+ afterEach(function() {
+ App.Service.find.restore();
+ App.store.safeLoad.restore();
+ });
+ it('should load service if it does not exist yet', function () {
+ mapper.addServiceIfNew('S1');
+ expect(App.store.safeLoad.calledOnce).to.be.true;
+ });
+ });
+
+ describe('#deleteServiceIfHasNoComponents', function () {
+ beforeEach(function () {
+ sinon.stub(App.Service, 'find').returns(Em.Object.create({isLoaded: true, hostComponents: []}));
+ sinon.stub(mapper, 'deleteRecord');
+ });
+ afterEach(function() {
+ App.Service.find.restore();
+ mapper.deleteRecord.restore();
+ });
+ it('should delete service record', function () {
+ mapper.deleteServiceIfHasNoComponents('S1');
+ expect(mapper.deleteRecord.calledOnce).to.be.true;
+ });
+ });
+
+ describe('#deleteHostComponent', function () {
+ beforeEach(function () {
+ sinon.stub(App.HostComponent, 'find').returns(Em.Object.create({isLoaded: true}));
+ sinon.stub(mapper, 'deleteRecord');
+ sinon.stub(mapper, 'updateHostComponentsOfHost');
+ sinon.stub(mapper, 'updateHostComponentsOfService');
+ sinon.stub(App.Host, 'find').returns(Em.Object.create({hostComponents: [{id: 'C1_host1'}]}));
+ sinon.stub(App.Service, 'find').returns(Em.Object.create({hostComponents: [{id: 'C1_host1'}]}));
+ mapper.deleteHostComponent({componentName: 'C1'}, 'host1');
+ });
+ afterEach(function() {
+ App.HostComponent.find.restore();
+ mapper.deleteRecord.restore();
+ mapper.updateHostComponentsOfHost.restore();
+ mapper.updateHostComponentsOfService.restore();
+ App.Host.find.restore();
+ App.Service.find.restore();
+ });
+ it('deleteRecord should be called', function () {
+ expect(mapper.deleteRecord.calledOnce).to.be.true;
+ });
+ it('updateHostComponentsOfHost should be called', function () {
+ expect(mapper.updateHostComponentsOfHost.calledWith(Em.Object.create({hostComponents: [{id: 'C1_host1'}]}), [])).to.be.true;
+ });
+ it('updateHostComponentsOfService should be called', function () {
+ expect(mapper.updateHostComponentsOfService.calledWith(Em.Object.create({hostComponents: [{id: 'C1_host1'}]}), [])).to.be.true;
+ });
+ });
+
+ describe('#createHostComponent', function () {
+ beforeEach(function () {
+ sinon.stub(App.store, 'safeLoad');
+ sinon.stub(mapper, 'updateHostComponentsOfHost');
+ sinon.stub(mapper, 'updateHostComponentsOfService');
+ sinon.stub(App.Host, 'find').returns(Em.Object.create({hostComponents: [], isLoaded: true}));
+ sinon.stub(App.Service, 'find').returns(Em.Object.create({hostComponents: []}));
+ mapper.createHostComponent({componentName: 'C1'}, 'host1');
+ });
+ afterEach(function() {
+ App.store.safeLoad.restore();
+ mapper.updateHostComponentsOfHost.restore();
+ mapper.updateHostComponentsOfService.restore();
+ App.Host.find.restore();
+ App.Service.find.restore();
+ });
+ it('deleteRecord should be called', function () {
+ expect(App.store.safeLoad.calledOnce).to.be.true;
+ });
+ it('updateHostComponentsOfHost should be called', function () {
+ expect(mapper.updateHostComponentsOfHost.calledOnce).to.be.true;
+ });
+ it('updateHostComponentsOfService should be called', function () {
+ expect(mapper.updateHostComponentsOfService.calledOnce).to.be.true;
+ });
+ });
+
+ describe('#updateHostComponentsOfHost', function () {
+ beforeEach(function () {
+ sinon.stub(App.store, 'safeLoad');
+ });
+ afterEach(function() {
+ App.store.safeLoad.restore();
+ });
+ it('App.store.safeLoad should be called', function () {
+ mapper.updateHostComponentsOfHost(Em.Object.create({id: 1}), [{id: 2}]);
+ expect(App.store.safeLoad.calledWith(App.Host, {id: 1, hostComponents: [{id: 2}]}));
+ });
+ });
+
+ describe('#updateHostComponentsOfService', function () {
+ beforeEach(function () {
+ sinon.stub(App.store, 'safeLoad');
+ });
+ afterEach(function() {
+ App.store.safeLoad.restore();
+ });
+ it('App.store.safeLoad should be called', function () {
+ mapper.updateHostComponentsOfService(Em.Object.create({id: 1}), [{id: 2}]);
+ expect(App.store.safeLoad.calledWith(App.Service, {id: 1, hostComponents: [{id: 2}]}));
+ });
+ });
+});