Repository: ambari Updated Branches: refs/heads/trunk fdbe0939e -> 50cb77bb0
AMBARI-19473 - Add Downgrade request validation to avoid accidental double-upgrades (jonathanhurley) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/50cb77bb Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/50cb77bb Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/50cb77bb Branch: refs/heads/trunk Commit: 50cb77bb0b0e4b782107601497b083095fbd5221 Parents: fdbe093 Author: Jonathan Hurley <[email protected]> Authored: Wed Jan 11 16:26:39 2017 -0500 Committer: Jonathan Hurley <[email protected]> Committed: Thu Jan 12 11:34:31 2017 -0500 ---------------------------------------------------------------------- .../resources/UpgradeResourceDefinition.java | 4 +- .../internal/UpgradeResourceProvider.java | 52 ++++++------- .../server/state/cluster/ClusterImpl.java | 8 +- .../UpgradeResourceDefinitionTest.java | 7 +- .../UpgradeResourceProviderHDP22Test.java | 2 + .../internal/UpgradeResourceProviderTest.java | 78 +++++++++++++++++--- ambari-web/app/utils/ajax/ajax.js | 15 +--- 7 files changed, 105 insertions(+), 61 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinition.java index 64d8ee1..c44754a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinition.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinition.java @@ -28,7 +28,6 @@ import org.apache.ambari.server.controller.spi.Resource; */ public class UpgradeResourceDefinition extends SimpleResourceDefinition { - public static String DOWNGRADE_DIRECTIVE = "downgrade"; public static String SKIP_SERVICE_CHECKS_DIRECTIVE = "skip_service_checks"; /** @@ -39,6 +38,7 @@ public class UpgradeResourceDefinition extends SimpleResourceDefinition { "upgrade", "upgrades", Collections.singleton(Resource.Type.UpgradeGroup), - Collections.singletonMap(DirectiveType.CREATE, Arrays.asList(DOWNGRADE_DIRECTIVE, SKIP_SERVICE_CHECKS_DIRECTIVE))); + Collections.singletonMap(DirectiveType.CREATE, + Arrays.asList(SKIP_SERVICE_CHECKS_DIRECTIVE))); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java index 4c01964..6f8ebb7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java @@ -48,7 +48,6 @@ import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.Stage; import org.apache.ambari.server.actionmanager.StageFactory; import org.apache.ambari.server.agent.ExecutionCommand.KeyNames; -import org.apache.ambari.server.api.resources.UpgradeResourceDefinition; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.ActionExecutionContext; @@ -372,16 +371,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider "manage upgrade and downgrade"); } - final Map<String, String> requestInfoProps = request.getRequestInfoProperties(); - final String forceDowngrade = requestInfoProps.get(UpgradeResourceDefinition.DOWNGRADE_DIRECTIVE); - - final Direction direction = Boolean.parseBoolean(forceDowngrade) ? Direction.DOWNGRADE - : Direction.UPGRADE; - UpgradeEntity entity = createResources(new Command<UpgradeEntity>() { @Override public UpgradeEntity invoke() throws AmbariException, AuthorizationException { + final String directionProperty = (String) requestMap.get(UPGRADE_DIRECTION); + if (StringUtils.isEmpty(directionProperty)) { + throw new AmbariException(String.format("%s is required", UPGRADE_DIRECTION)); + } + + final Direction direction = Direction.valueOf(directionProperty); + // Default to ROLLING upgrade, but attempt to read from properties. UpgradeType upgradeType = UpgradeType.ROLLING; if (requestMap.containsKey(UPGRADE_TYPE)) { @@ -1760,9 +1760,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider // Remove relevant upgrade entity try { Cluster cluster = clusters.get().getClusterById(clusterId); - UpgradeEntity lastUpgradeItemForCluster = s_upgradeDAO.findLastUpgradeOrDowngradeForCluster(cluster.getClusterId()); - lastUpgradeItemForCluster.setSuspended(true); - s_upgradeDAO.merge(lastUpgradeItemForCluster); + UpgradeEntity upgradeEntity = s_upgradeDAO.findUpgradeByRequestId(requestId); + upgradeEntity.setSuspended(true); + s_upgradeDAO.merge(upgradeEntity); cluster.setUpgradeEntity(null); } catch (AmbariException e) { @@ -2002,14 +2002,19 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider String clusterName = (String) requestMap.get(UPGRADE_CLUSTER_NAME); String version = (String) requestMap.get(UPGRADE_VERSION); + String direction = (String) requestMap.get(UPGRADE_DIRECTION); - if (null == clusterName) { + if (StringUtils.isBlank(clusterName)) { throw new AmbariException(String.format("%s is required", UPGRADE_CLUSTER_NAME)); } - if (null == version) { + if (StringUtils.isBlank(version)) { throw new AmbariException(String.format("%s is required", UPGRADE_VERSION)); } + + if (StringUtils.isBlank(direction)) { + throw new AmbariException(String.format("%s is required", UPGRADE_DIRECTION)); + } } } @@ -2033,22 +2038,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider boolean failOnCheckWarnings = Boolean.parseBoolean((String) requestMap.get(UPGRADE_FAIL_ON_CHECK_WARNINGS)); String preferredUpgradePack = requestMap.containsKey(UPGRADE_PACK) ? (String) requestMap.get(UPGRADE_PACK) : null; - // Validate there isn't an direction == upgrade/downgrade already in progress. - List<UpgradeEntity> upgrades = s_upgradeDAO.findUpgrades(cluster.getClusterId()); - for (UpgradeEntity entity : upgrades) { - if (entity.getDirection() == direction) { - Map<Long, HostRoleCommandStatusSummaryDTO> summary = s_hostRoleCommandDAO.findAggregateCounts( - entity.getRequestId()); - CalculatedStatus calc = CalculatedStatus.statusFromStageSummary(summary, summary.keySet()); - HostRoleStatus status = calc.getStatus(); - if (!HostRoleStatus.getCompletedStates().contains(status)) { - throw new AmbariException( - String.format("Unable to perform %s as another %s is in progress. %s request %d is in %s", - direction.getText(false), direction.getText(false), direction.getText(true), - entity.getRequestId().longValue(), status) - ); - } - } + // verify that there is not an upgrade or downgrade that is in progress or suspended + UpgradeEntity existingUpgrade = cluster.getUpgradeInProgress(); + if( null != existingUpgrade ){ + throw new AmbariException( + String.format("Unable to perform %s as another %s (request ID %s) is in progress.", + direction.getText(false), direction.getText(false), + existingUpgrade.getRequestId().longValue())); } // skip this check if it's a downgrade or we are instructed to skip it http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java index 6455d6e..7b0b696 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java @@ -1023,12 +1023,10 @@ public class ClusterImpl implements Cluster { return mostRecentUpgrade; } - List<HostRoleStatus> UNFINISHED_STATUSES = new ArrayList<>(); - UNFINISHED_STATUSES.add(HostRoleStatus.PENDING); - UNFINISHED_STATUSES.add(HostRoleStatus.ABORTED); - + // look for any item from the prior upgrade which is still in progress + // (not failed, completed, or aborted) List<HostRoleCommandEntity> commands = hostRoleCommandDAO.findByRequestIdAndStatuses( - mostRecentUpgrade.getRequestId(), UNFINISHED_STATUSES); + mostRecentUpgrade.getRequestId(), HostRoleStatus.IN_PROGRESS_STATUSES); if (!commands.isEmpty()) { return mostRecentUpgrade; http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinitionTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinitionTest.java index 6a42115..f3e475c 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinitionTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UpgradeResourceDefinitionTest.java @@ -20,11 +20,11 @@ package org.apache.ambari.server.api.resources; import static org.junit.Assert.assertEquals; -import java.util.HashSet; - import org.apache.ambari.server.controller.spi.Resource; import org.junit.Test; +import com.google.common.collect.Sets; + /** * UpgradeResourceDefinition tests. */ @@ -52,8 +52,7 @@ public class UpgradeResourceDefinitionTest { public void testGetCreateDirectives() { ResourceDefinition resourceDefinition = new UpgradeResourceDefinition(); - assertEquals( - new HashSet<String>() {{add(UpgradeResourceDefinition.DOWNGRADE_DIRECTIVE); add(UpgradeResourceDefinition.SKIP_SERVICE_CHECKS_DIRECTIVE);}}, + assertEquals(Sets.newHashSet(UpgradeResourceDefinition.SKIP_SERVICE_CHECKS_DIRECTIVE), resourceDefinition.getCreateDirectives()); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java index 1747b28..e803529 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java @@ -74,6 +74,7 @@ import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceComponentHost; import org.apache.ambari.server.state.StackId; +import org.apache.ambari.server.state.stack.upgrade.Direction; import org.apache.ambari.server.topology.TopologyManager; import org.apache.ambari.server.utils.StageUtils; import org.apache.ambari.server.view.ViewRegistry; @@ -242,6 +243,7 @@ public class UpgradeResourceProviderHDP22Test { requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1"); requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.4.2"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java index 92e4a49..a702e6f 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java @@ -46,16 +46,17 @@ import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.HostRoleStatus; import org.apache.ambari.server.actionmanager.Stage; -import org.apache.ambari.server.api.resources.UpgradeResourceDefinition; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.audit.AuditLogger; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.AmbariServer; +import org.apache.ambari.server.controller.ResourceProviderFactory; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; import org.apache.ambari.server.controller.spi.RequestStatus; import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.Resource.Type; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.utilities.PredicateBuilder; @@ -145,6 +146,7 @@ public class UpgradeResourceProviderTest { private AmbariMetaInfo ambariMetaInfo; private TopologyManager topologyManager; private ConfigFactory configFactory; + private HostRoleCommandDAO hrcDAO; @Before public void before() throws Exception { @@ -185,6 +187,7 @@ public class UpgradeResourceProviderTest { upgradeDao = injector.getInstance(UpgradeDAO.class); requestDao = injector.getInstance(RequestDAO.class); repoVersionDao = injector.getInstance(RepositoryVersionDAO.class); + hrcDAO = injector.getInstance(HostRoleCommandDAO.class); AmbariEventPublisher publisher = createNiceMock(AmbariEventPublisher.class); replay(publisher); @@ -297,6 +300,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.TRUE.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_MANUAL_VERIFICATION, Boolean.FALSE.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, Boolean.TRUE.toString()); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); @@ -357,6 +361,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_TYPE, UpgradeType.ROLLING.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_MANUAL_VERIFICATION, Boolean.TRUE.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, Boolean.TRUE.toString()); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); @@ -402,6 +407,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.TRUE.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_MANUAL_VERIFICATION, Boolean.TRUE.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, Boolean.TRUE.toString()); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); @@ -554,6 +560,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); // tests skipping SC failure options requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, "true"); @@ -637,9 +644,9 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.DOWNGRADE.name()); Map<String, String> requestInfoProperties = new HashMap<String, String>(); - requestInfoProperties.put(UpgradeResourceDefinition.DOWNGRADE_DIRECTIVE, "true"); ResourceProvider upgradeResourceProvider = createProvider(amc); @@ -671,6 +678,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); @@ -680,6 +688,12 @@ public class UpgradeResourceProviderTest { List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId()); assertEquals(1, upgrades.size()); + UpgradeEntity upgrade = upgrades.get(0); + + // now abort the upgrade so another can be created + abortUpgrade(upgrade.getRequestId()); + + // create another upgrade which should fail requestProps = new HashMap<>(); requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1"); requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2"); @@ -693,14 +707,15 @@ public class UpgradeResourceProviderTest { // !!! expected } + // fix the properties and try again requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1"); requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); requestProps.put(UpgradeResourceProvider.UPGRADE_FROM_VERSION, "2.1.1.0"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.DOWNGRADE.name()); Map<String, String> requestInfoProperties = new HashMap<>(); - requestInfoProperties.put(UpgradeResourceDefinition.DOWNGRADE_DIRECTIVE, "true"); request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties); RequestStatus status = upgradeResourceProvider.createResources(request); @@ -750,6 +765,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_nonrolling_new_stack"); requestProps.put(UpgradeResourceProvider.UPGRADE_TYPE, "NON_ROLLING"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); @@ -760,7 +776,8 @@ public class UpgradeResourceProviderTest { List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId()); assertEquals(1, upgrades.size()); - List<UpgradeGroupEntity> groups = upgrades.get(0).getUpgradeGroups(); + UpgradeEntity upgrade = upgrades.get(0); + List<UpgradeGroupEntity> groups = upgrade.getUpgradeGroups(); boolean isHiveGroupFound = false; boolean isZKGroupFound = false; @@ -780,6 +797,9 @@ public class UpgradeResourceProviderTest { isZKGroupFound = false; sch.setVersion("2.2.0.0"); + // now abort the upgrade so another can be created + abortUpgrade(upgrade.getRequestId()); + // create downgrade with one upgraded service StackId stackId = new StackId("HDP", "2.2.0"); cluster.setDesiredStackVersion(stackId, true); @@ -789,9 +809,9 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_nonrolling_new_stack"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); requestProps.put(UpgradeResourceProvider.UPGRADE_FROM_VERSION, "2.2.0.0"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.DOWNGRADE.name()); Map<String, String> requestInfoProperties = new HashMap<>(); - requestInfoProperties.put(UpgradeResourceDefinition.DOWNGRADE_DIRECTIVE, "true"); request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties); RequestStatus status = upgradeResourceProvider.createResources(request); @@ -929,6 +949,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.2.3"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_direction"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); @@ -949,6 +970,8 @@ public class UpgradeResourceProviderTest { Assert.assertFalse(item.getText().toLowerCase().contains("downgrade")); } + // now abort the upgrade so another can be created + abortUpgrade(upgrade.getRequestId()); requestProps.clear(); // Now perform a downgrade @@ -957,11 +980,9 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_direction"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); requestProps.put(UpgradeResourceProvider.UPGRADE_FROM_VERSION, "2.2.2.3"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.DOWNGRADE.name()); - Map<String, String> requestInfoProps = new HashMap<String, String>(); - requestInfoProps.put("downgrade", "true"); - - request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProps); + request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); upgradeResourceProvider.createResources(request); upgrades = upgradeDao.findUpgrades(cluster.getClusterId()); @@ -1056,6 +1077,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); @@ -1209,7 +1231,13 @@ public class UpgradeResourceProviderTest { * @return the provider */ private UpgradeResourceProvider createProvider(AmbariManagementController amc) { - return new UpgradeResourceProvider(amc); + ResourceProviderFactory factory = injector.getInstance(ResourceProviderFactory.class); + AbstractControllerResourceProvider.init(factory); + + Resource.Type type = Type.Upgrade; + return (UpgradeResourceProvider) AbstractControllerResourceProvider.getResourceProvider(type, + PropertyHelper.getPropertyIds(type), PropertyHelper.getKeyPropertyIds(type), + amc); } private RequestStatus testCreateResources() throws Exception { @@ -1224,6 +1252,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1"); requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test"); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true"); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); @@ -1405,11 +1434,12 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_TYPE, UpgradeType.ROLLING.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_MANUAL_VERIFICATION, Boolean.FALSE.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, Boolean.TRUE.toString()); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); // this will cause a NPE when creating the upgrade, allowing us to test // rollback UpgradeResourceProvider upgradeResourceProvider = createProvider(amc); - upgradeResourceProvider.s_upgradeDAO = null; + UpgradeResourceProvider.s_upgradeDAO = null; try { Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); @@ -1442,6 +1472,7 @@ public class UpgradeResourceProviderTest { requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test_host_ordered"); requestProps.put(UpgradeResourceProvider.UPGRADE_TYPE, UpgradeType.HOST_ORDERED.toString()); requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, Boolean.TRUE.toString()); + requestProps.put(UpgradeResourceProvider.UPGRADE_DIRECTION, Direction.UPGRADE.name()); ResourceProvider upgradeResourceProvider = createProvider(amc); Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); @@ -1488,6 +1519,31 @@ public class UpgradeResourceProviderTest { } /** + * Aborts and upgrade. + * + * @param requestId + * @throws Exception + */ + private void abortUpgrade(long requestId) throws Exception { + // now abort the upgrade so another can be created + Map<String, Object> requestProps = new HashMap<>(); + requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, String.valueOf(requestId)); + requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1"); + requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_STATUS, "ABORTED"); + requestProps.put(UpgradeResourceProvider.UPGRADE_SUSPENDED, "false"); + Request request = PropertyHelper.getUpdateRequest(requestProps, null); + + ResourceProvider upgradeResourceProvider = createProvider(amc); + upgradeResourceProvider.updateResources(request, null); + + // !!! this is required since the ActionManager/ActionScheduler isn't + // running and can't remove queued PENDING - it's a cheap way of ensuring + // that the upgrade commands do get aborted + hrcDAO.updateStatusByRequestId(requestId, HostRoleStatus.ABORTED, + HostRoleStatus.IN_PROGRESS_STATUSES); + } + + /** * */ private class MockModule implements Module { http://git-wip-us.apache.org/repos/asf/ambari/blob/50cb77bb/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index d4b1474..e344128 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -1722,7 +1722,8 @@ var urls = { "repository_version": data.value, "upgrade_type": data.type, "skip_failures": data.skipComponentFailures, - "skip_service_check_failures": data.skipSCFailures + "skip_service_check_failures": data.skipSCFailures, + "direction": "UPGRADE" } }) } @@ -1735,13 +1736,11 @@ var urls = { 'format': function (data) { return { data: JSON.stringify({ - "RequestInfo": { - "downgrade": "true" - }, "Upgrade": { "from_version": data.from, "repository_version": data.value, - "upgrade_type": data.upgradeType + "upgrade_type": data.upgradeType, + "direction": "DOWNGRADE" } }) } @@ -1754,9 +1753,6 @@ var urls = { 'format': function (data) { return { data: JSON.stringify({ - "RequestInfo": { - "downgrade": data.isDowngrade - }, "Upgrade": { "request_status": "ABORTED", "suspended": "false" @@ -1772,9 +1768,6 @@ var urls = { 'format': function (data) { return { data: JSON.stringify({ - "RequestInfo": { - "downgrade": data.isDowngrade - }, "Upgrade": { "request_status": "ABORTED", "suspended": "true"
