You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jg...@apache.org on 2018/06/07 17:36:25 UTC
[ambari] branch branch-feature-AMBARI-14714-mpack-advisor updated:
[AMBARI-23643] Mpack Advisor integration in Install Wizard (#1487)
This is an automated email from the ASF dual-hosted git repository.
jgolieb pushed a commit to branch branch-feature-AMBARI-14714-mpack-advisor
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714-mpack-advisor by this push:
new 85ecd56 [AMBARI-23643] Mpack Advisor integration in Install Wizard (#1487)
85ecd56 is described below
commit 85ecd5675e290af840370e377423a19ff80c23ea
Author: Jason Golieb <j...@golieb.net>
AuthorDate: Thu Jun 7 13:36:12 2018 -0400
[AMBARI-23643] Mpack Advisor integration in Install Wizard (#1487)
* Remove references to deleted unit test files and fix broken tests.
* [AMBARI-23969] UI should load stack services from multiple mpacks. (#1403)
* [AMBARI-23969] UI should load stack services from multiple mpacks.
* Removed stack version number
* AMBARI-23972. Update code for : (1). 'mpack-recommendations' directory creation and (2). putting 'mpack_advisor_wrapper.py' in '/var/lib/ambari-server/resources/scripts/' folder.
* AMBARI-14714. Fix some unit tests
* AMBARI-14714. Fix ServiceResourceProviderTest
* AMBARI-23746. Cannot create same named service in different service groups in same request
* AMBARI-23746. Cannot create same named component in different service groups in same request
* AMBARI-22875. Service group name mismatch
* AMBARI-23746. Cannot query services with same name
* AMBARI-23746. Use List for componentID duplicate check
* AMBARI-23987. Set 'skip.service.checks' = true during deploy.
* Clear clusterData when user is not logged in.
* [AMBARI-23993] Mpack Instance Manager should create pid dir and log dir for each instance (#1424)
* AMBARI-23993: Mpack Instance Manager should create pid dir and log dir for each instance
* AMBARI-23993: Mpack Instance Manager should create pid dir and log dir for each instance
* AMBARI-23993-2: Mpack Instance Manager should create pid dir and log dir for each instance: add get_log_dir and get_run_dir to import
* AMBARI-23999 Remove hardcoded logic in UI to create HDPCORE service group and create multiple service groups
* AMBARI-24011: Add workaround to hide client modules in the dashboard (jluniya) (#1443)
Change-Id: Ie69b4e0ca654d59952807694cf2f3f24d6b74c0d
* BUG-104321: Python Mpack Advisor should return MpackInstance block during Host Component Layout Recommendation
* AMBARI-24025 Display Mpack Info on Service Summary Page
* AMBARI-24025 Display Mpack Info on Service Summary Page
* AMBARI-23986. Host components API call doesn't return all host components (#1450)
* AMBARI-24030. Fixes the following : 1. Reading the Node Manager Host (nmHost) correctly. 2. Comments the incorrectly implemented fn : isServiceDeployed().
* AMBARI-24025 Display Mpack Info on Service Summary Page
* [AMBARI-24039] Quicklinks for HBASE are not displayed.
* [AMBARI-24033] Use servicegroup api instead of service to show installed services in the UI.
* AMBARI-14714. Fix some unit tests (#1464)
* AMBARI-24046. Fix the incorrect string from config_name to config-name in mpack_advisor.py (#1480)
* [AMBARI-23643] Mpack Advisor integration in Install wizard.
---
ambari-web/app/controllers/installer.js | 1 +
ambari-web/app/controllers/wizard.js | 83 ++++++++++++++++++-
.../app/controllers/wizard/step7_controller.js | 2 -
.../app/controllers/wizard/step8_controller.js | 92 ++++++++++++----------
ambari-web/app/mixins/common/blueprint.js | 6 +-
.../app/mixins/common/configs/enhanced_configs.js | 52 ++++++------
.../hosts/host_component_recommendation_mixin.js | 46 ++++++-----
.../hosts/host_component_validation_mixin.js | 46 +++++++----
ambari-web/app/mixins/common/serverValidator.js | 87 ++++++++------------
.../app/mixins/wizard/assign_master_components.js | 43 ++++------
ambari-web/app/utils/ajax/ajax.js | 36 +++++----
11 files changed, 289 insertions(+), 205 deletions(-)
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index 06c41f0..c2ca8cf 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -387,6 +387,7 @@ App.InstallerController = App.WizardController.extend(App.Persist, {
},
loadCurrentHostGroups: function () {
+ this.set("content.recommendations", this.getDBProperty('recommendations'));
this.set("content.recommendationsHostGroups", this.getDBProperty('recommendationsHostGroups'));
},
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index feccd7d..cb3fcf5 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -18,7 +18,7 @@
var App = require('app');
-
+var blueprintUtils = require('utils/blueprint');
require('models/host');
App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingMixin, {
@@ -1705,5 +1705,86 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
});
}
});
+ },
+
+ /**
+ * Return mpack_instances data needed for mpack advisor recommendations requests.
+ * This is basically service groups formatted as required by the mpack advisor API.
+ */
+ getMpackInstances: function (configs) {
+ const mpackInstances = {};
+ const selectedServices = this.get('content.selectedServices');
+
+ selectedServices.forEach(service => {
+ //these will be defined by the user in the future
+ const serviceGroupName = service.mpackName;
+ const serviceInstanceName = service.name;
+
+ if (!mpackInstances[serviceGroupName]) {
+ mpackInstances[serviceGroupName] = {
+ name: serviceGroupName,
+ type: service.mpackName,
+ version: service.mpackVersion,
+ service_instances: []
+ };
+ }
+
+ const serviceInstance = {
+ name: serviceInstanceName,
+ type: service.name
+ };
+
+ //configs will be passed if we are building a request for configs recommendations/validations
+ //it will not be passed if we are building a request for host recommendations/validations
+ if (configs) {
+ const configurations = this.getConfigsForServiceInstance(service.name, service.mpackName, service.mpackVersion, null, configs);
+ if (configurations) {
+ serviceInstance.configurations = configurations;
+ }
+ }
+
+ mpackInstances[serviceGroupName].service_instances.push(serviceInstance);
+ });
+
+ const mpack_instances = [];
+ for (let prop in mpackInstances) {
+ mpack_instances.push(mpackInstances[prop]);
+ }
+
+ return mpack_instances;
+ },
+
+ /**
+ * Returns configs specific to the given service, stack, and stack version formatted as a blueprint fragment.
+ * This is used to build out the Mpack Advisor config recommendation/validation request.
+ * This is also used to get the "MISC" configs (configs not specific to a service).
+ * If we want to filter these down to just a subset, such as the "cluster-setttings.xml" configs, pass the corresponding "fileName" value.
+ *
+ * @param {string} serviceName The name/type of the service to get configs for.
+ * @param {string} stackName The name of the stack/mpack to get configs for.
+ * @param {string} stackVersion The version of the stack/mpack to get configs for.
+ * @param {string} filename The file where the configs originate, such as "cluster-settings.xml". Ignored if set to null.
+ * @param {array} configs List of configs to be filtered. This is typically all configs loaded from the stack information.
+ */
+ getConfigsForServiceInstance: function (serviceName, stackName, stackVersion, fileName, configs) {
+ const serviceConfigs = configs.findProperty('serviceName', serviceName);
+
+ if (serviceConfigs) {
+ let serviceInstanceConfigs;
+ if (stackName && stackVersion) {
+ serviceInstanceConfigs = serviceConfigs.configs.filter(config => (config.stackName === stackName && config.stackVersion === stackVersion) || config.stackName === undefined);
+ } else {
+ serviceInstanceConfigs = serviceConfigs.configs;
+ }
+
+ if (fileName) {
+ serviceInstanceConfigs = serviceInstanceConfigs.filterProperty('fileName', fileName);
+ }
+
+ serviceConfigs.set('configs', serviceInstanceConfigs);
+ return blueprintUtils.buildConfigsJSON([serviceConfigs]); //buildConfigsJSON() expects an array
+ }
+
+ return null;
}
});
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index e0cd249..c1f376a 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -617,13 +617,11 @@ App.WizardStep7Controller = App.WizardStepController.extend(App.ServerValidatorM
self.loadConfigRecommendations(null, self.completeConfigLoading.bind(self));
});
}
-
} else {
console.timeEnd('applyServicesConfigs execution time: ');
console.time('loadConfigRecommendations execution time: ');
self.loadConfigRecommendations(null, self.completeConfigLoading.bind(self));
}
-
},
/**
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index 90c3a3b..8dd78b6 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -971,7 +971,7 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
const serviceGroups = mpacks.map(mpack => ({
"ServiceGroupInfo": {
"service_group_name": mpack.name,
- "version": mpack.id
+ "version": `${mpack.name}-${mpack.version}`
}
})
);
@@ -1645,53 +1645,59 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
* @method createNotification
*/
createNotification: function () {
- if (!this.get('isInstaller')) return;
- var miscConfigs = this.get('configs').filterProperty('serviceName', 'MISC'),
- createNotification = miscConfigs.findProperty('name', 'create_notification').value;
- if (createNotification !== 'yes') return;
- var predefinedNotificationConfigNames = require('data/configs/alert_notification').mapProperty('name'),
- configsForNotification = this.get('configs').filterProperty('filename', 'alert_notification');
- var properties = {},
- names = [
- 'ambari.dispatch.recipients',
- 'mail.smtp.host',
- 'mail.smtp.port',
- 'mail.smtp.from',
- 'mail.smtp.starttls.enable',
- 'mail.smtp.startssl.enable'
- ];
- if (miscConfigs.findProperty('name', 'smtp_use_auth').value == 'true') { // yes, it's not converted to boolean
- names.pushObjects(['ambari.dispatch.credential.username', 'ambari.dispatch.credential.password']);
- }
+ if (this.get('isInstaller')) {
+ const miscConfigs = this.get('configs').filterProperty('serviceName', 'MISC');
+ if (miscConfigs) {
+ const createNotification = miscConfigs.findProperty('name', 'create_notification');
+ if (createNotification && createNotification.value === 'yes') {
+ const predefinedNotificationConfigNames = require('data/configs/alert_notification').mapProperty('name');
+ const configsForNotification = this.get('configs').filterProperty('filename', 'alert_notification');
+ const properties = {};
+ const names = [
+ 'ambari.dispatch.recipients',
+ 'mail.smtp.host',
+ 'mail.smtp.port',
+ 'mail.smtp.from',
+ 'mail.smtp.starttls.enable',
+ 'mail.smtp.startssl.enable'
+ ];
+
+ if (miscConfigs.findProperty('name', 'smtp_use_auth').value == 'true') { // yes, it's not converted to boolean
+ names.pushObjects(['ambari.dispatch.credential.username', 'ambari.dispatch.credential.password']);
+ }
- names.forEach(function (name) {
- properties[name] = miscConfigs.findProperty('name', name).value;
- });
+ names.forEach(function (name) {
+ properties[name] = miscConfigs.findProperty('name', name).value;
+ });
- properties['ambari.dispatch.recipients'] = properties['ambari.dispatch.recipients'].replace(/\s/g, '').split(',');
+ properties['ambari.dispatch.recipients'] = properties['ambari.dispatch.recipients'].replace(/\s/g, '').split(',');
- configsForNotification.forEach(function (config) {
- if (predefinedNotificationConfigNames.contains(config.name)) return;
- properties[config.name] = config.value;
- });
+ configsForNotification.forEach(function (config) {
+ if (predefinedNotificationConfigNames.contains(config.name)) return;
+ properties[config.name] = config.value;
+ });
- var apiObject = {
- AlertTarget: {
- name: 'Initial Notification',
- description: 'Notification created during cluster installing',
- global: true,
- notification_type: 'EMAIL',
- alert_states: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'],
- properties: properties
- }
- };
- this.addRequestToAjaxQueue({
- name: 'alerts.create_alert_notification',
- data: {
- urlParams: 'overwrite_existing=true',
- data: apiObject
+ var apiObject = {
+ AlertTarget: {
+ name: 'Initial Notification',
+ description: 'Notification created during cluster installing',
+ global: true,
+ notification_type: 'EMAIL',
+ alert_states: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'],
+ properties: properties
+ }
+ };
+
+ this.addRequestToAjaxQueue({
+ name: 'alerts.create_alert_notification',
+ data: {
+ urlParams: 'overwrite_existing=true',
+ data: apiObject
+ }
+ });
+ }
}
- });
+ }
},
/**
diff --git a/ambari-web/app/mixins/common/blueprint.js b/ambari-web/app/mixins/common/blueprint.js
index 3df3b1a..cbc633d 100644
--- a/ambari-web/app/mixins/common/blueprint.js
+++ b/ambari-web/app/mixins/common/blueprint.js
@@ -44,7 +44,11 @@ App.BlueprintMixin = Em.Mixin.create({
res.blueprint.host_groups.push({
name: group_name,
components: mappedComponents[host] ? mappedComponents[host].map(function (c) {
- return { name: Em.get(c, 'componentName') };
+ return {
+ mpack_instance: Em.get(c, 'mpackInstance'),
+ service_instance: Em.get(c, 'serviceInstance'),
+ name: Em.get(c, 'componentName')
+ };
}) : []
});
diff --git a/ambari-web/app/mixins/common/configs/enhanced_configs.js b/ambari-web/app/mixins/common/configs/enhanced_configs.js
index 92d1012..7d2f7a2 100644
--- a/ambari-web/app/mixins/common/configs/enhanced_configs.js
+++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js
@@ -219,7 +219,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
if (requiredTags.length) {
this.loadAdditionalSites(requiredTags, stepConfigs, recommendations, dataToSend, onComplete);
} else {
- this.addRecommendationRequestParams(recommendations, dataToSend, stepConfigs);
+ dataToSend.recommendations = this.addRequestedConfigs(recommendations, stepConfigs);
return this.getRecommendationsRequest(dataToSend, onComplete);
}
} else {
@@ -231,14 +231,22 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
},
/**
- *
+ * Adds the configs to include in the request to the recommendations.blueprint object in the format required.
+ *
* @param recommendations
- * @param dataToSend
- * @param stepConfigs
+ * @param configs
*/
- addRecommendationRequestParams: function(recommendations, dataToSend, stepConfigs) {
- recommendations.blueprint.configurations = blueprintUtils.buildConfigsJSON(stepConfigs);
- dataToSend.recommendations = recommendations;
+ addRequestedConfigs: function (recommendations, configs) {
+ const wizardController = this.get('wizardController');
+
+ if (wizardController) {
+ recommendations.blueprint.configurations = wizardController.getConfigsForServiceInstance('MISC', null, null, 'cluster-settings.xml', configs);
+ recommendations.blueprint.mpack_instances = wizardController.getMpackInstances(configs);
+ } else {
+ App.get('mpackInstances'); //TODO: implement this property on the App object along with a routine to populate it at startup, similar to App.allHostNames
+ }
+
+ return recommendations;
},
/**
@@ -253,7 +261,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
App.config.getConfigsByTypes(sites).done(function (configs) {
stepConfigs = stepConfigs.concat(configs);
- self.addRecommendationRequestParams(recommendations, dataToSend, stepConfigs);
+ dataToSend.recommendations = self.addRequestedConfigs(recommendations, stepConfigs);
self.getRecommendationsRequest(dataToSend, onComplete);
});
},
@@ -282,37 +290,24 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
const params = {
recommend: updateDependencies ? 'configuration-dependencies' : 'configurations',
hosts: this.get('hostNames'),
- services: this.get('serviceNames'),
changed_configurations: updateDependencies ? changedConfigs : undefined
};
- //TODO - mpacks: Hard coded to use first mpack. Change when we are installing multiple mpacks.
- const selectedMpacks = this.get('content.selectedMpacks');
-
- if (selectedMpacks) {
- params.stackName = selectedMpacks[0].name;
- params.stackVersion = selectedMpacks[0].version;
- }
-
return params;
},
getRecommendationsRequest: function (dataToSend, callback) {
const self = this;
this.set('recommendationsInProgress', true);
- const stackVersionUrl = App.getStackVersionUrl(dataToSend.stackName, dataToSend.stackVersion) || App.get('stackVersionURL');
return App.ajax.send({
- name: 'config.recommendations',
+ name: 'mpack.advisor.recommendations',
sender: self,
data: {
- stackVersionUrl: stackVersionUrl,
- dataToSend: {
+ data: {
recommend: dataToSend.recommend,
hosts: dataToSend.hosts,
- services: dataToSend.services,
changed_configurations: dataToSend.changed_configurations,
- user_context: dataToSend.user_context,
recommendations: dataToSend.recommendations
}
},
@@ -402,7 +397,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
* @method dependenciesSuccess
*/
loadRecommendationsSuccess: function (data, opt, params) {
- this._saveRecommendedValues(data, params.dataToSend.changed_configurations);
+ this._saveRecommendedValues(data, params.data.changed_configurations);
if (this.isConfigHasInitialState()) {
/** clearing all recommendations info **/
this.undoRedoRecommended(this.get('recommendations'), false);
@@ -445,12 +440,11 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
* @private
*/
_saveRecommendedValues: function(data, changedConfigs) {
- Em.assert('invalid data - `data.resources[0].recommendations.blueprint.configurations` not defined ', data && data.resources[0] && Em.get(data.resources[0], 'recommendations.blueprint.configurations'));
var recommendations = data.resources[0].recommendations;
if (recommendations['config-groups'] && this.get('selectedConfigGroup') && !this.get('selectedConfigGroup.isDefault')) {
this.saveConfigGroupsRecommendations(recommendations, changedConfigs);
} else {
- var configObject = recommendations.blueprint.configurations;
+ var configObject = this.getAllRecommendedConfigs(recommendations);
this.get('stepConfigs').forEach(function(stepConfig) {
this.updateConfigsByRecommendations(configObject, stepConfig.get('configs'), changedConfigs);
}, this);
@@ -459,6 +453,12 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
this.cleanUpRecommendations();
},
+ getAllRecommendedConfigs: function (recommendations) {
+ const serviceInstances = recommendations.blueprint.mpack_instances.reduce((result, value) => result.concat(value.service_instances), []);
+ const configs = serviceInstances.reduce((result, value) => Object.assign(result, value.configurations), {});
+ return configs;
+ },
+
/**
*
* @param {object} recommendations
diff --git a/ambari-web/app/mixins/common/hosts/host_component_recommendation_mixin.js b/ambari-web/app/mixins/common/hosts/host_component_recommendation_mixin.js
index e0cbb3f..1d151a4 100644
--- a/ambari-web/app/mixins/common/hosts/host_component_recommendation_mixin.js
+++ b/ambari-web/app/mixins/common/hosts/host_component_recommendation_mixin.js
@@ -21,26 +21,29 @@ require('mixins/common/blueprint');
var App = require('app');
/**
- * @typedef {object} RecommendComponentObject
- * @property {string} componentName name of the component
- * @property {number} [size=0] desired components size
- * @property {string[]} [hosts=[]] hosts assigned to component
+ * @typedef {object} ServiceInstanceObject
+ * @property {string} name name of the service instance
+ * @property {string} type of the service instance (usually the name of the service, i.e. ZOOKEEPER)
+ */
+
+/**
+ * @typedef {object} MpackInstanceObject
+ * @property {string} name name of the mpack instances (usually the name of a service group)
+ * @property {string} type of the mpack instance (usually the name of the mpack, i.e. HDPCORE)
+ * @property {string} version of the mpack
+ * @property {ServiceInstanceObject[]} service_instances list of service instances
*/
/**
* @typedef {object} HostComponentRecommendationOptions
* @property {string[]} hosts list of host names, in most cases all available host names
- * @property {RecommendComponentObject[]} components list of components
- * @property {string[]} services list of service names
- * @property {object} [blueprint=null] when null blueprint will be created by <code>HostComponentRecommendationOptions.components</code> attribute
+ * @property {MpackInstanceObject[]} mpack_instances list of mpack instances
*/
/**
* @typedef {object} HostRecommendationRequestData
- * @property {string} stackVersionUrl stack version url
- * @property {string[]} hosts host names
- * @property {string[]} services service names
* @property {string} recommend recommendation type e.g. 'host_groups'
+ * @property {string[]} hosts list of host names
* @property {object} recommendations blueprint object
*/
@@ -58,7 +61,6 @@ App.HostComponentRecommendationMixin = Em.Mixin.create(App.BlueprintMixin, {
*/
getRecommendedHosts: function(options) {
var opts = $.extend({
- services: [],
hosts: [],
components: [],
blueprint: null
@@ -77,11 +79,12 @@ App.HostComponentRecommendationMixin = Em.Mixin.create(App.BlueprintMixin, {
var res = [];
if (!components) return [];
components.forEach(function(component) {
- var componentName = Em.get(component, 'componentName');
if (Em.get(component, 'hosts.length')) {
Em.get(component, 'hosts').forEach(function(hostName) {
res.push(Em.Object.create({
- componentName: componentName,
+ componentName: Em.get(component, 'componentName'),
+ mpackInstance: Em.get(component, 'mpackInstance'),
+ serviceInstance: Em.get(component, 'serviceInstance'),
hostName: hostName
}));
});
@@ -97,17 +100,17 @@ App.HostComponentRecommendationMixin = Em.Mixin.create(App.BlueprintMixin, {
* @method getRecommendationRequestData
*/
getRecommendationRequestData: function(options) {
- const stackVersionUrl = App.getStackVersionUrl(options.stackName, options.stackVersion) || App.get('stackVersionURL');
-
- return {
- stackVersionUrl: stackVersionUrl,
- dataToSend: {
+ const requestData = {
+ data: {
recommend: 'host_groups',
hosts: options.hosts,
- services: options.services,
recommendations: options.blueprint || this.getComponentsBlueprint(options.components)
}
- };
+ }
+
+ requestData.data.recommendations.blueprint.mpack_instances = options.mpack_instances;
+
+ return requestData;
},
/**
@@ -118,7 +121,7 @@ App.HostComponentRecommendationMixin = Em.Mixin.create(App.BlueprintMixin, {
*/
loadComponentsRecommendationsFromServer: function(recommendationData) {
return App.ajax.send({
- name: 'config.recommendations',
+ name: 'mpack.advisor.recommendations',
sender: this,
data: recommendationData,
success: 'loadRecommendationsSuccessCallback',
@@ -126,6 +129,7 @@ App.HostComponentRecommendationMixin = Em.Mixin.create(App.BlueprintMixin, {
});
},
+ //these can be overridden in the derived object
loadRecommendationsSuccessCallback: function() {},
loadRecommendationsErrorCallback: function() {}
});
diff --git a/ambari-web/app/mixins/common/hosts/host_component_validation_mixin.js b/ambari-web/app/mixins/common/hosts/host_component_validation_mixin.js
index a7e752c..ee7fb84 100644
--- a/ambari-web/app/mixins/common/hosts/host_component_validation_mixin.js
+++ b/ambari-web/app/mixins/common/hosts/host_component_validation_mixin.js
@@ -21,12 +21,23 @@ require('mixins/common/blueprint');
var App = require('app');
/**
+ * @typedef {object} ServiceInstanceObject
+ * @property {string} name name of the service instance
+ * @property {string} type of the service instance (usually the name of the service, i.e. ZOOKEEPER)
+ */
+
+/**
+ * @typedef {object} MpackInstanceObject
+ * @property {string} name name of the mpack instances (usually the name of a service group)
+ * @property {string} type of the mpack instance (usually the name of the mpack, i.e. HDPCORE)
+ * @property {string} version of the mpack
+ * @property {ServiceInstanceObject[]} service_instances list of service instances
+ */
+
+/**
* @typedef {object} HostValidationRequestData
- * @property {string} stackVersionUrl stack version url
* @property {string[]} hosts host names
- * @property {string[]} services service names
- * @property {string} validate validation type e.g. 'host_groups'
- * @property {object} recommendations blueprint object
+ * @property {MpackInstanceObject[]} mpack_instances list of mpack instances
*/
App.HostComponentValidationMixin = Em.Mixin.create(App.BlueprintMixin, {
@@ -38,7 +49,6 @@ App.HostComponentValidationMixin = Em.Mixin.create(App.BlueprintMixin, {
*/
validateSelectedHostComponents: function(options) {
var opts = $.extend({
- services: [],
blueprint: null,
hosts: [],
components: []
@@ -57,11 +67,12 @@ App.HostComponentValidationMixin = Em.Mixin.create(App.BlueprintMixin, {
var res = [];
if (!components) return [];
components.forEach(function(component) {
- var componentName = Em.get(component, 'componentName');
if (Em.get(component, 'hosts.length')) {
Em.get(component, 'hosts').forEach(function(hostName) {
res.push(Em.Object.create({
- componentName: componentName,
+ componentName: Em.get(component, 'componentName'),
+ mpackInstance: Em.get(component, 'mpackInstance'),
+ serviceInstance: Em.get(component, 'serviceInstance'),
hostName: hostName
}));
});
@@ -76,15 +87,17 @@ App.HostComponentValidationMixin = Em.Mixin.create(App.BlueprintMixin, {
* @return {HostValidationRequestData}
*/
getHostComponentValidationParams: function(options) {
- const stackVersionUrl = App.getStackVersionUrl(options.stackName, options.stackVersion) || App.get('stackVersionURL');
-
- return {
- stackVersionUrl: stackVersionUrl,
- hosts: options.hosts,
- services: options.services,
- validate: 'host_groups',
- recommendations: options.blueprint || this.getComponentsBlueprint(options.components)
+ const requestData = {
+ data: {
+ validate: 'host_groups',
+ hosts: options.hosts,
+ recommendations: options.blueprint || this.getComponentsBlueprint(options.components)
+ }
};
+
+ requestData.data.recommendations.blueprint.mpack_instances = options.mpack_instances;
+
+ return requestData;
},
/**
@@ -95,7 +108,7 @@ App.HostComponentValidationMixin = Em.Mixin.create(App.BlueprintMixin, {
*/
getHostComponentValidationRequest: function(validationData) {
return App.ajax.send({
- name: 'config.validations',
+ name: 'mpack.advisor.validations',
sender: this,
data: validationData,
success: 'updateValidationsSuccessCallback',
@@ -103,6 +116,7 @@ App.HostComponentValidationMixin = Em.Mixin.create(App.BlueprintMixin, {
});
},
+ //these can be overridden in the derived object
updateValidationsSuccessCallback: function() {},
updateValidationsErrorCallback: function() {}
});
diff --git a/ambari-web/app/mixins/common/serverValidator.js b/ambari-web/app/mixins/common/serverValidator.js
index 4b40bb1..b8e069a 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -114,8 +114,21 @@ App.ServerValidatorMixin = Em.Mixin.create({
* @type {Array} of strings (hostNames)
*/
hostGroups: function() {
- return this.get('content.recommendationsHostGroups') || blueprintUtils.generateHostGroups(App.get('allHostNames'));
- }.property('content.recommendationsHostGroups', 'App.allHostNames', 'App.componentToBeAdded', 'App.componentToBeDeleted'),
+ const hostGroups = this.get('content.recommendationsHostGroups')
+ || this.get('content.recommendations')
+ || blueprintUtils.generateHostGroups(App.get('allHostNames'));
+
+ return hostGroups;
+ }.property('content.recommendationsHostGroups', 'content.recommendations', 'App.allHostNames', 'App.componentToBeAdded', 'App.componentToBeDeleted'),
+
+ getMpackInstances(configs) {
+ if (this.get('isWizard')) {
+ const wizardController = this.get('wizardController');
+ return wizardController.getMpackInstances(configs);
+ } else {
+ App.get('mpackInstances'); //TODO: implement this property on the App object along with a routine to populate it at startup, similar to App.allHostNames
+ }
+ },
/**
* controller that is child of this mixin has to contain stepConfigs
@@ -133,8 +146,7 @@ App.ServerValidatorMixin = Em.Mixin.create({
criticalIssues: []
}));
- const mpacks = this.get('content.selectedMpacks'); //TODO - mpacks
- this.runServerSideValidation(mpacks[0].name, mpacks[0].version).done(function() {
+ this.runServerSideValidation().done(function() {
if (self.get('configErrorList.issues.length') || self.get('configErrorList.criticalIssues.length')) {
App.showConfigValidationPopup(self.get('configErrorList'), primary, secondary, self);
} else {
@@ -152,25 +164,17 @@ App.ServerValidatorMixin = Em.Mixin.create({
* send request to validate configs
* @returns {*}
*/
- runServerSideValidation: function (stackName, stackVersion) {
- var self = this;
- var recommendations = this.get('hostGroups');
- var stepConfigs = this.get('stepConfigs');
- var dfd = $.Deferred();
-
- this.getBlueprintConfigurations(this.get('stepConfigs'))
- .done(function(blueprintConfigurations) {
- recommendations.blueprint.configurations = blueprintConfigurations;
- var request = self.validateSelectedConfigs({
- hosts: self.get('hostNames'),
- services: self.get('serviceNames'),
- blueprint: recommendations,
- stackName: stackName,
- stackVersion: stackVersion
- });
- self.set('validationRequest', request);
- request.done(dfd.resolve).fail(dfd.reject);
- });
+ runServerSideValidation: function () {
+ const dfd = $.Deferred();
+
+ const request = this.validateSelectedConfigs({
+ hosts: this.get('hostNames'),
+ blueprint: this.get('hostGroups')
+ });
+
+ this.set('validationRequest', request);
+ request.done(dfd.resolve).fail(dfd.reject);
+
return dfd.promise();
},
@@ -182,7 +186,6 @@ App.ServerValidatorMixin = Em.Mixin.create({
*/
validateSelectedConfigs: function(options) {
var opts = $.extend({
- services: [],
hosts: [],
blueprint: null
}, options || {});
@@ -197,7 +200,7 @@ App.ServerValidatorMixin = Em.Mixin.create({
*/
getServiceConfigsValidationRequest: function(validationData) {
return App.ajax.send({
- name: 'config.validations',
+ name: 'mpack.advisor.validations',
sender: this,
data: validationData,
success: 'validationSuccess',
@@ -211,36 +214,16 @@ App.ServerValidatorMixin = Em.Mixin.create({
* @returns {ConfigsValidationRequestData}
*/
getServiceConfigsValidationParams: function(options) {
- const stackVersionUrl = App.getStackVersionUrl(options.stackName, options.stackVersion) || App.get('stackVersionURL');
-
return {
- stackVersionUrl: stackVersionUrl,
- hosts: options.hosts,
- services: options.services,
- validate: 'configurations',
- recommendations: options.blueprint
+ data: {
+ validate: 'configurations',
+ hosts: options.hosts,
+ recommendations: options.blueprint
+ }
};
},
/**
- * Return JSON for blueprint configurations
- * @param {App.ServiceConfigs[]} serviceConfigs
- * @returns {*}
- */
- getBlueprintConfigurations: function (serviceConfigs) {
- var dfd = $.Deferred();
- // check if we have configs from 'cluster-env', if not, then load them, as they are mandatory for validation request
- if (!serviceConfigs.findProperty('serviceName', 'MISC')) {
- App.config.getConfigsByTypes([{site: 'cluster-env', serviceName: 'MISC'}]).done(function(configs) {
- dfd.resolve(blueprintUtils.buildConfigsJSON(serviceConfigs.concat(configs)));
- });
- } else {
- dfd.resolve(blueprintUtils.buildConfigsJSON(serviceConfigs));
- }
- return dfd.promise();
- },
-
- /**
* Creates config validation error object
*
* @param type - error type, see <code>errorTypes<code>
@@ -384,14 +367,12 @@ App.ServerValidatorMixin = Em.Mixin.create({
valueObserver: function () {
var self = this;
if (this.get('isInstallWizard') && this.get('currentTabName') === 'all-configurations') {
- const mpacks = this.get('content.selectedMpacks'); //TODO - mpacks
-
if (this.get('requestTimer')) clearTimeout(this.get('requestTimer'));
self.set('requestTimer', setTimeout(function () {
if (self.get('validationRequest')) {
self.get('validationRequest').abort();
}
- self.runServerSideValidation(mpacks[0].name, mpacks[0].version).done(function () {
+ self.runServerSideValidation().done(function () {
self.set('validationRequest', null);
self.set('requestTimer', 0);
});
diff --git a/ambari-web/app/mixins/wizard/assign_master_components.js b/ambari-web/app/mixins/wizard/assign_master_components.js
index d0b4bd9..ff878b2 100644
--- a/ambari-web/app/mixins/wizard/assign_master_components.js
+++ b/ambari-web/app/mixins/wizard/assign_master_components.js
@@ -465,23 +465,13 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
*/
getRecommendationRequestData: function(options) {
var res = this._super(options);
- res.dataToSend.services = this.getCurrentServiceNames();
if (!this.get('isInstallerWizard')) {
- res.dataToSend.recommendations = this.getCurrentMasterSlaveBlueprint();
+ res.data.recommendations = this.getCurrentMasterSlaveBlueprint();
}
return res;
},
/**
- * @override App.HostComponentRecommendationMixin
- */
- getHostComponentValidationParams: function(options) {
- var res = this._super(options);
- res.services = this.getCurrentServiceNames();
- return res;
- },
-
- /**
* Returns selected and installed service names
* @return {string[]}
*/
@@ -530,12 +520,9 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
self.set('backFromNextStep', true);
}
- //TODO - mpacks: Hard-coding to only ask for recommendations for first mpack. Need to change this when we are installing multiple mpacks.
- const selectedMpacks = self.get('content.selectedMpacks');
self.getRecommendedHosts({
- stackName: selectedMpacks[0].name,
- stackVersion: selectedMpacks[0].version,
- hosts: self.getHosts()
+ hosts: self.getHosts(),
+ mpack_instances: self.get('wizardController').getMpackInstances()
}).then(function () {
self.loadStepCallback(self.createComponentInstallationObjects(), self);
});
@@ -711,7 +698,11 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
host_group.components.forEach(function(component) {
var willBeDisplayed = true;
var stackMasterComponent = stackMasterComponentsMap[component.name];
+
if (stackMasterComponent) {
+ stackMasterComponent.mpackInstance = component.mpack_instance;
+ stackMasterComponent.serviceInstance = component.service_instance;
+
var isMasterCreateOnConfig = this.get('mastersToCreate').contains(component.name);
// If service is already installed and not being added as a new service then render on UI only those master components
// that have already installed hostComponents.
@@ -757,6 +748,8 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
componentObj.component_name = componentName;
componentObj.display_name = App.format.role(fullComponent.get('componentName'), false);
componentObj.serviceId = fullComponent.get('serviceName');
+ componentObj.serviceInstance = fullComponent.serviceInstance;
+ componentObj.mpackInstance = fullComponent.mpackInstance;
componentObj.isServiceCoHost = App.StackServiceComponent.find().findProperty('componentName', componentName).get('isCoHostedComponent') && !this.get('mastersToMove').contains(componentName);
componentObj.selectedHost = savedComponent ? savedComponent.hostName : hostName;
componentObj.isInstalled = savedComponent ? savedComponent.isInstalled || (this.get('markSavedComponentsAsInstalled') && !this.get('mastersToCreate').contains(fullComponent.get('componentName'))) : false;
@@ -935,6 +928,7 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
return aValue - bValue;
});
},
+
/**
* Update dependent co-hosted components according to the change in the component host
* @method updateCoHosts
@@ -953,7 +947,6 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
}, this);
}.observes('selectedServicesMasters.@each.selectedHost'),
-
/**
* On change callback for inputs
* @param {string} componentName
@@ -1165,8 +1158,9 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
},
recommendAndValidate: function(callback) {
- var self = this,
- hostNames = this.getHosts();
+ const self = this;
+ const hostNames = this.getHosts();
+ const mpackInstances = this.get('wizardController').getMpackInstances();
if (this.get('validationInProgress')) {
this.set('runQueuedValidation', true);
@@ -1175,19 +1169,14 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
this.set('validationInProgress', true);
- //TODO - mpacks: Hard coded to request first mpack only. Must be changed when we are installing multiple mpacks.
- const selectedMpacks = this.get('content.selectedMpacks');
- // load recommendations with partial request
this.getRecommendedHosts({
hosts: hostNames,
- stackName: selectedMpacks[0].name,
- stackVersion: selectedMpacks[0].version,
+ mpack_instances: mpackInstances,
components: this.getCurrentComponentHostMap()
}).then(function() {
self.validateSelectedHostComponents({
hosts: hostNames,
- stackName: selectedMpacks[0].name,
- stackVersion: selectedMpacks[0].version,
+ mpack_instances: mpackInstances,
blueprint: self.get('recommendations')
}).then(function() {
if (callback) {
@@ -1214,6 +1203,8 @@ App.AssignMasterComponents = Em.Mixin.create(App.HostComponentValidationMixin, A
Em.set(component, 'size', Em.getWithDefault(component, 'hosts.length', 0));
} else {
acc.push({
+ mpackInstance: Em.get(i, 'mpackInstance'),
+ serviceInstance: Em.get(i, 'serviceInstance'),
componentName: componentName,
hosts: [hostName],
size: 1
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index b225aee..0bcf2af 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -2145,22 +2145,6 @@ var urls = {
}
},
- 'config.validations': {
- 'real': '{stackVersionUrl}/validations',
- 'mock': '/data/stacks/HDP-2.1/validations.json',
- 'type': 'POST',
- 'format': function (data) {
- return {
- data: JSON.stringify({
- hosts: data.hosts,
- services: data.services,
- validate: data.validate,
- recommendations: data.recommendations
- })
- }
- }
- },
-
'preinstalled.checks': {
'real': '/requests',
'mock': '',
@@ -3136,6 +3120,26 @@ var urls = {
real: '/mpacks?fields=*'
},
+ 'mpack.advisor.recommendations': {
+ real: '/mpacks/recommendations',
+ format: function (data) {
+ return {
+ type: 'POST',
+ data: JSON.stringify(data.data)
+ }
+ }
+ },
+
+ 'mpack.advisor.validations': {
+ real: '/mpacks/validations',
+ format: function (data) {
+ return {
+ type: 'POST',
+ data: JSON.stringify(data.data)
+ }
+ }
+ },
+
'registry.all': {
real: '/registries?fields=mpacks/*,mpacks/versions/RegistryMpackVersionInfo/*,scenarios/*'
},
--
To stop receiving notification emails like this one, please contact
jgolieb@apache.org.