This is an automated email from the ASF dual-hosted git repository.

jialiang pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new fa16a47215 AMBARI-26109 : Adding DFSRouter via 'Actions Button' in 
HDFS summary page (#3807)
fa16a47215 is described below

commit fa16a47215bd9d7ec0664498aad162f80d0c7f28
Author: Ananya Singh <[email protected]>
AuthorDate: Thu Aug 15 06:42:27 2024 +0530

    AMBARI-26109 : Adding DFSRouter via 'Actions Button' in HDFS summary page 
(#3807)
    
    Co-authored-by: ananysin <[email protected]>
---
 ambari-web/app/controllers.js                      |   5 +
 .../routerBasedFederation/step1_controller.js      |  26 +++
 .../routerBasedFederation/step2_controller.js      |  67 ++++++++
 .../routerBasedFederation/step3_controller.js      | 191 +++++++++++++++++++++
 .../routerBasedFederation/step4_controller.js      |  80 +++++++++
 .../routerBasedFederation/wizard_controller.js     | 158 +++++++++++++++++
 .../main/admin/highAvailability_controller.js      |  22 +++
 ambari-web/app/controllers/main/service/item.js    |   5 +
 .../wizards/router_federation_properties.js        |  80 +++++++++
 ambari-web/app/data/controller_route.js            |   4 +
 ambari-web/app/messages.js                         |  22 +++
 .../app/mixins/wizard/assign_master_components.js  |   3 +
 ambari-web/app/models/host_component.js            |   6 +
 ambari-web/app/models/service.js                   |   2 +-
 .../app/routes/dfsrouter_federation_routes.js      | 166 ++++++++++++++++++
 ambari-web/app/routes/main.js                      |   2 +
 .../federation/routerBasedFederation/step1.hbs     |  28 +++
 .../federation/routerBasedFederation/step3.hbs     |  56 ++++++
 .../federation/routerBasedFederation/step4.hbs     |  19 ++
 .../federation/routerBasedFederation/wizard.hbs    |  35 ++++
 ambari-web/app/utils/db.js                         |   1 +
 ambari-web/app/views.js                            |   5 +
 .../federation/routerBasedFederation/step1_view.js |  28 +++
 .../federation/routerBasedFederation/step2_view.js |  25 +++
 .../federation/routerBasedFederation/step3_view.js |  31 ++++
 .../federation/routerBasedFederation/step4_view.js |  35 ++++
 .../routerBasedFederation/wizard_view.js           |  32 ++++
 ambari-web/app/views/main/service/item.js          |   7 +
 ambari-web/test/models/service_test.js             |   2 +-
 29 files changed, 1141 insertions(+), 2 deletions(-)

diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index bd858a51b0..fbfa68d05c 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -61,6 +61,11 @@ 
require('controllers/main/admin/federation/step1_controller');
 require('controllers/main/admin/federation/step2_controller');
 require('controllers/main/admin/federation/step3_controller');
 require('controllers/main/admin/federation/step4_controller');
+require('controllers/main/admin/federation/routerBasedFederation/wizard_controller');
+require('controllers/main/admin/federation/routerBasedFederation/step1_controller');
+require('controllers/main/admin/federation/routerBasedFederation/step2_controller');
+require('controllers/main/admin/federation/routerBasedFederation/step3_controller');
+require('controllers/main/admin/federation/routerBasedFederation/step4_controller');
 
require('controllers/main/admin/highAvailability/hawq/addStandby/wizard_controller');
 
require('controllers/main/admin/highAvailability/hawq/addStandby/step1_controller');
 
require('controllers/main/admin/highAvailability/hawq/addStandby/step2_controller');
diff --git 
a/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step1_controller.js
 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step1_controller.js
new file mode 100644
index 0000000000..60ee0bb268
--- /dev/null
+++ 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step1_controller.js
@@ -0,0 +1,26 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep1Controller = Em.Controller.extend({
+    name: "routerFederationWizardStep1Controller",
+    next: function () {
+        App.router.send('next');
+    }
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step2_controller.js
 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step2_controller.js
new file mode 100644
index 0000000000..a367c3d2b2
--- /dev/null
+++ 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step2_controller.js
@@ -0,0 +1,67 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep2Controller = 
Em.Controller.extend(App.AssignMasterComponents, {
+
+    name: "routerFederationWizardStep2Controller",
+
+    useServerValidation: false,
+
+    mastersToShow: ['NAMENODE', 'ROUTER'],
+
+    mastersToAdd: ['ROUTER'],
+
+    showCurrentPrefix: ['NAMENODE', 'ROUTER'],
+
+    showAdditionalPrefix: ['ROUTER'],
+
+    mastersAddableInHA: ['ROUTER'],
+
+    showInstalledMastersFirst: true,
+
+    renderComponents: function (masterComponents) {
+        // check if we are restoring components assignment by checking 
existence of ROUTER component in array
+        var restoringComponents = 
masterComponents.someProperty('component_name', 'ROUTER');
+        masterComponents = restoringComponents ? masterComponents : 
masterComponents.concat(this.generateRouterComponents());
+        this._super(masterComponents);
+        // if you have similar functions for router, call them here
+    },
+
+
+    generateRouterComponents: function () {
+        var router = [];
+        App.HostComponent.find().filterProperty('componentName', 
'ROUTER').forEach(function (rbf) {
+            var rbfComponent = 
this.createComponentInstallationObject(Em.Object.create({
+                serviceName: rbf.get('service.serviceName'),
+                componentName: rbf.get('componentName')
+            }), rbf.get('hostName'));
+            rbfComponent.isInstalled = true;
+            router.push(rbfComponent);
+        }, this);
+        return router;
+    },
+
+    actions: {
+        back() {
+            this.clearStep()
+        }
+    }
+
+});
diff --git 
a/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step3_controller.js
 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step3_controller.js
new file mode 100644
index 0000000000..364f125b1c
--- /dev/null
+++ 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step3_controller.js
@@ -0,0 +1,191 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep3Controller = 
Em.Controller.extend(App.BlueprintMixin, {
+    name: "routerFederationWizardStep3Controller",
+    selectedService: null,
+    stepConfigs: [],
+    serverConfigData: {},
+    once: false,
+    isLoaded: false,
+    isConfigsLoaded: false,
+    versionLoaded: true,
+    hideDependenciesInfoBar: true,
+
+    /**
+     * Map of sites and properties to delete
+     * @type Object
+     */
+
+    clearStep: function () {
+        this.get('stepConfigs').clear();
+        this.set('serverConfigData', {});
+        this.set('isConfigsLoaded', false);
+        this.set('isLoaded', false);
+    },
+
+    loadStep: function () {
+        this.clearStep();
+        this.loadConfigsTags();
+    },
+
+    loadConfigsTags: function () {
+        return App.ajax.send({
+            name: 'config.tags',
+            sender: this,
+            success: 'onLoadConfigsTags'
+        });
+    },
+
+
+    onLoadConfigsTags: function (data) {
+        var urlParams = '(type=hdfs-rbf-site&tag=' + 
data.Clusters.desired_configs['hdfs-rbf-site'].tag + ')|';
+        urlParams += '(type=hdfs-site&tag=' + 
data.Clusters.desired_configs['hdfs-site'].tag + ')|';
+        urlParams += '(type=core-site&tag=' + 
data.Clusters.desired_configs['core-site'].tag + ')';
+        App.ajax.send({
+            name: 'admin.get.all_configurations',
+            sender: this,
+            data: {
+                urlParams: urlParams
+            },
+            success: 'onLoadConfigs'
+        });
+    },
+
+    onLoadConfigs: function (data) {
+        this.set('serverConfigData', data);
+        this.set('isConfigsLoaded', true);
+    },
+
+    onLoad: function () {
+        if (this.get('isConfigsLoaded') && 
App.router.get('clusterController.isHDFSNameSpacesLoaded')) {
+            var routerFederationConfig = $.extend(true, {}, 
require('data/configs/wizards/router_federation_properties').routerFederationConfig);
+            if (App.get('hasNameNodeFederation')) {
+                routerFederationConfig.configs = 
routerFederationConfig.configs.rejectProperty('firstRun');
+            }
+            routerFederationConfig.configs = 
this.tweakServiceConfigs(routerFederationConfig.configs);
+            var configsFromServer = this.get('serverConfigData.items');
+            var hdfsrbfConfigs = configsFromServer.findProperty('type', 
'hdfs-rbf-site');
+            var configToSave = {
+                type: 'hdfs-rbf-site',
+                properties: hdfsrbfConfigs&&hdfsrbfConfigs.properties,
+            };
+            if (hdfsrbfConfigs && hdfsrbfConfigs.properties_attributes) {
+                configToSave.properties_attributes = 
hdfsrbfConfigs.properties_attributes;
+            }
+            for(const property of routerFederationConfig.configs){
+                configToSave.properties[property.name]=property.value
+            }
+            App.ajax.send({
+                name: 'common.service.configurations',
+                sender: self,
+                data: {
+                    desired_config: configToSave
+                },
+                error: 'onTaskError'
+            });
+
+            this.renderServiceConfigs(routerFederationConfig);
+            this.set('isLoaded', true);
+        }
+    }.observes('isConfigsLoaded', 
'App.router.clusterController.isHDFSNameSpacesLoaded'),
+
+    prepareDependencies: function () {
+        var ret = {};
+        var configsFromServer = this.get('serverConfigData.items');
+        var nameNodes = 
this.get('content.masterComponentHosts').filterProperty('component', 
'NAMENODE');
+        var hdfsSiteConfigs = configsFromServer.findProperty('type', 
'hdfs-site').properties;
+        var coreSiteConfigs = configsFromServer.findProperty('type', 
'core-site').properties;
+        var nameServices = 
App.HDFSService.find().objectAt(0).get('masterComponentGroups').mapProperty('name');
+        var modifiedNameServices = [];
+        var nnCounter = 1;
+        ret.nameServicesList = nameServices.join(',');
+        ret.nameservice1 = nameServices[0];
+        for (let i = 0; i < nameServices.length; i++) {
+            let nameservice = nameServices[i];
+            modifiedNameServices.push(`${nameservice}.nn${nnCounter}`);
+            nnCounter++;
+            modifiedNameServices.push(`${nameservice}.nn${nnCounter}`);
+            nnCounter++;
+        }
+        ret.modifiedNameServices = modifiedNameServices.join(',');
+
+        ret.zkAddress = coreSiteConfigs['ha.zookeeper.quorum'];
+
+        return ret;
+    },
+    tweakServiceConfigs: function (configs) {
+        var dependencies = this.prepareDependencies();
+        var result = [];
+        var configsToRemove = [];
+        var hdfsSiteConfigs = 
this.get('serverConfigData').items.findProperty('type', 'hdfs-site').properties;
+        var wizardController = 
App.router.get(this.get('content.controllerName'));
+        configs.forEach(function (config) {
+            config.isOverridable = false;
+            config.name = wizardController.replaceDependencies(config.name, 
dependencies);
+            config.displayName = 
wizardController.replaceDependencies(config.displayName, dependencies);
+            config.value = wizardController.replaceDependencies(config.value, 
dependencies);
+            config.recommendedValue = 
wizardController.replaceDependencies(config.recommendedValue, dependencies);
+            result.push(config);
+
+        }, this);
+
+        return result;
+    },
+
+    renderServiceConfigs: function (_serviceConfig) {
+        var serviceConfig = App.ServiceConfig.create({
+            serviceName: _serviceConfig.serviceName,
+            displayName: _serviceConfig.displayName,
+            configCategories: [],
+            showConfig: true,
+            configs: []
+        });
+
+        _serviceConfig.configCategories.forEach(function (_configCategory) {
+            if (App.Service.find().someProperty('serviceName', 
_configCategory.name)) {
+                serviceConfig.configCategories.pushObject(_configCategory);
+            }
+        }, this);
+
+        this.loadComponentConfigs(_serviceConfig, serviceConfig);
+
+        this.get('stepConfigs').pushObject(serviceConfig);
+        this.set('selectedService', this.get('stepConfigs').objectAt(0));
+        this.set('once', true);
+    },
+
+    /**
+     * Load child components to service config object
+     * @param _componentConfig
+     * @param componentConfig
+     */
+    loadComponentConfigs: function (_componentConfig, componentConfig) {
+        _componentConfig.configs.forEach(function (_serviceConfigProperty) {
+            var serviceConfigProperty = 
App.ServiceConfigProperty.create(_serviceConfigProperty);
+            componentConfig.configs.pushObject(serviceConfigProperty);
+            serviceConfigProperty.set('isEditable', 
serviceConfigProperty.get('isReconfigurable'));
+        }, this);
+    },
+
+    isNextDisabled: function () {
+        return !this.get('isLoaded') || (this.get('isLoaded') && 
this.get('selectedService.configs').someProperty('isValid', false));
+    }.property('[email protected]', 'isLoaded')
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step4_controller.js
 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step4_controller.js
new file mode 100644
index 0000000000..8e0f5925f2
--- /dev/null
+++ 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/step4_controller.js
@@ -0,0 +1,80 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep4Controller = 
App.HighAvailabilityProgressPageController.extend(App.WizardEnableDone, {
+
+    name: "routerFederationWizardStep4Controller",
+
+    commands: ['installRouter', 'startRouters'],
+
+    tasksMessagesPrefix: 'admin.routerFederation.wizard.step',
+
+    initializeTasks: function () {
+        this._super();
+        this.removeUnneededTasks();
+    },
+
+    removeUnneededTasks: function () {
+        var installedServices = App.Service.find().mapProperty('serviceName');
+        if (!installedServices.contains('RANGER')) {
+            this.removeTasks(['startInfraSolr', 'startRangerAdmin', 
'startRangerUsersync']);
+        }
+        if (!installedServices.contains('AMBARI_INFRA_SOLR')) {
+            this.removeTasks(['startInfraSolr']);
+        }
+    },
+
+    reconfigureServices: function () {
+        var servicesModel = App.Service.find();
+        var configs = [];
+        var data = this.get('content.serviceConfigProperties');
+        var note = 
Em.I18n.t('admin.routerFederation.wizard,step4.save.configuration.note');
+        configs.push({
+            Clusters: {
+                desired_config: this.reconfigureSites(['hdfs-rbf-site'], data, 
note)
+            }
+        });
+        return App.ajax.send({
+            name: 'common.service.multiConfigurations',
+            sender: this,
+            data: {
+                configs: configs
+            },
+            error: 'onTaskError',
+            success: 'installHDFSClients'
+        });
+    },
+
+    installHDFSClients: function () {
+        var nnHostNames = 
this.get('content.masterComponentHosts').filterProperty('component', 
'NAMENODE').mapProperty('hostName');
+        var jnHostNames = 
App.HostComponent.find().filterProperty('componentName', 
'JOURNALNODE').mapProperty('hostName');
+        var hostNames = nnHostNames.concat(jnHostNames).uniq();
+        this.createInstallComponentTask('HDFS_CLIENT', hostNames, 'HDFS');
+    },
+
+    installRouter: function () {
+        this.createInstallComponentTask('ROUTER', 
this.get('content.masterComponentHosts').filterProperty('component', 
'ROUTER').mapProperty('hostName'), "HDFS");
+    },
+
+    startRouters: function () {
+        var hostNames = 
this.get('content.masterComponentHosts').filterProperty('component', 
'ROUTER').mapProperty('hostName');
+        this.updateComponent('ROUTER', hostNames, "HDFS", "Start");
+    }
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/wizard_controller.js
 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/wizard_controller.js
new file mode 100644
index 0000000000..588030821d
--- /dev/null
+++ 
b/ambari-web/app/controllers/main/admin/federation/routerBasedFederation/wizard_controller.js
@@ -0,0 +1,158 @@
+/**
+ * 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');
+
+App.RouterFederationWizardController = App.WizardController.extend({
+
+    name: 'routerFederationWizardController',
+
+    totalSteps: 4,
+
+    /**
+     * @type {string}
+     */
+    displayName: Em.I18n.t('admin.routerFederation.wizard.header'),
+
+    isFinished: false,
+
+    content: Em.Object.create({
+        controllerName: 'routerFederationWizardController'
+    }),
+
+    /**
+     * Load data for all steps until <code>current step</code>
+     */
+    loadMap: {
+        '1': [
+            {
+                type: 'sync',
+                callback: function () {
+                    this.load('cluster');
+                }
+            }
+        ],
+        '2': [
+            {
+                type: 'async',
+                callback: function () {
+                    var self = this,
+                        dfd = $.Deferred();
+                    this.loadServicesFromServer();
+                    this.loadMasterComponentHosts().done(function () {
+                        self.loadConfirmedHosts();
+                        dfd.resolve();
+                    });
+                    return dfd.promise();
+                }
+            }
+        ],
+        '3': [
+            {
+                type: 'sync',
+                callback: function () {
+                    this.load('cluster');
+                }
+            }
+        ],
+        '4': [
+            {
+                type: 'sync',
+                callback: function () {
+                    this.loadServiceConfigProperties();
+                    this.loadTasksStatuses();
+                    this.loadTasksRequestIds();
+                    this.loadRequestIds();
+                }
+            }
+        ]
+    },
+
+    init: function () {
+        this._super();
+        this.clearStep();
+    },
+
+    clearStep: function () {
+        this.set('isFinished', false);
+    },
+
+    setCurrentStep: function (currentStep, completed) {
+        this._super(currentStep, completed);
+        App.clusterStatus.setClusterStatus({
+            clusterName: this.get('content.cluster.name'),
+            wizardControllerName: 'routerFederationWizardController',
+            localdb: App.db.data
+        });
+    },
+
+    saveNNHosts: function (nnHosts) {
+        this.set('content.nnHosts', nnHosts);
+        this.setDBProperty('nnHosts', nnHosts);
+    },
+
+    /**
+     * Load hosts for additional and current ResourceManagers from local db to 
<code>controller.content</code>
+     */
+    loadNNHosts: function() {
+        var nnHosts = this.getDBProperty('nnHosts');
+        this.set('content.nnHosts', nnHosts);
+    },
+
+    saveServiceConfigProperties: function (stepController) {
+        var serviceConfigProperties = [];
+        var data = stepController.get('serverConfigData');
+
+        var _content = stepController.get('stepConfigs')[0];
+        _content.get('configs').forEach(function (_configProperties) {
+            var siteObj = data.items.findProperty('type', 
_configProperties.get('filename'));
+            if (siteObj) {
+                siteObj.properties[_configProperties.get('name')] = 
_configProperties.get('value');
+            }
+        }, this);
+        this.setDBProperty('serviceConfigProperties', data);
+        this.set('content.serviceConfigProperties', data);
+    },
+
+    /**
+     * Load serviceConfigProperties to model
+     */
+    loadServiceConfigProperties: function () {
+        this.set('content.serviceConfigProperties', 
this.getDBProperty('serviceConfigProperties'));
+    },
+
+    /**
+     * Remove all loaded data.
+     * Created as copy for App.router.clearAllSteps
+     */
+    clearAllSteps: function () {
+        this.clearInstallOptions();
+        // clear temporary information stored during the install
+        this.set('content.cluster', this.getCluster());
+    },
+
+    /**
+     * Clear all temporary data
+     */
+    finish: function () {
+        this.resetDbNamespace();
+        App.router.get('updateController').updateAll();
+        this.set('isFinished', true);
+    }
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/controllers/main/admin/highAvailability_controller.js 
b/ambari-web/app/controllers/main/admin/highAvailability_controller.js
index 3ac7214979..f73f895ec7 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability_controller.js
@@ -142,6 +142,28 @@ App.MainAdminHighAvailabilityController = 
App.WizardController.extend({
     return true;
   },
 
+  /**
+   * enable router Based Federation
+   * @return {Boolean}
+   */
+  enableRouterFederation: function () {
+    //Prerequisite Checks
+    var message = [];
+    if (!App.HostComponent.find().filterProperty('componentName', 
'ZOOKEEPER_SERVER').everyProperty('workStatus', 'STARTED')) {
+      
message.push(Em.I18n.t('admin.nameNodeFederation.wizard.required.zookeepers'));
+    }
+
+    if (!App.HostComponent.find().filterProperty('componentName', 
'JOURNALNODE').everyProperty('workStatus', 'STARTED')) {
+      
message.push(Em.I18n.t('admin.nameNodeFederation.wizard.required.journalnodes'));
+    }
+    if (message.length > 0) {
+      this.showErrorPopup(message);
+      return false;
+    }
+    App.router.transitionTo('main.services.enableRouterFederation');
+    return true;
+  },
+
   /**
    * open Manage JournalNode Wizard if there are two started NameNodes with 
defined active/standby state
    * @returns {boolean}
diff --git a/ambari-web/app/controllers/main/service/item.js 
b/ambari-web/app/controllers/main/service/item.js
index d749c313f7..380c94aaab 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -1518,6 +1518,11 @@ App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDow
     highAvailabilityController.enableNameNodeFederation();
   },
 
+  openRouterFederationWizard: function () {
+    var highAvailabilityController = 
App.router.get('mainAdminHighAvailabilityController');
+    highAvailabilityController.enableRouterFederation();
+  },
+
   /**
    * This method is called when user event to download configs for "All 
Clients"
    * is made from service action menu
diff --git 
a/ambari-web/app/data/configs/wizards/router_federation_properties.js 
b/ambari-web/app/data/configs/wizards/router_federation_properties.js
new file mode 100644
index 0000000000..c87f2eb4d4
--- /dev/null
+++ b/ambari-web/app/data/configs/wizards/router_federation_properties.js
@@ -0,0 +1,80 @@
+/**
+ * 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.
+ */
+
+module.exports =
+    {
+        "routerFederationConfig": {
+            serviceName: 'MISC',
+            displayName: 'MISC',
+            configCategories: [
+                App.ServiceConfigCategory.create({ name: 'HDFS', displayName: 
'HDFS'})
+            ],
+            sites: ['core-site', 'hdfs-rbf-site'],
+            configs: [
+                {
+                    "name": "dfs.federation.router.monitor.namenode",
+                    "displayName": "dfs.federation.router.monitor.namenode",
+                    "description": "RPC address for HDFS Services 
communication.",
+                    "isReconfigurable": false,
+                    "recommendedValue": "{{nameservice1}}.nn1, 
{{nameservice1}}.nn2, 
{{newNameservice}}.{{newNameNode1Index}},{{newNameservice}}.{{newNameNode2Index}}",
+                    "value": "{{modifiedNameServices}}",
+                    "category": "HDFS",
+                    "filename": "hdfs-rbf-site",
+                    "serviceName": 'MISC',
+                    "isRouterConfigs" : true
+                },
+                {
+                    "name": "dfs.federation.router.default.nameserviceId",
+                    "displayName": 
"dfs.federation.router.default.nameserviceId",
+                    "description": "Nameservice identifier of the default 
subcluster to monitor.",
+                    "isReconfigurable": false,
+                    "recommendedValue": "{{nameservice1}}",
+                    "value": "{{nameservice1}}",
+                    "category": "HDFS",
+                    "filename": "hdfs-rbf-site",
+                    "serviceName": 'MISC',
+                    "isRouterConfigs" : true
+                },
+                {
+                    "name": "zk-dt-secret-manager.zkAuthType",
+                    "displayName": "zk-dt-secret-manager.zkAuthType",
+                    "description": "Secret Manager Zookeeper Authentication 
Type",
+                    "isReconfigurable": false,
+                    "recommendedValue": "none",
+                    "value": "none",
+                    "category": "HDFS",
+                    "filename": "hdfs-rbf-site",
+                    "serviceName": 'MISC',
+                    "isRouterConfigs" : true
+                },
+                {
+                    "name": "zk-dt-secret-manager.zkConnectionString",
+                    "displayName": "zk-dt-secret-manager.zkConnectionString",
+                    "description": "Secret Manager Zookeeper Connection 
String",
+                    "isReconfigurable": false,
+                    "recommendedValue": 
"zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181",
+                    "value": "{{zkAddress}}",
+                    "category": "HDFS",
+                    "filename": "hdfs-rbf-site",
+                    "serviceName": 'MISC',
+                    "isRouterConfigs" : true
+                }
+            ]
+        }
+
+    };
\ No newline at end of file
diff --git a/ambari-web/app/data/controller_route.js 
b/ambari-web/app/data/controller_route.js
index 8f6f385bff..914ee88f15 100644
--- a/ambari-web/app/data/controller_route.js
+++ b/ambari-web/app/data/controller_route.js
@@ -85,6 +85,10 @@ module.exports = [
     wizardControllerName: 
App.router.get('nameNodeFederationWizardController.name'),
     route: 'main.services.enableNameNodeFederation'
   },
+  {
+    wizardControllerName: 
App.router.get('routerFederationWizardController.name'),
+    route: 'main.services.enableRouterFederation'
+  },
   {
     wizardControllerName: 
App.router.get('manageJournalNodeWizardController.name'),
     route: 'main.services.manageJournalNode'
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 78626c1989..350883769d 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1727,6 +1727,28 @@ Em.I18n.translations = {
   'admin.nameNodeFederation.wizard.step4.task16.title': 'Start NameNode',
   'admin.nameNodeFederation.wizard.step4.task17.title': 'Restart Required 
Services',
 
+  'admin.routerFederation.button.enable':'Add DFSRouter',
+  'admin.routerFederation.wizard.header': 'Add HDFS Router',
+  'admin.routerFederation.closePopup': 'Are you sure you want to quit?',
+  'admin.routerFederation.closePopup2': 'Add HDFS Router Wizard is in 
progress. Are you sure you want to exit the wizard?',
+  'admin.routerFederation.wizard.step1.header': 'Get Started',
+  'admin.routerFederation.wizard.step1.body':'This wizard will walk you 
through the process of enabling DFSRouter to manage federated cluster.',
+  'admin.routerFederation.wizard.step2.header': 'Select Hosts',
+  'admin.routerFederation.wizard.step2.body': 'Select hosts running the 
Routers for {0}',
+  'admin.routerFederation.wizard.step3.header': 'Review',
+  'admin.routerFederation.wizard.step3.addRouter': '<b>Add Router:</b> ',
+  'admin.routerFederation.wizard.step3.toBeInstalled': 'Router TO BE 
INSTALLED',
+  'admin.routerFederation.wizard.step3.confirm.config.body': '<div 
class="alert alert-info">' +
+      '<p><b>Review Configuration Changes.</b></p>' +
+      'The following lists the configuration changes that will be made by the 
Wizard to enable Router. This information is for <b> review only </b> and is 
not editable' +
+      '</div>',
+  'admin.routerFederation.wizard.step4.header': 'Configure Router',
+  'admin.routerFederation.wizard,step4.save.configuration.note':'This 
configuration is created by Enable DFSRouter wizard',
+  'admin.routerFederation.wizard.step4.notice.inProgress':'Please wait while 
your Router is being deployed.',
+  'admin.routerFederation.wizard.step4.notice.completed':'Add DFSRouter Wizard 
has been completed successfully.',
+  'admin.routerFederation.wizard.step4.task0.title': 'Install Routers',
+  'admin.routerFederation.wizard.step4.task1.title': 'Start Routers',
+
   'admin.security.title':'Kerberos security has not been enabled',
   'admin.security.enabled': 'Kerberos security is enabled',
   'admin.security.disabled': 'Kerberos security is disabled',
diff --git a/ambari-web/app/mixins/wizard/assign_master_components.js 
b/ambari-web/app/mixins/wizard/assign_master_components.js
index 25bf86c38b..53b566212e 100644
--- a/ambari-web/app/mixins/wizard/assign_master_components.js
+++ b/ambari-web/app/mixins/wizard/assign_master_components.js
@@ -1120,6 +1120,9 @@ App.AssignMasterComponents = 
Em.Mixin.create(App.HostComponentValidationMixin, A
       }
 
       newMaster.set("selectedHost", suggestedHost);
+      if(!currentMasters.get("lastObject.serviceComponentId")){
+        currentMasters.get("lastObject").set("serviceComponentId",0)
+      }
       newMaster.set("serviceComponentId", 
(currentMasters.get("lastObject.serviceComponentId") + 1));
 
       
this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastMaster)
 + 1, newMaster);
diff --git a/ambari-web/app/models/host_component.js 
b/ambari-web/app/models/host_component.js
index 428bca3a16..c404e5691b 100644
--- a/ambari-web/app/models/host_component.js
+++ b/ambari-web/app/models/host_component.js
@@ -575,6 +575,12 @@ App.HostComponentActionMap = {
         cssClass: 'icon icon-sitemap',
         disabled: !App.get('isHaEnabled') || App.get('allHostNames.length') < 4
       },
+      TOGGLE_RBF_FEDERATION: {
+        action: 'openRouterFederationWizard',
+        label: Em.I18n.t('admin.routerFederation.button.enable'),
+        cssClass: 'icon icon-sitemap',
+        disabled: !App.get('hasNameNodeFederation')
+      },
       UPDATE_REPLICATION: {
         action: 'updateHBaseReplication',
         customCommand: 'UPDATE_REPLICATION',
diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js
index 06d108297e..a1bb73ba37 100644
--- a/ambari-web/app/models/service.js
+++ b/ambari-web/app/models/service.js
@@ -117,7 +117,7 @@ App.Service = DS.Model.extend({
   serviceTypes: function() {
     var typeServiceMap = {
       GANGLIA: ['MONITORING'],
-      HDFS: ['HA_MODE', 'FEDERATION'],
+      HDFS: ['HA_MODE', 'FEDERATION', 'DFSRouter'],
       YARN: ['HA_MODE'],
       RANGER: ['HA_MODE'],
       HAWQ: ['HA_MODE']
diff --git a/ambari-web/app/routes/dfsrouter_federation_routes.js 
b/ambari-web/app/routes/dfsrouter_federation_routes.js
new file mode 100644
index 0000000000..bc7f8388e9
--- /dev/null
+++ b/ambari-web/app/routes/dfsrouter_federation_routes.js
@@ -0,0 +1,166 @@
+/**
+ * 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');
+
+module.exports = App.WizardRoute.extend({
+    route: '/NameNode/federation/routerBasedFederation',
+
+    breadcrumbs: {
+        label: Em.I18n.t('admin.routerFederation.wizard.header')
+    },
+
+    enter: function (router, transition) {
+        var routerFederationWizardController = 
router.get('routerFederationWizardController');
+        routerFederationWizardController.dataLoading().done(function () {
+            //Set HDFS as current service
+            App.router.set('mainServiceItemController.content', 
App.Service.find().findProperty('serviceName', 'HDFS'));
+            App.router.get('updateController').set('isWorking', false);
+            var popup = App.ModalPopup.show({
+                classNames: ['wizard-modal-wrapper'],
+                modalDialogClasses: ['modal-xlg'],
+                header: Em.I18n.t('admin.routerFederation.wizard.header'),
+                bodyClass: App.RouterFederationWizardView.extend({
+                    controller: routerFederationWizardController
+                }),
+                primary: Em.I18n.t('form.cancel'),
+                showFooter: false,
+                secondary: null,
+
+                onClose: function () {
+                    var routerFederationWizardController = 
router.get('routerFederationWizardController'),
+                        currStep = 
routerFederationWizardController.get('currentStep');
+                    App.showConfirmationPopup(function () {
+                        
routerFederationWizardController.resetOnClose(routerFederationWizardController, 
'main.services.index');
+                    }, Em.I18n.t(parseInt(currStep) === 4 ? 
'admin.routerFederation.closePopup2' : 'admin.routerFederation.closePopup'));
+                },
+                didInsertElement: function () {
+                    this._super();
+                    this.fitHeight();
+                }
+            });
+            routerFederationWizardController.set('popup', popup);
+            var currentClusterStatus = App.clusterStatus.get('value');
+            if (currentClusterStatus) {
+                switch (currentClusterStatus.clusterState) {
+                    case 'RBF_FEDERATION_DEPLOY' :
+                        
routerFederationWizardController.setCurrentStep(currentClusterStatus.localdb.RouterFederationWizard.currentStep);
+                        break;
+                    default:
+                        var currStep = 
App.router.get('routerFederationWizardController.currentStep');
+                        
routerFederationWizardController.setCurrentStep(currStep);
+                        break;
+                }
+            }
+            Em.run.next(function () {
+                
App.router.get('wizardWatcherController').setUser(routerFederationWizardController.get('name'));
+                router.transitionTo('step' + 
routerFederationWizardController.get('currentStep'));
+            });
+        });
+    },
+
+    step1: Em.Route.extend({
+        route: '/step1',
+        connectOutlets: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            controller.dataLoading().done(function () {
+                controller.setCurrentStep('1');
+                controller.connectOutlet('routerFederationWizardStep1', 
controller.get('content'));
+            })
+        },
+        unroutePath: function () {
+            return false;
+        },
+        next: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            router.transitionTo('step2');
+        }
+    }),
+
+    step2: Em.Route.extend({
+        route: '/step2',
+        connectOutlets: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            controller.dataLoading().done(function () {
+                controller.setCurrentStep('2');
+                controller.loadAllPriorSteps();
+                controller.connectOutlet('routerFederationWizardStep2', 
controller.get('content'));
+            })
+        },
+        unroutePath: function () {
+            return false;
+        },
+        next: function (router) {
+            var wizardController = 
router.get('routerFederationWizardController');
+            var stepController = 
router.get('routerFederationWizardStep2Controller');
+            wizardController.saveMasterComponentHosts(stepController);
+            router.transitionTo('step3');
+        },
+        back: function (router) {
+            router.transitionTo('step1');
+        }
+    }),
+
+    step3: Em.Route.extend({
+        route: '/step3',
+        connectOutlets: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            controller.dataLoading().done(function () {
+                controller.setCurrentStep('3');
+                controller.loadAllPriorSteps();
+                controller.connectOutlet('routerFederationWizardStep3', 
controller.get('content'));
+            })
+        },
+        unroutePath: function () {
+            return false;
+        },
+        next: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            var stepController = 
router.get('routerFederationWizardStep3Controller');
+            controller.saveServiceConfigProperties(stepController);
+            router.transitionTo('step4');
+        },
+        back: Em.Router.transitionTo('step2')
+    }),
+
+    step4: Em.Route.extend({
+        route: '/step4',
+        connectOutlets: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            controller.dataLoading().done(function () {
+                controller.setCurrentStep('4');
+                controller.setLowerStepsDisable(4);
+                controller.loadAllPriorSteps();
+                controller.connectOutlet('routerFederationWizardStep4', 
controller.get('content'));
+            })
+        },
+        unroutePath: function (router, path) {
+            // allow user to leave route if wizard has finished
+            if 
(router.get('routerFederationWizardController').get('isFinished')) {
+                this._super(router, path);
+            } else {
+                return false;
+            }
+        },
+        next: function (router) {
+            var controller = router.get('routerFederationWizardController');
+            controller.resetOnClose(controller, 'main.services.index');
+        }
+    })
+
+});
\ No newline at end of file
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index bc2c542c8a..6567a92f0d 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -893,6 +893,8 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
 
     enableNameNodeFederation: require('routes/namenode_federation_routes'),
 
+    enableRouterFederation : require('routes/dfsrouter_federation_routes'),
+
     addHawqStandby: require('routes/add_hawq_standby_routes'),
 
     removeHawqStandby: require('routes/remove_hawq_standby_routes'),
diff --git 
a/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step1.hbs
 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step1.hbs
new file mode 100644
index 0000000000..1576e900d4
--- /dev/null
+++ 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step1.hbs
@@ -0,0 +1,28 @@
+{{!
+* 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.
+}}
+<div class="wizard-content col-md-9">
+  <h4 class="step-title">{{t admin.routerFederation.wizard.step1.header}}</h4>
+  <div class="step-description">
+    <p>{{t admin.routerFederation.wizard.step1.body}}</p>
+  </div>
+</div>
+<div class="wizard-footer col-md-12">
+  <div class="btn-area">
+    <button class="btn btn-success pull-right" {{action next 
target="controller"}}>{{t common.next}} &rarr;</button>
+  </div>
+</div>
\ No newline at end of file
diff --git 
a/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step3.hbs
 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step3.hbs
new file mode 100644
index 0000000000..41e14ab3b0
--- /dev/null
+++ 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step3.hbs
@@ -0,0 +1,56 @@
+{{!
+* 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.
+}}
+<div class="wizard-content col-md-9">
+  <h4 class="step-title">{{t admin.highAvailability.wizard.step3.header}}</h4>
+  <p class="step-description">{{t 
admin.highAvailability.wizard.step3.confirm.host.body}}</p>
+  <div class="panel panel-default">
+    <div class="panel-body">
+      <div id="ha-step3-content" class="well pre-scrollable">
+        <div id="step8-info">
+          <table id="ha-step3-review-table">
+            {{#each host in view.addRouters}}
+              <tr>
+                <td>{{t admin.routerFederation.wizard.step3.addRouter}}</td>
+                <td>{{host}}</td>
+                <td><span class="to-be-installed-green"><i class="glyphicon 
glyphicon-plus"></i>&nbsp;{{t 
admin.routerFederation.wizard.step3.toBeInstalled}}</span></td>
+              </tr>
+            {{/each}}
+          </table>
+        </div>
+      </div>
+      <div id="serviceConfig">
+        {{#if controller.isLoaded}}
+          {{{t admin.routerFederation.wizard.step3.confirm.config.body}}}
+          {{view App.ServiceConfigView 
isNotEditableBinding="controller.isNotEditable"}}
+        {{else}}
+          {{view App.SpinnerView}}
+        {{/if}}
+      </div>
+    </div>
+  </div>
+</div>
+
+<div class="wizard-footer col-md-12">
+  <div class="btn-area">
+    <a class="btn btn-default" {{action back}}>&larr; {{t common.back}}</a>
+    <button class="btn btn-success pull-right" {{bindAttr 
disabled="controller.isNextDisabled"}} {{action next}}>{{t common.next}} 
&rarr;</button>
+    {{#if App.router.nextBtnClickInProgress}}
+      {{view App.SpinnerView tagName="span" classNames="pull-right"}}
+    {{/if}}
+  </div>
+</div>
\ No newline at end of file
diff --git 
a/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step4.hbs
 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step4.hbs
new file mode 100644
index 0000000000..79f070ab5d
--- /dev/null
+++ 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/step4.hbs
@@ -0,0 +1,19 @@
+{{!
+* 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.
+}}
+{{template "templates/common/progress"}}
+
diff --git 
a/ambari-web/app/templates/main/admin/federation/routerBasedFederation/wizard.hbs
 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/wizard.hbs
new file mode 100644
index 0000000000..6f81321fd7
--- /dev/null
+++ 
b/ambari-web/app/templates/main/admin/federation/routerBasedFederation/wizard.hbs
@@ -0,0 +1,35 @@
+{{!
+* 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.
+}}
+
+<div id="rm-ha-wizard" class="wizard">
+  <div class="wizard-body row">
+    <div class="wizard-nav col-md-3">
+      <ul class="nav nav-pills nav-stacked">
+        <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled 
view.isStep1Completed:completed"}}><a href="javascript:void(null);"  {{action 
gotoStep1 target="controller"}}><i class="step-marker"><span 
class="step-index">1</span></i><p class="step-name">{{t 
admin.routerFederation.wizard.step1.header}}</p></a></li>
+        <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled 
view.isStep2Completed:completed"}}><a href="javascript:void(null);"  {{action 
gotoStep2 target="controller"}}><i class="step-marker"><span 
class="step-index">2</span></i><p class="step-name">{{t 
admin.routerFederation.wizard.step2.header}}</p></a></li>
+        <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled 
view.isStep3Completed:completed"}}><a href="javascript:void(null);"  {{action 
gotoStep3 target="controller"}}><i class="step-marker"><span 
class="step-index">3</span></i><p class="step-name">{{t 
admin.routerFederation.wizard.step3.header}}</p></a></li>
+        <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled 
view.isStep4Completed:completed"}}><a href="javascript:void(null);"  {{action 
gotoStep4 target="controller"}}><i class="step-marker"><span 
class="step-index">4</span></i><p class="step-name">{{t 
admin.routerFederation.wizard.step4.header}}</p></a></li>
+      </ul>
+    </div>
+      {{#if view.isLoaded}}
+        {{outlet}}
+      {{else}}
+        {{view App.SpinnerView}}
+      {{/if}}
+  </div>
+</div>
\ No newline at end of file
diff --git a/ambari-web/app/utils/db.js b/ambari-web/app/utils/db.js
index 78bc99af57..701a70cca2 100644
--- a/ambari-web/app/utils/db.js
+++ b/ambari-web/app/utils/db.js
@@ -49,6 +49,7 @@ var InitialData = {
   'ActivateHawqStandbyWizard': {},
   'RAHighAvailabilityWizard': {},
   'NameNodeFederationWizard': {},
+  'RouterFederationWizard': {},
   'RollbackHighAvailabilityWizard': {},
   'MainAdminStackAndUpgrade': {},
   'KerberosDisable': {},
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index c11d1d6332..30aa6bc7ee 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -224,6 +224,11 @@ require('views/main/admin/federation/step1_view');
 require('views/main/admin/federation/step2_view');
 require('views/main/admin/federation/step3_view');
 require('views/main/admin/federation/step4_view');
+require('views/main/admin/federation/routerBasedFederation/wizard_view');
+require('views/main/admin/federation/routerBasedFederation/step1_view');
+require('views/main/admin/federation/routerBasedFederation/step2_view');
+require('views/main/admin/federation/routerBasedFederation/step3_view');
+require('views/main/admin/federation/routerBasedFederation/step4_view');
 require('views/main/admin/serviceAccounts_view');
 require('views/main/admin/stack_upgrade/upgrade_wizard_view');
 require('views/main/admin/stack_upgrade/upgrade_version_box_view');
diff --git 
a/ambari-web/app/views/main/admin/federation/routerBasedFederation/step1_view.js
 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step1_view.js
new file mode 100644
index 0000000000..cb4a2086a9
--- /dev/null
+++ 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step1_view.js
@@ -0,0 +1,28 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep1View = Em.View.extend({
+
+    templateName: 
require('templates/main/admin/federation/routerBasedFederation/step1'),
+
+    didInsertElement: function() {
+    }
+
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/views/main/admin/federation/routerBasedFederation/step2_view.js
 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step2_view.js
new file mode 100644
index 0000000000..07c4f3bab0
--- /dev/null
+++ 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step2_view.js
@@ -0,0 +1,25 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep2View = App.AssignMasterComponentsView.extend({
+    title: Em.I18n.t('admin.routerFederation.wizard.step2.header'),
+    alertMessage: 
Em.computed.i18nFormat('admin.routerFederation.wizard.step2.body', 
'controller.content.nameServiceId')
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/views/main/admin/federation/routerBasedFederation/step3_view.js
 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step3_view.js
new file mode 100644
index 0000000000..d79b9f4e0b
--- /dev/null
+++ 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step3_view.js
@@ -0,0 +1,31 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep3View = Em.View.extend({
+
+    templateName: 
require('templates/main/admin/federation/routerBasedFederation/step3'),
+
+    didInsertElement: function () {
+        this.get('controller').loadStep();
+    },
+    addRouters: function () {
+        return 
this.get('controller.content.masterComponentHosts').filterProperty('component', 
'ROUTER').filterProperty('isInstalled', false).mapProperty('hostName');
+    }.property('controller.content.masterComponentHosts'),
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/views/main/admin/federation/routerBasedFederation/step4_view.js
 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step4_view.js
new file mode 100644
index 0000000000..b4ef26551f
--- /dev/null
+++ 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/step4_view.js
@@ -0,0 +1,35 @@
+/**
+ * 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');
+
+App.RouterFederationWizardStep4View = 
App.HighAvailabilityProgressPageView.extend({
+
+    templateName: 
require('templates/main/admin/federation/routerBasedFederation/step4'),
+
+    headerTitle: Em.I18n.t('admin.routerFederation.wizard.step4.header'),
+
+    noticeInProgress: 
Em.I18n.t('admin.routerFederation.wizard.step4.notice.inProgress'),
+
+    noticeCompleted: 
Em.I18n.t('admin.routerFederation.wizard.step4.notice.completed'),
+
+    submitButtonText: Em.I18n.t('common.complete'),
+
+    labelWidth: 'col-md-5'
+
+});
\ No newline at end of file
diff --git 
a/ambari-web/app/views/main/admin/federation/routerBasedFederation/wizard_view.js
 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/wizard_view.js
new file mode 100644
index 0000000000..6c15e364aa
--- /dev/null
+++ 
b/ambari-web/app/views/main/admin/federation/routerBasedFederation/wizard_view.js
@@ -0,0 +1,32 @@
+/**
+ * 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');
+
+App.RouterFederationWizardView = Em.View.extend(App.WizardMenuMixin, 
App.WizardHostsLoading, {
+
+    templateName: 
require('templates/main/admin/federation/routerBasedFederation/wizard'),
+
+    didInsertElement: function() {
+        var currentStep = this.get('controller.currentStep');
+        if (currentStep > 3) {
+            this.get('controller').setLowerStepsDisable(currentStep);
+        }
+    }
+});
\ No newline at end of file
diff --git a/ambari-web/app/views/main/service/item.js 
b/ambari-web/app/views/main/service/item.js
index bb61663e0e..b887e1eae1 100644
--- a/ambari-web/app/views/main/service/item.js
+++ b/ambari-web/app/views/main/service/item.js
@@ -241,6 +241,13 @@ App.MainServiceItemView = 
Em.View.extend(App.HiveInteractiveCheck, {
               break;
           }
         }
+        if (service.get('serviceTypes').contains('DFSRouter') && 
App.isAuthorized('SERVICE.ENABLE_HA')) {
+          switch (service.get('serviceName')) {
+            case 'HDFS':
+              options.push(actionMap.TOGGLE_RBF_FEDERATION);
+              break;
+          }
+        }
         if (serviceCheckSupported) {
           options.push(actionMap.RUN_SMOKE_TEST);
         }
diff --git a/ambari-web/test/models/service_test.js 
b/ambari-web/test/models/service_test.js
index c600af6781..fdcd0eb08b 100644
--- a/ambari-web/test/models/service_test.js
+++ b/ambari-web/test/models/service_test.js
@@ -137,7 +137,7 @@ describe('App.Service', function () {
       },
       {
         serviceName: 'HDFS',
-        result: ['HA_MODE', 'FEDERATION']
+        result: ['HA_MODE', 'FEDERATION', 'DFSRouter']
       },
       {
         serviceName: 'YARN',


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to