You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/02/24 16:08:27 UTC

[40/50] [abbrv] ambari git commit: Merge branch 'trunk' into branch-dev-patch-upgrade

Merge branch 'trunk' into branch-dev-patch-upgrade


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2eea1bfa
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2eea1bfa
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2eea1bfa

Branch: refs/heads/trunk
Commit: 2eea1bfa9008b0e17dcca8c196ea911fdce041fd
Parents: 4d3839c 4fcca62
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Feb 22 11:48:00 2016 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Feb 22 11:48:00 2016 -0500

----------------------------------------------------------------------
 .../python/resource_management/core/logger.py   |   2 +-
 .../timeline/AbstractTimelineMetricsSink.java   |  53 +++++-
 .../ApplicationHistoryServer.java               |   6 +-
 .../loadsimulator/net/RestMetricsSender.java    |   4 +-
 .../ApplicationHistoryStoreTestUtils.java       |   2 +-
 .../TestApplicationHistoryClientService.java    |   6 +-
 .../TestFileSystemApplicationHistoryStore.java  |  12 +-
 .../TestMemoryApplicationHistoryStore.java      |  12 +-
 .../webapp/TestAHSWebServices.java              |   2 +-
 .../server/checks/CheckDatabaseHelper.java      | 137 ++++++++-----
 .../server/configuration/Configuration.java     |  89 +++++++++
 .../server/controller/ControllerModule.java     |  16 ++
 .../controller/ServiceComponentRequest.java     |  35 +++-
 .../controller/ServiceComponentResponse.java    |  22 ++-
 .../internal/ComponentResourceProvider.java     |  38 ++++
 .../server/orm/dao/HostRoleCommandDAO.java      | 166 +++++++++++++---
 .../orm/entities/HostRoleCommandEntity.java     |   7 +-
 .../ServiceComponentDesiredStateEntity.java     |  11 ++
 .../serveraction/ServerActionExecutor.java      |  13 +-
 .../ambari/server/state/ServiceComponent.java   |  14 ++
 .../server/state/ServiceComponentImpl.java      |  81 +++++++-
 .../server/state/cluster/ClusterImpl.java       |  36 ++--
 .../services/AlertNoticeDispatchService.java    |  17 +-
 .../server/upgrade/UpgradeCatalog222.java       |  55 ++++++
 .../server/upgrade/UpgradeCatalog240.java       |  14 ++
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |   1 +
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   2 +
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   2 +
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   4 +
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |   2 +
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |   2 +
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   2 +-
 .../src/main/resources/alert-templates.xml      |  20 +-
 .../1.6.1.2.2.0/configuration/accumulo-env.xml  |   1 -
 .../0.5.0.2.1/configuration/falcon-env.xml      |   1 -
 .../FLUME/1.4.0.2.0/configuration/flume-env.xml |   1 -
 .../0.96.0.2.0/configuration/hbase-env.xml      |   1 -
 .../HDFS/2.1.0.2.0/configuration/hadoop-env.xml |   1 -
 .../HIVE/0.12.0.2.0/configuration/hive-env.xml  |   1 -
 .../HIVE/0.12.0.2.0/configuration/hive-site.xml |   1 +
 .../0.8.1.2.2/configuration/kafka-broker.xml    |   1 -
 .../OOZIE/4.0.0.2.0/configuration/oozie-env.xml |   1 -
 .../configuration-mapred/mapred-env.xml         |   1 -
 .../YARN/2.1.0.2.0/configuration/yarn-env.xml   |   1 -
 .../3.4.5.2.0/configuration/zookeeper-env.xml   |   1 -
 .../src/main/resources/properties.json          |   1 +
 .../main/resources/scripts/Ambaripreupload.py   |  46 +++--
 .../stacks/HDP/2.0.6/services/stack_advisor.py  |   5 +-
 .../services/HBASE/configuration/hbase-env.xml  |   1 -
 .../stacks/HDP/2.2/services/stack_advisor.py    |  17 +-
 .../services/HIVE/configuration/hive-site.xml   |   2 +
 .../stacks/HDP/2.3/services/stack_advisor.py    |  32 ++--
 .../stacks/HDP/2.4/services/HIVE/metainfo.xml   |  41 +++-
 .../actionmanager/TestActionScheduler.java      |  24 +--
 .../ambari/server/agent/AgentResourceTest.java  |   2 +
 .../server/checks/CheckDatabaseHelperTest.java  |  20 +-
 .../server/configuration/ConfigurationTest.java |  95 ++++++++++
 .../AmbariManagementControllerTest.java         |   3 +
 .../server/controller/KerberosHelperTest.java   |   2 +
 .../internal/ComponentResourceProviderTest.java |  37 ++--
 .../ambari/server/stack/StackManagerTest.java   |  35 ++--
 .../ambari/server/state/ConfigHelperTest.java   |   2 +
 .../server/upgrade/UpgradeCatalog222Test.java   | 134 ++++++++++++-
 .../server/upgrade/UpgradeCatalog240Test.java   |  12 ++
 .../ambari/server/utils/StageUtilsTest.java     |   2 +
 .../stacks/2.0.6/common/test_stack_advisor.py   |  12 +-
 .../stacks/2.2/common/test_stack_advisor.py     |  14 +-
 .../stacks/2.3/common/test_stack_advisor.py     |  46 +++++
 ambari-web/app/assets/test/tests.js             |   1 +
 .../hawq/addStandby/step3_controller.js         |   2 +-
 .../app/mappers/components_state_mapper.js      |   5 +
 ambari-web/app/messages.js                      |   5 +
 .../app/models/alerts/alert_definition.js       |   4 +-
 ambari-web/app/views.js                         |   1 +
 .../configs/widgets/list_config_widget_view.js  |  11 +-
 ambari-web/app/views/main/dashboard/widgets.js  |  19 +-
 .../main/dashboard/widgets/hawqsegment_live.js  | 190 +++++++++++++++++++
 ambari-web/test/controllers/installer_test.js   |   2 +-
 .../progress_popup_controller_test.js           |   4 +-
 ...anage_alert_notifications_controller_test.js |   8 +-
 .../main/service/info/config_test.js            |   2 +-
 .../widgets/create/step2_controller_test.js     |   2 +-
 .../test/controllers/main/service_test.js       |  12 --
 .../test/controllers/wizard/step3_test.js       |  18 --
 .../test/controllers/wizard/step7_test.js       |   2 +-
 .../test/controllers/wizard/step9_test.js       |   7 +-
 .../test/mappers/server_data_mapper_test.js     |   8 +-
 .../mixins/common/configs/configs_saver_test.js |  10 +-
 .../host_components/install_component_test.js   |   2 +-
 .../test/models/alerts/alert_instance_test.js   |   3 +-
 ambari-web/test/utils/form_field_test.js        |   2 +-
 .../widgets/slider_config_widget_view_test.js   |   4 +-
 ambari-web/test/views/common/table_view_test.js |   2 +-
 .../admin/stack_upgrade/services_view_test.js   |   6 +-
 .../views/main/alert_definitions_view_test.js   |   4 +-
 .../test/views/main/dashboard/widget_test.js    |  18 +-
 .../dashboard/widgets/hawqsegment_live_test.js  |  69 +++++++
 .../ambari_metrics/regionserver_base_test.js    |   2 +-
 ambari-web/test/views/wizard/step5_view_test.js |   4 +-
 ambari-web/test/views/wizard/step9_view_test.js |  31 ++-
 100 files changed, 1564 insertions(+), 378 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
