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 2015/10/28 16:17:20 UTC
ambari git commit: AMBARI-13591. RU and EU: Allow set-current to
force a version into the db (ncole)
Repository: ambari
Updated Branches:
refs/heads/trunk c52c40fa1 -> 81c608f48
AMBARI-13591. RU and EU: Allow set-current to force a version into the db (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/81c608f4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/81c608f4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/81c608f4
Branch: refs/heads/trunk
Commit: 81c608f4896828411871f7874168bff2e8bdb84b
Parents: c52c40f
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Oct 27 17:01:15 2015 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Oct 28 11:10:08 2015 -0400
----------------------------------------------------------------------
.../ClusterStackVersionResourceProvider.java | 150 ++++++++++-------
.../server/orm/dao/ClusterVersionDAO.java | 39 ++++-
.../orm/dao/HostComponentDesiredStateDAO.java | 19 ++-
.../server/orm/dao/HostComponentStateDAO.java | 31 ++++
.../ambari/server/orm/dao/HostVersionDAO.java | 33 ++++
ambari-server/src/main/python/ambari-server.py | 2 +-
.../main/python/ambari_server/serverUpgrade.py | 11 +-
...ClusterStackVersionResourceProviderTest.java | 159 +++++++++++++++++++
.../src/test/python/TestServerUpgrade.py | 55 ++++++-
9 files changed, 433 insertions(+), 66 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 2a1431d..adae105 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -17,10 +17,18 @@
*/
package org.apache.ambari.server.controller.internal;
-import com.google.gson.Gson;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Provider;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.StaticallyInject;
@@ -52,6 +60,7 @@ import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.events.ActionFinalReportReceivedEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
import org.apache.ambari.server.orm.dao.HostVersionDAO;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
@@ -74,17 +83,11 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.utils.StageUtils;
import org.apache.commons.lang.StringUtils;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Provider;
+import com.google.inject.persist.Transactional;
/**
* Resource provider for cluster stack versions resources.
@@ -102,6 +105,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
protected static final String CLUSTER_STACK_VERSION_HOST_STATES_PROPERTY_ID = PropertyHelper.getPropertyId("ClusterStackVersions", "host_states");
protected static final String CLUSTER_STACK_VERSION_REPOSITORY_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("ClusterStackVersions", "repository_version");
protected static final String CLUSTER_STACK_VERSION_STAGE_SUCCESS_FACTOR = PropertyHelper.getPropertyId("ClusterStackVersions", "success_factor");
+ protected static final String CLUSTER_STACK_VERSION_FORCE = "ClusterStackVersions/force";
protected static final String INSTALL_PACKAGES_ACTION = "install_packages";
protected static final String INSTALL_PACKAGES_FULL_NAME = "Install version";
@@ -141,6 +145,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
add(CLUSTER_STACK_VERSION_STATE_PROPERTY_ID);
add(CLUSTER_STACK_VERSION_REPOSITORY_VERSION_PROPERTY_ID);
add(CLUSTER_STACK_VERSION_STAGE_SUCCESS_FACTOR);
+ add(CLUSTER_STACK_VERSION_FORCE);
}
};
@@ -187,6 +192,9 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
@Inject
private static Injector injector;
+ @Inject
+ private static HostComponentStateDAO hostComponentStateDAO;
+
/**
* We have to include such a hack here, because if we
* make finalizeUpgradeAction field static and request injection
@@ -639,54 +647,72 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
Cluster cluster = getManagementController().getClusters().getCluster(clName);
cluster.setDesiredStackVersion(stackId);
- Map<String, String> args = new HashMap<String, String>();
- if (newStateStr.equals(RepositoryVersionState.CURRENT.toString())) {
- // Finalize upgrade workflow
- args.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
- } else if (newStateStr.equals(RepositoryVersionState.INSTALLED.toString())) {
- // Finalize downgrade workflow
- args.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "downgrade");
- } else {
- throw new IllegalArgumentException(
- String.format("Invalid desired state %s. Should be either CURRENT or INSTALLED",
- newStateStr));
+ String forceCurrent = (String) propertyMap.get(CLUSTER_STACK_VERSION_FORCE);
+ boolean force = false;
+ if (null != forceCurrent) {
+ force = Boolean.parseBoolean(forceCurrent);
}
- // Get a host name to populate the hostrolecommand table's hostEntity.
- String defaultHostName;
- ArrayList<Host> hosts = new ArrayList<Host>(cluster.getHosts());
- if (!hosts.isEmpty()) {
- Collections.sort(hosts);
- defaultHostName = hosts.get(0).getHostName();
- } else {
- throw new AmbariException("Could not find at least one host to set the command for");
- }
+ if (!force) {
+ Map<String, String> args = new HashMap<String, String>();
+ if (newStateStr.equals(RepositoryVersionState.CURRENT.toString())) {
+ // Finalize upgrade workflow
+ args.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
+ } else if (newStateStr.equals(RepositoryVersionState.INSTALLED.toString())) {
+ // Finalize downgrade workflow
+ args.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "downgrade");
+ } else {
+ throw new IllegalArgumentException(
+ String.format("Invalid desired state %s. Should be either CURRENT or INSTALLED",
+ newStateStr));
+ }
- args.put(FinalizeUpgradeAction.VERSION_KEY, desiredRepoVersion);
- args.put(FinalizeUpgradeAction.CLUSTER_NAME_KEY, clName);
+ // Get a host name to populate the hostrolecommand table's hostEntity.
+ String defaultHostName;
+ ArrayList<Host> hosts = new ArrayList<Host>(cluster.getHosts());
+ if (!hosts.isEmpty()) {
+ Collections.sort(hosts);
+ defaultHostName = hosts.get(0).getHostName();
+ } else {
+ throw new AmbariException("Could not find at least one host to set the command for");
+ }
- ExecutionCommand command = new ExecutionCommand();
- command.setCommandParams(args);
- command.setClusterName(clName);
- finalizeUpgradeAction.setExecutionCommand(command);
+ args.put(FinalizeUpgradeAction.VERSION_KEY, desiredRepoVersion);
+ args.put(FinalizeUpgradeAction.CLUSTER_NAME_KEY, clName);
- HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(defaultHostName,
- Role.AMBARI_SERVER_ACTION, null, null);
- finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand);
+ ExecutionCommand command = new ExecutionCommand();
+ command.setCommandParams(args);
+ command.setClusterName(clName);
+ finalizeUpgradeAction.setExecutionCommand(command);
- CommandReport report = finalizeUpgradeAction.execute(null);
+ HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(defaultHostName,
+ Role.AMBARI_SERVER_ACTION, null, null);
+ finalizeUpgradeAction.setHostRoleCommand(hostRoleCommand);
- LOG.info("Finalize output:");
- LOG.info("STDOUT: {}", report.getStdOut());
- LOG.info("STDERR: {}", report.getStdErr());
+ CommandReport report = finalizeUpgradeAction.execute(null);
- if (report.getStatus().equals(HostRoleStatus.COMPLETED.toString())) {
- return getRequestStatus(null);
+ LOG.info("Finalize output:");
+ LOG.info("STDOUT: {}", report.getStdOut());
+ LOG.info("STDERR: {}", report.getStdErr());
+
+ if (report.getStatus().equals(HostRoleStatus.COMPLETED.toString())) {
+ return getRequestStatus(null);
+ } else {
+ String detailedOutput = "Finalization failed. More details: \n" +
+ "STDOUT: " + report.getStdOut() + "\n" +
+ "STDERR: " + report.getStdErr();
+ throw new SystemException(detailedOutput);
+ }
} else {
- String detailedOutput = "Finalization failed. More details: \n" +
- "STDOUT: " + report.getStdOut() + "\n" +
- "STDERR: " + report.getStdErr();
- throw new SystemException(detailedOutput);
+ // !!! revisit for PU
+ ClusterVersionEntity current = cluster.getCurrentClusterVersion();
+
+ if (!current.getRepositoryVersion().equals(rve)) {
+ updateVersionStates(current.getClusterId(), current.getRepositoryVersion(), rve);
+ }
+
+
+ return getRequestStatus(null);
}
} catch (AmbariException e) {
throw new SystemException("Cannot perform request", e);
@@ -729,4 +755,20 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
return healthyHosts;
}
+
+ /**
+ * Updates the version states. Transactional to ensure only one transaction for all updates
+ * @param clusterId the cluster
+ * @param current the repository that is current for the cluster
+ * @param target the target repository
+ */
+ @Transactional
+ protected void updateVersionStates(Long clusterId, RepositoryVersionEntity current,
+ RepositoryVersionEntity target) {
+
+ hostComponentStateDAO.updateVersions(target.getVersion());
+ hostVersionDAO.updateVersions(target, current);
+ clusterVersionDAO.updateVersions(clusterId, target, current);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
index 8d4c5ee..28449ae 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
@@ -19,11 +19,11 @@ package org.apache.ambari.server.orm.dao;
import java.util.List;
+import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.TypedQuery;
-import com.google.inject.persist.Transactional;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
@@ -32,6 +32,7 @@ import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.StackId;
import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
/**
* The {@link ClusterVersionDAO} class manages the {@link ClusterVersionEntity} instances associated with a cluster.
@@ -176,4 +177,40 @@ public class ClusterVersionDAO extends CrudDAO<ClusterVersionEntity, Long>{
this.create(clusterVersionEntity);
return clusterVersionEntity;
}
+
+ /**
+ * Updates the cluster version's existing CURRENT record to the INSTALLED, and the target
+ * becomes CURRENT. This method invokes {@code clear()} on the entity manager to force entities to be refreshed.
+ * @param clusterId the cluster
+ * @param target the repo version that will be marked as CURRENT
+ * @param current the cluster's current record to be marked INSTALLED
+ */
+ @Transactional
+ public void updateVersions(Long clusterId, RepositoryVersionEntity target, RepositoryVersionEntity current) {
+ // !!! first update target to be current
+ StringBuilder sb = new StringBuilder("UPDATE ClusterVersionEntity cve");
+ sb.append(" SET cve.state = ?1 ");
+ sb.append(" WHERE cve.clusterId = ?2");
+ sb.append(" AND cve.repositoryVersion = ?3");
+
+ EntityManager em = entityManagerProvider.get();
+
+ TypedQuery<Long> query = em.createQuery(sb.toString(), Long.class);
+ daoUtils.executeUpdate(query, RepositoryVersionState.CURRENT, clusterId, target);
+
+ // !!! then move existing current to installed
+ sb = new StringBuilder("UPDATE ClusterVersionEntity cve");
+ sb.append(" SET cve.state = ?1 ");
+ sb.append(" WHERE cve.clusterId = ?2");
+ sb.append(" AND cve.repositoryVersion = ?3");
+ sb.append(" AND cve.state = ?4");
+
+ query = em.createQuery(sb.toString(), Long.class);
+ daoUtils.executeUpdate(query, RepositoryVersionState.INSTALLED, clusterId, current,
+ RepositoryVersionState.CURRENT);
+
+ em.clear();
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
index 2620c8c..46da9da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
@@ -18,19 +18,21 @@
package org.apache.ambari.server.orm.dao;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntityPK;
import org.apache.ambari.server.orm.entities.HostEntity;
-import javax.persistence.EntityManager;
-import javax.persistence.NoResultException;
-import javax.persistence.TypedQuery;
-import java.util.List;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
@Singleton
public class HostComponentDesiredStateDAO {
@@ -106,4 +108,5 @@ public class HostComponentDesiredStateDAO {
public void removeByPK(HostComponentDesiredStateEntityPK primaryKey) {
remove(findByPK(primaryKey));
}
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
index d5707be..6389ef2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.orm.dao;
+import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
@@ -27,6 +28,7 @@ import javax.persistence.TypedQuery;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.state.UpgradeState;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -182,4 +184,33 @@ public class HostComponentStateDAO {
hostEntity.removeHostComponentStateEntity(hostComponentStateEntity);
hostDAO.merge(hostEntity);
}
+
+ /**
+ * Marks hosts components to the specified version that are NOT already set or "UNKNOWN".
+ * Also marks all host components as not being in an upgrade state. This method
+ * invokes {@code clear()} on the entity manager to force entities to be refreshed.
+ *
+ * @param version the version
+ */
+ @Transactional
+ public void updateVersions(String version) {
+ EntityManager em = entityManagerProvider.get();
+
+ // !!! first the version
+ StringBuilder sb = new StringBuilder("UPDATE HostComponentStateEntity hostComponent");
+ sb.append(" SET hostComponent.version = ?1 ");
+ sb.append(" WHERE hostComponent.version NOT IN ?2");
+
+ TypedQuery<Long> query = em.createQuery(sb.toString(), Long.class);
+ daoUtils.executeUpdate(query, version, Arrays.asList(version, "UNKNOWN"));
+
+ // !!! now the upgrade state
+ sb = new StringBuilder("UPDATE HostComponentStateEntity hostComponent");
+ sb.append(" SET hostComponent.upgradeState = ?1");
+
+ query = em.createQuery(sb.toString(), Long.class);
+ daoUtils.executeUpdate(query, UpgradeState.NONE);
+
+ em.clear();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index ad617af..a1ffc2a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -28,6 +28,7 @@ import javax.persistence.TypedQuery;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.HostVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.StackId;
@@ -192,4 +193,36 @@ public class HostVersionDAO extends CrudDAO<HostVersionEntity, Long> {
this.remove(hostVersion);
}
}
+
+ /**
+ * Updates the host versions existing CURRENT record to the INSTALLED, and the target
+ * becomes CURRENT. This method invokes {@code clear()} on the entity manager to force entities to be refreshed.
+ * @param target the repo version that all hosts to mark as CURRENT
+ * @param current the repo version that all hosts marked as INSTALLED
+ */
+ @Transactional
+ public void updateVersions(RepositoryVersionEntity target, RepositoryVersionEntity current) {
+ // !!! first update target to be current
+ StringBuilder sb = new StringBuilder("UPDATE HostVersionEntity hve");
+ sb.append(" SET hve.state = ?1 ");
+ sb.append(" WHERE hve.repositoryVersion = ?2");
+
+ EntityManager em = entityManagerProvider.get();
+
+ TypedQuery<Long> query = em.createQuery(sb.toString(), Long.class);
+ daoUtils.executeUpdate(query, RepositoryVersionState.CURRENT, target);
+
+ // !!! then move existing current to installed
+ sb = new StringBuilder("UPDATE HostVersionEntity hve");
+ sb.append(" SET hve.state = ?1 ");
+ sb.append(" WHERE hve.repositoryVersion = ?2");
+ sb.append(" AND hve.state = ?3");
+
+ query = em.createQuery(sb.toString(), Long.class);
+ daoUtils.executeUpdate(query, RepositoryVersionState.INSTALLED, current,
+ RepositoryVersionState.CURRENT);
+
+ em.clear();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/python/ambari-server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index 2fae1ee..56dfecc 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -372,7 +372,7 @@ def init_parser_options(parser):
dest="jdbc_db")
parser.add_option('--cluster-name', default=None, help="Cluster name", dest="cluster_name")
parser.add_option('--version-display-name', default=None, help="Display name of desired repo version", dest="desired_repo_version")
-
+ parser.add_option('--force-version', action="store_true", default=False, help="Force version to current", dest="force_repo_version")
@OsFamilyFuncImpl(OSConst.WINSRV_FAMILY)
def are_cmd_line_db_args_blank(options):
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/main/python/ambari_server/serverUpgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverUpgrade.py b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
index 7048812..312766d 100644
--- a/ambari-server/src/main/python/ambari_server/serverUpgrade.py
+++ b/ambari-server/src/main/python/ambari_server/serverUpgrade.py
@@ -411,7 +411,8 @@ def set_current(options):
data = {
"ClusterStackVersions": {
"repository_version": finalize_options.desired_repo_version,
- "state": "CURRENT"
+ "state": "CURRENT",
+ "force": finalize_options.force_repo_version
}
}
@@ -497,5 +498,13 @@ class SetCurrentVersionOptions:
except AttributeError:
self.desired_repo_version = None
+ try:
+ self.force_repo_version = options.force_repo_version
+ except AttributeError:
+ self.force_repo_version = False
+
+ if not self.force_repo_version:
+ self.force_repo_version = False
+
def no_finalize_options_set(self):
return self.cluster_name is None or self.desired_repo_version is None
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
index 1819ef9..06ae045 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
@@ -63,7 +63,9 @@ import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.dao.ClusterDAO;
import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.HostVersionDAO;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
import org.apache.ambari.server.orm.dao.ResourceTypeDAO;
import org.apache.ambari.server.orm.dao.StackDAO;
@@ -119,6 +121,9 @@ public class ClusterStackVersionResourceProviderTest {
private StageFactory stageFactory;
private AmbariActionExecutionHelper actionExecutionHelper;
+ private HostVersionDAO hostVersionDAO;
+ private HostComponentStateDAO hostComponentStateDAO;
+
private String operatingSystemsJson = "[\n" +
" {\n" +
" \"repositories\":[\n" +
@@ -142,6 +147,9 @@ public class ClusterStackVersionResourceProviderTest {
public void setup() throws Exception {
// Create instances of mocks
repositoryVersionDAOMock = createNiceMock(RepositoryVersionDAO.class);
+ hostVersionDAO = createNiceMock(HostVersionDAO.class);
+ hostComponentStateDAO = createNiceMock(HostComponentStateDAO.class);
+
configHelper = createNiceMock(ConfigHelper.class);
InMemoryDefaultTestModule inMemoryModule = new InMemoryDefaultTestModule();
Properties properties = inMemoryModule.getProperties();
@@ -159,6 +167,7 @@ public class ClusterStackVersionResourceProviderTest {
stackDAO = injector.getInstance(StackDAO.class);
clusterDAO = injector.getInstance(ClusterDAO.class);
hostDAO = injector.getInstance(HostDAO.class);
+
}
@After
@@ -480,6 +489,153 @@ public class ClusterStackVersionResourceProviderTest {
new StackId(newDesiredStack.getStackName(), newDesiredStack.getStackVersion()));
}
+ /**
+ * Tests manual finalization scenario
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateResourcesWithForce() throws Exception {
+
+
+ Resource.Type type = Resource.Type.ClusterStackVersion;
+ String clusterName = "Cluster100";
+
+ AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+ StackId stackId = new StackId("HDP", "2.0.1");
+ StackEntity stackEntity = stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
+ Assert.assertNotNull(stackEntity);
+
+ ResourceTypeEntity resourceTypeEntity = resourceTypeDAO.findById(ResourceTypeEntity.CLUSTER_RESOURCE_TYPE);
+ if (resourceTypeEntity == null) {
+ resourceTypeEntity = new ResourceTypeEntity();
+ resourceTypeEntity.setId(ResourceTypeEntity.CLUSTER_RESOURCE_TYPE);
+ resourceTypeEntity.setName(ResourceTypeEntity.CLUSTER_RESOURCE_TYPE_NAME);
+ resourceTypeEntity = resourceTypeDAO.merge(resourceTypeEntity);
+ }
+ ResourceEntity resourceEntity = new ResourceEntity();
+ resourceEntity.setResourceType(resourceTypeEntity);
+
+ final Host host1 = createNiceMock("host1", Host.class);
+ final Host host2 = createNiceMock("host2", Host.class);
+
+ expect(host1.getHostName()).andReturn("host1").anyTimes();
+ expect(host2.getHostName()).andReturn("host2").anyTimes();
+ replay(host1, host2);
+
+ ServiceComponentHost sch = createMock(ServiceComponentHost.class);
+ List<ServiceComponentHost> schs = Collections.singletonList(sch);
+
+ Cluster cluster = createNiceMock(Cluster.class);
+ cluster.setClusterName(clusterName);
+
+ ArrayList<Host> hosts = new ArrayList<Host>() {{
+ add(host1);
+ add(host2);
+ }};
+
+ Clusters clusters = createNiceMock(Clusters.class);
+ expect(clusters.getCluster(anyObject(String.class))).andReturn(cluster);
+
+ RepositoryVersionEntity repoVersion = new RepositoryVersionEntity();
+ repoVersion.setOperatingSystems(operatingSystemsJson);
+ StackEntity newDesiredStack = stackDAO.find("HDP", "2.0.1");
+ repoVersion.setStack(newDesiredStack);
+
+ final ServiceOsSpecific.Package hivePackage = new ServiceOsSpecific.Package();
+ hivePackage.setName("hive");
+ final ServiceOsSpecific.Package mysqlPackage = new ServiceOsSpecific.Package();
+ mysqlPackage.setName("mysql");
+ mysqlPackage.setSkipUpgrade(Boolean.TRUE);
+ List<ServiceOsSpecific.Package> packages = new ArrayList<ServiceOsSpecific.Package>() {{
+ add(hivePackage);
+ add(mysqlPackage);
+ }};
+
+ ActionManager actionManager = createNiceMock(ActionManager.class);
+
+ RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+ ResourceProviderFactory resourceProviderFactory = createNiceMock(ResourceProviderFactory.class);
+ ResourceProvider csvResourceProvider = createNiceMock(ClusterStackVersionResourceProvider.class);
+
+ AbstractControllerResourceProvider.init(resourceProviderFactory);
+
+ Map<String, Map<String, String>> hostConfigTags = new HashMap<String, Map<String, String>>();
+ expect(configHelper.getEffectiveDesiredTags(anyObject(ClusterImpl.class), anyObject(String.class))).andReturn(hostConfigTags);
+
+ expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+ expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
+ expect(managementController.getAuthName()).andReturn("admin").anyTimes();
+ expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
+ expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
+ expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+ (Map<String, String>) anyObject(List.class), anyObject(String.class))).andReturn(packages).anyTimes();
+
+ expect(resourceProviderFactory.getHostResourceProvider(anyObject(Set.class), anyObject(Map.class),
+ eq(managementController))).andReturn(csvResourceProvider).anyTimes();
+
+ expect(cluster.getCurrentStackVersion()).andReturn(stackId);
+ expect(cluster.getServiceComponentHosts(anyObject(String.class))).andReturn(schs).anyTimes();
+
+ RepositoryVersionEntity currentRepo = new RepositoryVersionEntity();
+ currentRepo.setVersion("2.2.2.0-2122");
+ ClusterVersionEntity current = new ClusterVersionEntity();
+ current.setRepositoryVersion(currentRepo);
+
+ Capture<StackId> capturedStackId = new Capture<StackId>();
+ cluster.setDesiredStackVersion(capture(capturedStackId));
+ expectLastCall().once();
+ expect(cluster.getHosts()).andReturn(hosts).anyTimes();
+ expect(cluster.getCurrentClusterVersion()).andReturn(current).anyTimes();
+
+ expect(sch.getServiceName()).andReturn("HIVE").anyTimes();
+
+ expect(repositoryVersionDAOMock.findByDisplayName(anyObject(String.class))).andReturn(repoVersion);
+
+ clusterVersionDAO.updateVersions((Long) anyObject(),
+ (RepositoryVersionEntity) anyObject(), (RepositoryVersionEntity) anyObject());
+ expectLastCall().once();
+
+ hostVersionDAO.updateVersions((RepositoryVersionEntity) anyObject(), (RepositoryVersionEntity) anyObject());
+ expectLastCall().once();
+
+ hostComponentStateDAO.updateVersions((String) anyObject());
+ expectLastCall().once();
+
+ // replay
+ replay(managementController, response, clusters, resourceProviderFactory, csvResourceProvider,
+ cluster, repositoryVersionDAOMock, configHelper, sch, actionManager, clusterVersionDAO,
+ hostVersionDAO, hostComponentStateDAO);
+
+ ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+ type,
+ PropertyHelper.getPropertyIds(type),
+ PropertyHelper.getKeyPropertyIds(type),
+ managementController);
+
+ injector.injectMembers(provider);
+
+
+ // add the property map to a set for the request. add more maps for multiple creates
+ Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+ // add properties to the request map
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_CLUSTER_NAME_PROPERTY_ID, clusterName);
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_STATE_PROPERTY_ID, "CURRENT");
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_REPOSITORY_VERSION_PROPERTY_ID, "HDP-2.2.2.0-2561");
+ properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_FORCE, "true");
+
+ // create the request
+ Request request = PropertyHelper.getUpdateRequest(properties, null);
+
+ provider.updateResources(request, null);
+
+ // verify
+ verify(managementController, response, clusterVersionDAO, hostVersionDAO, hostComponentStateDAO);
+ Assert.assertEquals(capturedStackId.getValue(),
+ new StackId(newDesiredStack.getStackName(), newDesiredStack.getStackVersion()));
+ }
+
public class MockModule extends AbstractModule {
@Override
@@ -489,6 +645,9 @@ public class ClusterStackVersionResourceProviderTest {
bind(Configuration.class).toInstance(configuration);
bind(StageFactory.class).toInstance(stageFactory);
bind(ClusterVersionDAO.class).toInstance(clusterVersionDAO);
+ bind(HostVersionDAO.class).toInstance(hostVersionDAO);
+ bind(HostComponentStateDAO.class).toInstance(hostComponentStateDAO);
+
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/81c608f4/ambari-server/src/test/python/TestServerUpgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestServerUpgrade.py b/ambari-server/src/test/python/TestServerUpgrade.py
index 7ef74b2..027830d 100644
--- a/ambari-server/src/test/python/TestServerUpgrade.py
+++ b/ambari-server/src/test/python/TestServerUpgrade.py
@@ -39,6 +39,7 @@ class TestServerUpgrade(TestCase):
options = MagicMock()
options.cluster_name = 'cc'
options.desired_repo_version = 'HDP-2.2.2.0-2561'
+ options.force_repo_version = None
# Case when server is not running
is_server_runing_mock.return_value = False, None
@@ -75,11 +76,63 @@ class TestServerUpgrade(TestCase):
self.assertTrue(urlopen_mock.called)
request = urlopen_mock.call_args_list[0][0][0]
self.assertEquals(request._Request__original, 'http://127.0.0.1:8080/api/v1/clusters/cc/stack_versions')
- self.assertEquals(request.data, '{"ClusterStackVersions": {"state": "CURRENT", "repository_version": "HDP-2.2.2.0-2561"}}')
+ self.assertEquals(request.data, '{"ClusterStackVersions": {"state": "CURRENT", "repository_version": "HDP-2.2.2.0-2561", "force": false}}')
self.assertEquals(request.origin_req_host, '127.0.0.1')
self.assertEquals(request.headers, {'X-requested-by': 'ambari', 'Authorization': 'Basic ZHVtbXlfc3RyaW5nOmR1bW15X3N0cmluZw=='})
+ @patch("ambari_server.serverUpgrade.is_server_runing")
+ @patch('ambari_server.serverUpgrade.SetCurrentVersionOptions.no_finalize_options_set')
+ @patch('ambari_server.serverUpgrade.get_validated_string_input')
+ @patch('ambari_server.serverUpgrade.get_ambari_properties')
+ @patch('ambari_server.serverUtils.get_ambari_server_api_base')
+ @patch('ambari_commons.logging_utils.get_verbose')
+ @patch('urllib2.urlopen')
+ def test_set_current_with_force(self, urlopen_mock, get_verbose_mock, get_ambari_server_api_base_mock,
+ get_ambari_properties_mock, get_validated_string_input_mock,
+ no_finalize_options_set_mock, is_server_runing_mock):
+ options = MagicMock()
+ options.cluster_name = 'cc'
+ options.desired_repo_version = 'HDP-2.2.2.0-2561'
+ options.force_repo_version = True
+ # Case when server is not running
+ is_server_runing_mock.return_value = False, None
+ try:
+ set_current(options)
+ self.fail("Server is not running - should error out")
+ except FatalException:
+ pass # expected
+
+
+ is_server_runing_mock.return_value = True, 11111
+
+ # Test insufficient options case
+ no_finalize_options_set_mock.return_value = True
+ try:
+ set_current(options)
+ self.fail("Should error out")
+ except FatalException:
+ pass # expected
+
+ no_finalize_options_set_mock.return_value = False
+
+ # Test normal flow
+ get_validated_string_input_mock.return_value = 'dummy_string'
+
+ p = get_ambari_properties_mock.return_value
+ p.get_property.side_effect = ["8080", "false"]
+
+ get_ambari_server_api_base_mock.return_value = 'http://127.0.0.1:8080/api/v1/'
+ get_verbose_mock.retun_value = False
+
+ set_current(options)
+
+ self.assertTrue(urlopen_mock.called)
+ request = urlopen_mock.call_args_list[0][0][0]
+ self.assertEquals(request._Request__original, 'http://127.0.0.1:8080/api/v1/clusters/cc/stack_versions')
+ self.assertEquals(request.data, '{"ClusterStackVersions": {"state": "CURRENT", "repository_version": "HDP-2.2.2.0-2561", "force": true}}')
+ self.assertEquals(request.origin_req_host, '127.0.0.1')
+ self.assertEquals(request.headers, {'X-requested-by': 'ambari', 'Authorization': 'Basic ZHVtbXlfc3RyaW5nOmR1bW15X3N0cmluZw=='})
def testCurrentVersionOptions(self):
# Negative test cases