index 65cc107,630eef2..519e4e6
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
@@@ -151,35 -115,14 +154,43 @@@ public class ServiceComponentDesiredSta
      this.desiredStack = desiredStack;
    }
  
 +  /**
 +   * Adds a historical entry for the version of this service component. New
 +   * entries are automatically created when this entities is merged via a
 +   * {@link CascadeType#MERGE}.
 +   *
 +   * @param historicalEntry
 +   *          the entry to add.
 +   */
 +  public void addHistory(ServiceComponentHistoryEntity historicalEntry) {
 +    if (null == serviceComponentHistory) {
 +      serviceComponentHistory = new ArrayList<>();
 +    }
 +
 +    serviceComponentHistory.add(historicalEntry);
 +
 +    if (!equals(historicalEntry.getServiceComponentDesiredState())) {
 +      historicalEntry.setServiceComponentDesiredState(this);
 +    }
 +  }
 +
 +  /**
 +   * Gets the history of this component's upgrades and downgrades.
 +   *
 +   * @return the component history, or {@code null} if none.
 +   */
 +  public Collection<ServiceComponentHistoryEntity> getHistory() {
 +    return serviceComponentHistory;
 +  }
 +
+   public boolean isRecoveryEnabled() {
+     return recoveryEnabled != 0;
+   }
+ 
+   public void setRecoveryEnabled(boolean recoveryEnabled) {
+     this.recoveryEnabled = (recoveryEnabled == false) ? 0 : 1;
+   }
+ 
    @Override
    public boolean equals(Object o) {
      if (this == o) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
index 4afc857,7b866a9..eca911d
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
@@@ -95,7 -95,8 +95,7 @@@ public class ServiceComponentImpl imple
      desiredStateEntity.setDesiredState(State.INIT);
      desiredStateEntity.setServiceName(service.getName());
      desiredStateEntity.setClusterId(service.getClusterId());
- 
+     desiredStateEntity.setRecoveryEnabled(false);
 -    desiredStateEntityPK = getDesiredStateEntityPK(desiredStateEntity);
      setDesiredStackVersion(service.getDesiredStackVersion());
  
      hostComponents = new HashMap<String, ServiceComponentHost>();
@@@ -178,9 -180,66 +178,58 @@@
  
    @Override
    public String getName() {
 -    ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
 -    if (desiredStateEntity != null) {
 -      return desiredStateEntity.getComponentName();
 -    } else {
 -      LOG.warn("Trying to fetch a member from an entity object that may " +
 -        "have been previously deleted, serviceName = " + getServiceName() + ", " +
 -        "componentName = " + componentName);
 -    }
 -    return null;
 +    return componentName;
    }
  
+   /**
+    * Get the recoveryEnabled value.
+    *
+    * @return true or false
+    */
+   @Override
+   public boolean isRecoveryEnabled() {
+     ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+     if (desiredStateEntity != null) {
+       return desiredStateEntity.isRecoveryEnabled();
+     } else {
+       LOG.warn("Trying to fetch a member from an entity object that may " +
+               "have been previously deleted, serviceName = " + service.getName() + ", " +
+               "componentName = " + componentName);
+     }
+     return false;
+   }
+ 
+   /**
+    * Set the recoveryEnabled field in the entity object.
+    *
+    * @param recoveryEnabled - true or false
+    */
+   @Override
+   public void setRecoveryEnabled(boolean recoveryEnabled) {
+     readWriteLock.writeLock().lock();
+     try {
+       if (LOG.isDebugEnabled()) {
+         LOG.debug("Setting RecoveryEnabled of Component" + ", clusterName="
+                 + service.getCluster().getClusterName() + ", clusterId="
+                 + service.getCluster().getClusterId() + ", serviceName="
+                 + service.getName() + ", componentName=" + getName()
+                 + ", oldRecoveryEnabled=" + isRecoveryEnabled() + ", newRecoveryEnabled="
+                 + recoveryEnabled);
+       }
+       ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+       if (desiredStateEntity != null) {
+         desiredStateEntity.setRecoveryEnabled(recoveryEnabled);
 -        saveIfPersisted();
++        saveIfPersisted(desiredStateEntity);
+       } else {
+         LOG.warn("Setting a member on an entity object that may have been " +
+                 "previously deleted, serviceName = " + service.getName());
+       }
+ 
+     } finally {
+       readWriteLock.writeLock().unlock();
+     }
+   }
+ 
    @Override
    public String getServiceName() {
      return service.getName();

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
index 09f31e4,6a8ead1..f2055a6
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
@@@ -127,10 -117,8 +129,11 @@@ public class UpgradeCatalog240 extends 
    @Override
    protected void executeDDLUpdates() throws AmbariException, SQLException {
      updateAdminPermissionTable();
+     updateServiceComponentDesiredStateTable();
      createSettingTable();
 +    updateRepoVersionTableDDL();
 +    updateServiceComponentDesiredStateTableDDL();
 +    createServiceComponentHistoryTable();
    }
  
    @Override
@@@ -408,158 -395,13 +411,169 @@@
    }
  
    /**
 +   * Makes the following changes to the {@value #REPO_VERSION_TABLE} table:
 +   * <ul>
 +   * <li>repo_type VARCHAR(255) DEFAULT 'STANDARD' NOT NULL</li>
 +   * <li>version_url VARCHAR(1024)</li>
 +   * <li>version_xml MEDIUMTEXT</li>
 +   * <li>version_xsd VARCHAR(512)</li>
 +   * <li>parent_id BIGINT</li>
 +   * </ul>
 +   *
 +   * @throws SQLException
 +   */
 +  private void updateRepoVersionTableDDL() throws SQLException {
 +    DBColumnInfo repoTypeColumn = new DBColumnInfo("repo_type", String.class, 255, RepositoryType.STANDARD.name(), false);
 +    DBColumnInfo versionUrlColumn = new DBColumnInfo("version_url", String.class, 1024, null, true);
 +    DBColumnInfo versionXmlColumn = new DBColumnInfo("version_xml", Clob.class, null, null, true);
 +    DBColumnInfo versionXsdColumn = new DBColumnInfo("version_xsd", String.class, 512, null, true);
 +    DBColumnInfo parentIdColumn = new DBColumnInfo("parent_id", Long.class, null, null, true);
 +
 +    dbAccessor.addColumn(REPO_VERSION_TABLE, repoTypeColumn);
 +    dbAccessor.addColumn(REPO_VERSION_TABLE, versionUrlColumn);
 +    dbAccessor.addColumn(REPO_VERSION_TABLE, versionXmlColumn);
 +    dbAccessor.addColumn(REPO_VERSION_TABLE, versionXsdColumn);
 +    dbAccessor.addColumn(REPO_VERSION_TABLE, parentIdColumn);
 +  }
 +
 +  /**
 +   * Makes the following changes to the {@value #SERVICE_COMPONENT_DS_TABLE} table,
 +   * but only if the table doesn't have it's new PK set.
 +   * <ul>
 +   * <li>id BIGINT NOT NULL</li>
 +   * <li>Drops FKs on {@value #HOST_COMPONENT_DS_TABLE} and {@value #HOST_COMPONENT_STATE_TABLE}</li>
 +   * <li>Populates {@value #SQLException#ID} in {@value #SERVICE_COMPONENT_DS_TABLE}</li>
 +   * <li>Creates {@code UNIQUE} constraint on {@value #HOST_COMPONENT_DS_TABLE}</li>
 +   * <li>Adds FKs on {@value #HOST_COMPONENT_DS_TABLE} and {@value #HOST_COMPONENT_STATE_TABLE}</li>
 +   * <li>Adds new sequence value of {@code servicecomponentdesiredstate_id_seq}</li>
 +   * </ul>
 +   *
 +   * @throws SQLException
 +   */
 +  @Transactional
 +  private void updateServiceComponentDesiredStateTableDDL() throws SQLException {
 +    if (dbAccessor.tableHasPrimaryKey(SERVICE_COMPONENT_DS_TABLE, ID)) {
 +      LOG.info("Skipping {} table Primary Key modifications since the new {} column already exists",
 +          SERVICE_COMPONENT_DS_TABLE, ID);
 +
 +      return;
 +    }
 +
 +    // drop FKs to SCDS in both HCDS and HCS tables
 +    dbAccessor.dropFKConstraint(HOST_COMPONENT_DS_TABLE, "hstcmpnntdesiredstatecmpnntnme");
 +    dbAccessor.dropFKConstraint(HOST_COMPONENT_STATE_TABLE, "hstcomponentstatecomponentname");
 +
 +    // remove existing compound PK
 +    dbAccessor.dropPKConstraint(SERVICE_COMPONENT_DS_TABLE, "servicecomponentdesiredstate_pkey");
 +
 +    // add new PK column to SCDS, making it nullable for now
 +    DBColumnInfo idColumn = new DBColumnInfo(ID, Long.class, null, null, true);
 +    dbAccessor.addColumn(SERVICE_COMPONENT_DS_TABLE, idColumn);
 +
 +    // populate SCDS id column
 +    AtomicLong scdsIdCounter = new AtomicLong(1);
 +    Statement statement = null;
 +    ResultSet resultSet = null;
 +    try {
 +      statement = dbAccessor.getConnection().createStatement();
 +      if (statement != null) {
 +        String selectSQL = String.format("SELECT cluster_id, service_name, component_name FROM %s",
 +            SERVICE_COMPONENT_DS_TABLE);
 +
 +        resultSet = statement.executeQuery(selectSQL);
 +        while (null != resultSet && resultSet.next()) {
 +          final Long clusterId = resultSet.getLong("cluster_id");
 +          final String serviceName = resultSet.getString("service_name");
 +          final String componentName = resultSet.getString("component_name");
 +
 +          String updateSQL = String.format(
 +              "UPDATE %s SET %s = %d WHERE cluster_id = %d AND service_name = '%s' AND component_name = '%s'",
 +              SERVICE_COMPONENT_DS_TABLE, ID, scdsIdCounter.getAndIncrement(), clusterId,
 +              serviceName, componentName);
 +
 +          dbAccessor.executeQuery(updateSQL);
 +        }
 +      }
 +    } finally {
 +      JdbcUtils.closeResultSet(resultSet);
 +      JdbcUtils.closeStatement(statement);
 +    }
 +
 +    // make the column NON NULL now
 +    dbAccessor.alterColumn(SERVICE_COMPONENT_DS_TABLE,
 +        new DBColumnInfo(ID, Long.class, null, null, false));
 +
 +    // create a new PK, matching the name of the constraint found in SQL
 +    dbAccessor.addPKConstraint(SERVICE_COMPONENT_DS_TABLE, "pk_sc_desiredstate", ID);
 +
 +    // create UNIQUE constraint, ensuring column order matches SQL files
 +    String[] uniqueColumns = new String[] { "component_name", "service_name", "cluster_id" };
 +    dbAccessor.addUniqueConstraint(SERVICE_COMPONENT_DS_TABLE, "unq_scdesiredstate_name",
 +        uniqueColumns);
 +
 +    // add FKs back to SCDS in both HCDS and HCS tables
 +    dbAccessor.addFKConstraint(HOST_COMPONENT_DS_TABLE, "hstcmpnntdesiredstatecmpnntnme",
 +        uniqueColumns, SERVICE_COMPONENT_DS_TABLE, uniqueColumns, false);
 +
 +    dbAccessor.addFKConstraint(HOST_COMPONENT_STATE_TABLE, "hstcomponentstatecomponentname",
 +        uniqueColumns, SERVICE_COMPONENT_DS_TABLE, uniqueColumns, false);
 +
 +    // Add sequence for SCDS id
 +    addSequence("servicecomponentdesiredstate_id_seq", scdsIdCounter.get(), false);
 +  }
 +
 +  /**
 +   * Makes the following changes to the {@value #SERVICE_COMPONENT_HISTORY_TABLE} table:
 +   * <ul>
 +   * <li>id BIGINT NOT NULL</li>
 +   * <li>component_id BIGINT NOT NULL</li>
 +   * <li>upgrade_id BIGINT NOT NULL</li>
 +   * <li>from_stack_id BIGINT NOT NULL</li>
 +   * <li>to_stack_id BIGINT NOT NULL</li>
 +   * <li>CONSTRAINT PK_sc_history PRIMARY KEY (id)</li>
 +   * <li>CONSTRAINT FK_sc_history_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate (id)</li>
 +   * <li>CONSTRAINT FK_sc_history_upgrade_id FOREIGN KEY (upgrade_id) REFERENCES upgrade (upgrade_id)</li>
 +   * <li>CONSTRAINT FK_sc_history_from_stack_id FOREIGN KEY (from_stack_id) REFERENCES stack (stack_id)</li>
 +   * <li>CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)</li>
 +   * <li>Creates the {@code servicecomponent_history_id_seq}</li>
 +   * </ul>
 +   *
 +   * @throws SQLException
 +   */
 +  private void createServiceComponentHistoryTable() throws SQLException {
 +    List<DBColumnInfo> columns = new ArrayList<>();
 +    columns.add(new DBColumnInfo(ID, Long.class, null, null, false));
 +    columns.add(new DBColumnInfo("component_id", Long.class, null, null, false));
 +    columns.add(new DBColumnInfo("upgrade_id", Long.class, null, null, false));
 +    columns.add(new DBColumnInfo("from_stack_id", Long.class, null, null, false));
 +    columns.add(new DBColumnInfo("to_stack_id", Long.class, null, null, false));
 +    dbAccessor.createTable(SERVICE_COMPONENT_HISTORY_TABLE, columns, (String[]) null);
 +
 +    dbAccessor.addPKConstraint(SERVICE_COMPONENT_HISTORY_TABLE, "PK_sc_history", ID);
 +
 +    dbAccessor.addFKConstraint(SERVICE_COMPONENT_HISTORY_TABLE, "FK_sc_history_component_id",
 +        "component_id", SERVICE_COMPONENT_DS_TABLE, "id", false);
 +
 +    dbAccessor.addFKConstraint(SERVICE_COMPONENT_HISTORY_TABLE, "FK_sc_history_upgrade_id",
 +        "upgrade_id", UPGRADE_TABLE, "upgrade_id", false);
 +
 +    dbAccessor.addFKConstraint(SERVICE_COMPONENT_HISTORY_TABLE, "FK_sc_history_from_stack_id",
 +        "from_stack_id", STACK_TABLE, "stack_id", false);
 +
 +    dbAccessor.addFKConstraint(SERVICE_COMPONENT_HISTORY_TABLE, "FK_sc_history_to_stack_id",
 +        "to_stack_id", STACK_TABLE, "stack_id", false);
 +
 +    addSequence("servicecomponent_history_id_seq", 0L, false);
 +  }
++
++  /**
+    * Alter servicecomponentdesiredstate table to add recovery_enabled column.
+    * @throws SQLException
+    */
+   private void updateServiceComponentDesiredStateTable() throws SQLException {
+     // ALTER TABLE servicecomponentdesiredstate ADD COLUMN
+     // recovery_enabled SMALLINT DEFAULT 0 NOT NULL
+     dbAccessor.addColumn(SERVICE_COMPONENT_DESIRED_STATE_TABLE,
 -            new DBAccessor.DBColumnInfo(RECOVERY_ENABLED_COL, Short.class, null, 0, false));
++            new DBColumnInfo(RECOVERY_ENABLED_COL, Short.class, null, 0, false));
+   }
  }

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 2db745b,6d63a90..bd7755c
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@@ -177,8 -176,8 +177,9 @@@ CREATE TABLE servicecomponentdesiredsta
    desired_stack_id BIGINT NOT NULL,
    desired_state VARCHAR(255) NOT NULL,
    service_name VARCHAR(255) NOT NULL,
+   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
 -  PRIMARY KEY (component_name, cluster_id, service_name)
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
  );
  
  CREATE TABLE servicedesiredstate (

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index b892bc8,2898ab7..ac1c5d7
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@@ -178,8 -177,8 +178,9 @@@ CREATE TABLE servicecomponentdesiredsta
    desired_stack_id BIGINT NOT NULL,
    desired_state VARCHAR(255) NOT NULL,
    service_name VARCHAR(100) NOT NULL,
+   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
 -  PRIMARY KEY (component_name, cluster_id, service_name)
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
  );
  
  CREATE TABLE servicedesiredstate (

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index 026efea,092f8c2..4ed3a19
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@@ -168,8 -167,8 +168,9 @@@ CREATE TABLE servicecomponentdesiredsta
    desired_stack_id NUMBER(19) NOT NULL,
    desired_state VARCHAR2(255) NOT NULL,
    service_name VARCHAR2(255) NOT NULL,
+   recovery_enabled SMALLINT DEFAULT 0 NOT NULL,
 -  PRIMARY KEY (component_name, cluster_id, service_name)
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
  );
  
  CREATE TABLE servicedesiredstate (

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index fb9889d,150ea9b..5d7be25
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@@ -177,8 -176,8 +177,9 @@@ CREATE TABLE servicecomponentdesiredsta
    desired_stack_id BIGINT NOT NULL,
    desired_state VARCHAR(255) NOT NULL,
    service_name VARCHAR(255) NOT NULL,
+   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
 -  PRIMARY KEY (component_name, cluster_id, service_name)
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
  );
  
  CREATE TABLE servicedesiredstate (

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index 3cc7516,0443336..c032b8f
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@@ -202,8 -201,8 +202,9 @@@ CREATE TABLE ambari.servicecomponentdes
    desired_stack_id BIGINT NOT NULL,
    desired_state VARCHAR(255) NOT NULL,
    service_name VARCHAR(255) NOT NULL,
+   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
 -  PRIMARY KEY (component_name, cluster_id, service_name)
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
  );
  GRANT ALL PRIVILEGES ON TABLE ambari.servicecomponentdesiredstate TO :username;
  

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index a5bfdc2,20a7634..6a6b77b
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@@ -167,8 -166,8 +167,9 @@@ CREATE TABLE servicecomponentdesiredsta
    desired_stack_id NUMERIC(19) NOT NULL,
    desired_state VARCHAR(255) NOT NULL,
    service_name VARCHAR(255) NOT NULL,
+   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
 -  PRIMARY KEY (component_name, cluster_id, service_name)
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
  );
  
  CREATE TABLE servicedesiredstate (

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 8e5b2f8,2c9adf3..43419c1
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@@ -187,10 -186,9 +187,9 @@@ CREATE TABLE servicecomponentdesiredsta
    desired_stack_id BIGINT NOT NULL,
    desired_state VARCHAR(255) NOT NULL,
    service_name VARCHAR(255) NOT NULL,
-   PRIMARY KEY CLUSTERED (id),
 -  recovery_enabled SMALLINT NOT NULL DEFAULT 0,
 -  PRIMARY KEY CLUSTERED (component_name, cluster_id, service_name)
 -  );
 +  CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
 +  CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id)
 +);
  
  CREATE TABLE servicedesiredstate (
    cluster_id BIGINT NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-web/app/messages.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eea1bfa/ambari-web/app/views.js
----------------------------------------------------------------------