/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ambari.server.controller.internal;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.H2DatabaseCleaner;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
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.agent.ExecutionCommand.KeyNames;
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;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
import org.apache.ambari.server.orm.dao.RequestDAO;
import org.apache.ambari.server.orm.dao.StackDAO;
import org.apache.ambari.server.orm.dao.StageDAO;
import org.apache.ambari.server.orm.dao.UpgradeDAO;
import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.RequestEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.orm.entities.StageEntity;
import org.apache.ambari.server.orm.entities.UpgradeEntity;
import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
import org.apache.ambari.server.security.TestAuthenticationFactory;
import org.apache.ambari.server.serveraction.upgrades.AutoSkipFailedSummaryAction;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigFactory;
import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.RepositoryVersionState;
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.UpgradeHelper;
import org.apache.ambari.server.state.UpgradeState;
import org.apache.ambari.server.state.stack.UpgradePack;
import org.apache.ambari.server.state.stack.upgrade.Direction;
import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
import org.apache.ambari.server.topology.TopologyManager;
import org.apache.ambari.server.utils.StageUtils;
import org.apache.ambari.server.view.ViewRegistry;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.core.context.SecurityContextHolder;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.util.Modules;
/**
* UpgradeResourceDefinition tests.
*/
public class UpgradeResourceProviderTest {
private UpgradeDAO upgradeDao = null;
private RequestDAO requestDao = null;
private RepositoryVersionDAO repoVersionDao = null;
private Injector injector;
private Clusters clusters;
private OrmTestHelper helper;
private AmbariManagementController amc;
private ConfigHelper configHelper;
private StackDAO stackDAO;
private AmbariMetaInfo ambariMetaInfo;
private TopologyManager topologyManager;
private ConfigFactory configFactory;
private HostRoleCommandDAO hrcDAO;
@Before
public void before() throws Exception {
SecurityContextHolder.getContext().setAuthentication(
TestAuthenticationFactory.createAdministrator());
// setup the config helper for placeholder resolution
configHelper = EasyMock.createNiceMock(ConfigHelper.class);
expect(
configHelper.getPlaceholderValueFromDesiredConfigurations(
EasyMock.anyObject(Cluster.class), EasyMock.eq("{{foo/bar}}"))).andReturn(
"placeholder-rendered-properly").anyTimes();
expect(
configHelper.getDefaultProperties(EasyMock.anyObject(StackId.class),
EasyMock.anyObject(Cluster.class), EasyMock.anyBoolean())).andReturn(
new HashMap<String, Map<String, String>>()).anyTimes();
EasyMock.replay(configHelper);
InMemoryDefaultTestModule module = new InMemoryDefaultTestModule();
// create an injector which will inject the mocks
injector = Guice.createInjector(Modules.override(module).with(new MockModule()));
H2DatabaseCleaner.resetSequences(injector);
injector.getInstance(GuiceJpaInitializer.class);
helper = injector.getInstance(OrmTestHelper.class);
amc = injector.getInstance(AmbariManagementController.class);
ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
configFactory = injector.getInstance(ConfigFactory.class);
Field field = AmbariServer.class.getDeclaredField("clusterController");
field.setAccessible(true);
field.set(null, amc);
stackDAO = injector.getInstance(StackDAO.class);
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);
ViewRegistry.initInstance(new ViewRegistry(publisher));
// TODO AMARI-12698, this file is attempting to check RU on version 2.1.1, which doesn't support it
// because it has no upgrade packs. We should use correct versions that have stacks.
// For now, Ignore the tests that fail.
StackEntity stackEntity211 = stackDAO.find("HDP", "2.1.1");
StackEntity stackEntity220 = stackDAO.find("HDP", "2.2.0");
StackId stack211 = new StackId("HDP-2.1.1");
StackId stack220 = new StackId("HDP-2.2.0");
RepositoryVersionEntity repoVersionEntity = new RepositoryVersionEntity();
repoVersionEntity.setDisplayName("My New Version 1");
repoVersionEntity.setOperatingSystems("");
repoVersionEntity.setStack(stackEntity211);
repoVersionEntity.setVersion("2.1.1.0");
repoVersionDao.create(repoVersionEntity);
repoVersionEntity = new RepositoryVersionEntity();
repoVersionEntity.setDisplayName("My New Version 2 for patch upgrade");
repoVersionEntity.setOperatingSystems("");
repoVersionEntity.setStack(stackEntity211);
repoVersionEntity.setVersion("2.1.1.1");
repoVersionDao.create(repoVersionEntity);
repoVersionEntity = new RepositoryVersionEntity();
repoVersionEntity.setDisplayName("My New Version 3 for major upgrade");
repoVersionEntity.setOperatingSystems("");
repoVersionEntity.setStack(stackEntity220);
repoVersionEntity.setVersion("2.2.0.0");
repoVersionDao.create(repoVersionEntity);
clusters = injector.getInstance(Clusters.class);
clusters.addCluster("c1", stack211);
Cluster cluster = clusters.getCluster("c1");
helper.getOrCreateRepositoryVersion(stack211, stack211.getStackVersion());
helper.getOrCreateRepositoryVersion(stack220, stack220.getStackVersion());
cluster.createClusterVersion(stack211, stack211.getStackVersion(), "admin", RepositoryVersionState.INSTALLING);
cluster.transitionClusterVersion(stack211, stack211.getStackVersion(), RepositoryVersionState.CURRENT);
clusters.addHost("h1");
Host host = clusters.getHost("h1");
Map<String, String> hostAttributes = new HashMap<>();
hostAttributes.put("os_family", "redhat");
hostAttributes.put("os_release_version", "6.3");
host.setHostAttributes(hostAttributes);
host.setState(HostState.HEALTHY);
clusters.mapHostToCluster("h1", "c1");
// add a single ZK server
Service service = cluster.addService("ZOOKEEPER");
service.setDesiredStackVersion(cluster.getDesiredStackVersion());
ServiceComponent component = service.addServiceComponent("ZOOKEEPER_SERVER");
ServiceComponentHost sch = component.addServiceComponentHost("h1");
sch.setVersion("2.1.1.0");
component = service.addServiceComponent("ZOOKEEPER_CLIENT");
sch = component.addServiceComponentHost("h1");
sch.setVersion("2.1.1.0");
Configuration configuration = injector.getInstance(Configuration.class);
configuration.setProperty("upgrade.parameter.zk-server.timeout", "824");
topologyManager = injector.getInstance(TopologyManager.class);
StageUtils.setTopologyManager(topologyManager);
StageUtils.setConfiguration(configuration);
ActionManager.setTopologyManager(topologyManager);
EasyMock.replay(injector.getInstance(AuditLogger.class));
}
@After
public void after() throws AmbariException, SQLException {
H2DatabaseCleaner.clearDatabaseAndStopPersistenceService(injector);
EasyMock.reset(injector.getInstance(AuditLogger.class));
injector = null;
}
/**
* Obtain request id from the {@code RequestStatus}
* @param requestStatus reqult of the {@code createResources}
* @return id of the request
*/
private long getRequestId(RequestStatus requestStatus){
assertEquals(1, requestStatus.getAssociatedResources().size());
Resource r = requestStatus.getAssociatedResources().iterator().next();
String id = r.getPropertyValue("Upgrade/request_id").toString();
return Long.parseLong(id);
}
@Test
public void testCreateResourcesWithAutoSkipFailures() throws Exception {
Cluster cluster = clusters.getCluster("c1");
Map<String, Object> requestProps = new HashMap<>();
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_TYPE, UpgradeType.ROLLING.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.TRUE.toString());
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);
upgradeResourceProvider.createResources(request);
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity entity = upgrades.get(0);
assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
assertEquals(3, upgradeGroups.size());
UpgradeGroupEntity preClusterGroup = upgradeGroups.get(0);
assertEquals("PRE_CLUSTER", preClusterGroup.getName());
List<UpgradeItemEntity> preClusterUpgradeItems = preClusterGroup.getItems();
assertEquals(2, preClusterUpgradeItems.size());
assertEquals("Foo", parseSingleMessage(preClusterUpgradeItems.get(0).getText()));
assertEquals("Foo", parseSingleMessage(preClusterUpgradeItems.get(1).getText()));
UpgradeGroupEntity zookeeperGroup = upgradeGroups.get(1);
assertEquals("ZOOKEEPER", zookeeperGroup.getName());
List<UpgradeItemEntity> zookeeperUpgradeItems = zookeeperGroup.getItems();
assertEquals(5, zookeeperUpgradeItems.size());
assertEquals("This is a manual task with a placeholder of placeholder-rendered-properly",
parseSingleMessage(zookeeperUpgradeItems.get(0).getText()));
assertEquals("Restarting ZooKeeper Server on h1", zookeeperUpgradeItems.get(1).getText());
assertEquals("Updating configuration zookeeper-newconfig",
zookeeperUpgradeItems.get(2).getText());
assertEquals("Service Check ZooKeeper", zookeeperUpgradeItems.get(3).getText());
assertTrue(zookeeperUpgradeItems.get(4).getText().contains("There are failures that were automatically skipped"));
// the last upgrade item is the skipped failure check
UpgradeItemEntity skippedFailureCheck = zookeeperUpgradeItems.get(zookeeperUpgradeItems.size() - 1);
skippedFailureCheck.getTasks().contains(AutoSkipFailedSummaryAction.class.getName());
UpgradeGroupEntity postClusterGroup = upgradeGroups.get(2);
assertEquals("POST_CLUSTER", postClusterGroup.getName());
List<UpgradeItemEntity> postClusterUpgradeItems = postClusterGroup.getItems();
assertEquals(2, postClusterUpgradeItems.size());
assertEquals("Please confirm you are ready to finalize", parseSingleMessage(postClusterUpgradeItems.get(0).getText()));
assertEquals("Save Cluster State", postClusterUpgradeItems.get(1).getText());
}
@Test
public void testCreateResourcesWithAutoSkipManualVerification() throws Exception {
Cluster cluster = clusters.getCluster("c1");
Map<String, Object> requestProps = new HashMap<>();
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_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);
upgradeResourceProvider.createResources(request);
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity entity = upgrades.get(0);
assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
assertEquals(2, upgradeGroups.size());
UpgradeGroupEntity zookeeperGroup = upgradeGroups.get(0);
assertEquals("ZOOKEEPER", zookeeperGroup.getName());
List<UpgradeItemEntity> zookeeperUpgradeItems = zookeeperGroup.getItems();
assertEquals(3, zookeeperUpgradeItems.size());
assertEquals("Restarting ZooKeeper Server on h1", zookeeperUpgradeItems.get(0).getText());
assertEquals("Updating configuration zookeeper-newconfig",
zookeeperUpgradeItems.get(1).getText());
assertEquals("Service Check ZooKeeper", zookeeperUpgradeItems.get(2).getText());
UpgradeGroupEntity postClusterGroup = upgradeGroups.get(1);
assertEquals("POST_CLUSTER", postClusterGroup.getName());
List<UpgradeItemEntity> postClusterUpgradeItems = postClusterGroup.getItems();
assertEquals(1, postClusterUpgradeItems.size());
assertEquals("Save Cluster State", postClusterUpgradeItems.get(0).getText());
}
@Test
public void testCreateResourcesWithAutoSkipAll() throws Exception {
Cluster cluster = clusters.getCluster("c1");
Map<String, Object> requestProps = new HashMap<>();
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_TYPE, UpgradeType.ROLLING.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.TRUE.toString());
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);
upgradeResourceProvider.createResources(request);
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity entity = upgrades.get(0);
assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
assertEquals(2, upgradeGroups.size());
UpgradeGroupEntity zookeeperGroup = upgradeGroups.get(0);
assertEquals("ZOOKEEPER", zookeeperGroup.getName());
List<UpgradeItemEntity> zookeeperUpgradeItems = zookeeperGroup.getItems();
assertEquals(4, zookeeperUpgradeItems.size());
assertEquals("Restarting ZooKeeper Server on h1", zookeeperUpgradeItems.get(0).getText());
assertEquals("Updating configuration zookeeper-newconfig",
zookeeperUpgradeItems.get(1).getText());
assertEquals("Service Check ZooKeeper", zookeeperUpgradeItems.get(2).getText());
assertTrue(zookeeperUpgradeItems.get(3).getText().contains("There are failures that were automatically skipped"));
// the last upgrade item is the skipped failure check
UpgradeItemEntity skippedFailureCheck = zookeeperUpgradeItems.get(zookeeperUpgradeItems.size() - 1);
skippedFailureCheck.getTasks().contains(AutoSkipFailedSummaryAction.class.getName());
UpgradeGroupEntity postClusterGroup = upgradeGroups.get(1);
assertEquals("POST_CLUSTER", postClusterGroup.getName());
List<UpgradeItemEntity> postClusterUpgradeItems = postClusterGroup.getItems();
assertEquals(1, postClusterUpgradeItems.size());
assertEquals("Save Cluster State", postClusterUpgradeItems.get(0).getText());
}
@Test
public void testGetResources() throws Exception {
RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
Resource res = createdResources.iterator().next();
Long id = (Long) res.getPropertyValue("Upgrade/request_id");
assertNotNull(id);
assertEquals(Long.valueOf(1), id);
// upgrade
Set<String> propertyIds = new HashSet<>();
propertyIds.add("Upgrade");
Predicate predicate = new PredicateBuilder()
.property(UpgradeResourceProvider.UPGRADE_REQUEST_ID).equals("1").and()
.property(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME).equals("c1")
.toPredicate();
Request request = PropertyHelper.getReadRequest(propertyIds);
ResourceProvider upgradeResourceProvider = createProvider(amc);
Set<Resource> resources = upgradeResourceProvider.getResources(request, predicate);
assertEquals(1, resources.size());
res = resources.iterator().next();
assertNotNull(res.getPropertyValue("Upgrade/progress_percent"));
assertNotNull(res.getPropertyValue(UpgradeResourceProvider.UPGRADE_DIRECTION));
assertEquals(Direction.UPGRADE, res.getPropertyValue(UpgradeResourceProvider.UPGRADE_DIRECTION));
assertEquals(false, res.getPropertyValue(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES));
assertEquals(false, res.getPropertyValue(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES));
assertEquals(UpgradeType.ROLLING, res.getPropertyValue(UpgradeResourceProvider.UPGRADE_TYPE));
// upgrade groups
propertyIds.clear();
propertyIds.add("UpgradeGroup");
predicate = new PredicateBuilder()
.property(UpgradeGroupResourceProvider.UPGRADE_REQUEST_ID).equals("1").and()
.property(UpgradeGroupResourceProvider.UPGRADE_CLUSTER_NAME).equals("c1")
.toPredicate();
request = PropertyHelper.getReadRequest(propertyIds);
ResourceProvider upgradeGroupResourceProvider = new UpgradeGroupResourceProvider(amc);
resources = upgradeGroupResourceProvider.getResources(request, predicate);
assertEquals(3, resources.size());
res = resources.iterator().next();
assertNotNull(res.getPropertyValue("UpgradeGroup/status"));
assertNotNull(res.getPropertyValue("UpgradeGroup/group_id"));
assertNotNull(res.getPropertyValue("UpgradeGroup/total_task_count"));
assertNotNull(res.getPropertyValue("UpgradeGroup/in_progress_task_count"));
assertNotNull(res.getPropertyValue("UpgradeGroup/completed_task_count"));
// upgrade items
propertyIds.clear();
propertyIds.add("UpgradeItem");
predicate = new PredicateBuilder()
.property(UpgradeItemResourceProvider.UPGRADE_GROUP_ID).equals("1").and()
.property(UpgradeItemResourceProvider.UPGRADE_REQUEST_ID).equals("1").and()
.property(UpgradeItemResourceProvider.UPGRADE_CLUSTER_NAME).equals("c1")
.toPredicate();
request = PropertyHelper.getReadRequest(propertyIds);
ResourceProvider upgradeItemResourceProvider = new UpgradeItemResourceProvider(amc);
resources = upgradeItemResourceProvider.getResources(request, predicate);
assertEquals(2, resources.size());
res = resources.iterator().next();
assertNotNull(res.getPropertyValue("UpgradeItem/status"));
// !!! check for manual stage vs item text
propertyIds.clear();
propertyIds.add("UpgradeItem");
predicate = new PredicateBuilder()
.property(UpgradeItemResourceProvider.UPGRADE_GROUP_ID).equals("3").and()
.property(UpgradeItemResourceProvider.UPGRADE_REQUEST_ID).equals("1").and()
.property(UpgradeItemResourceProvider.UPGRADE_CLUSTER_NAME).equals("c1")
.toPredicate();
request = PropertyHelper.getReadRequest(propertyIds);
upgradeItemResourceProvider = new UpgradeItemResourceProvider(amc);
resources = upgradeItemResourceProvider.getResources(request, predicate);
assertEquals(2, resources.size());
res = resources.iterator().next();
assertEquals("Confirm Finalize", res.getPropertyValue("UpgradeItem/context"));
String msgStr = res.getPropertyValue("UpgradeItem/text").toString();
JsonParser parser = new JsonParser();
JsonArray msgArray = (JsonArray) parser.parse(msgStr);
JsonObject msg = (JsonObject) msgArray.get(0);
assertTrue(msg.get("message").getAsString().startsWith("Please confirm"));
}
/**
* Tests that retrieving an upgrade correctly populates less common upgrade
* options correctly.
*/
@Test
public void testGetResourcesWithSpecialOptions() throws Exception {
Cluster cluster = clusters.getCluster("c1");
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(0, upgrades.size());
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
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");
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, "true");
ResourceProvider upgradeResourceProvider = createProvider(amc);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
RequestStatus status = upgradeResourceProvider.createResources(request);
assertNotNull(status);
// upgrade
Set<String> propertyIds = new HashSet<>();
propertyIds.add("Upgrade");
Predicate predicate = new PredicateBuilder()
.property(UpgradeResourceProvider.UPGRADE_REQUEST_ID).equals("1").and()
.property(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME).equals("c1")
.toPredicate();
request = PropertyHelper.getReadRequest(propertyIds);
Set<Resource> resources = upgradeResourceProvider.getResources(request, predicate);
assertEquals(1, resources.size());
Resource resource = resources.iterator().next();
assertEquals(true, resource.getPropertyValue(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES));
assertEquals(true, resource.getPropertyValue(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES));
}
@Test
public void testCreatePartialDowngrade() throws Exception {
clusters.addHost("h2");
Host host = clusters.getHost("h2");
Map<String, String> hostAttributes = new HashMap<>();
hostAttributes.put("os_family", "redhat");
hostAttributes.put("os_release_version", "6.3");
host.setHostAttributes(hostAttributes);
clusters.mapHostToCluster("h2", "c1");
Cluster cluster = clusters.getCluster("c1");
Service service = cluster.getService("ZOOKEEPER");
// this should get skipped
ServiceComponent component = service.getServiceComponent("ZOOKEEPER_SERVER");
ServiceComponentHost sch = component.addServiceComponentHost("h2");
sch.setVersion("2.2.2.2");
// start out with 0 (sanity check)
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(0, upgrades.size());
// a downgrade MUST have an upgrade to come from, so populate an upgrade in
// the DB
RequestEntity requestEntity = new RequestEntity();
requestEntity.setRequestId(2L);
requestEntity.setClusterId(cluster.getClusterId());
requestEntity.setStages(new ArrayList<StageEntity>());
requestDao.create(requestEntity);
UpgradeEntity upgradeEntity = new UpgradeEntity();
upgradeEntity.setClusterId(cluster.getClusterId());
upgradeEntity.setDirection(Direction.UPGRADE);
upgradeEntity.setFromVersion("2.1.1.1");
upgradeEntity.setToVersion("2.2.2.2");
upgradeEntity.setUpgradePackage("upgrade_test");
upgradeEntity.setUpgradeType(UpgradeType.ROLLING);
upgradeEntity.setRequestEntity(requestEntity);
upgradeDao.create(upgradeEntity);
upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity lastUpgrade = upgradeDao.findLastUpgradeForCluster(cluster.getClusterId(), Direction.UPGRADE);
assertNotNull(lastUpgrade);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
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<>();
ResourceProvider upgradeResourceProvider = createProvider(amc);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties);
upgradeResourceProvider.createResources(request);
upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(2, upgrades.size());
UpgradeEntity downgrade = upgrades.get(1);
assertEquals(cluster.getClusterId(), downgrade.getClusterId().longValue());
List<UpgradeGroupEntity> upgradeGroups = downgrade.getUpgradeGroups();
assertEquals(3, upgradeGroups.size());
UpgradeGroupEntity group = upgradeGroups.get(1);
assertEquals("ZOOKEEPER", group.getName());
assertEquals(4, group.getItems().size());
}
@Test
public void testDowngradeToBase() throws Exception {
Cluster cluster = clusters.getCluster("c1");
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
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);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
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");
requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test");
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true");
request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
try {
upgradeResourceProvider.createResources(request);
Assert.fail("Expected an exception going downgrade with no upgrade pack");
} catch (Exception e) {
// !!! 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<>();
request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties);
RequestStatus status = upgradeResourceProvider.createResources(request);
assertEquals(1, status.getAssociatedResources().size());
Resource r = status.getAssociatedResources().iterator().next();
String id = r.getPropertyValue("Upgrade/request_id").toString();
UpgradeEntity entity = upgradeDao.findUpgrade(Long.parseLong(id));
assertNotNull(entity);
assertEquals("2.1.1.0", entity.getFromVersion());
assertEquals("2.2.0.0", entity.getToVersion());
assertEquals(Direction.DOWNGRADE, entity.getDirection());
StageDAO dao = injector.getInstance(StageDAO.class);
List<StageEntity> stages = dao.findByRequestId(entity.getRequestId());
Gson gson = new Gson();
for (StageEntity se : stages) {
Map<String, String> map = gson.<Map<String, String>>fromJson(se.getCommandParamsStage(), Map.class);
assertTrue(map.containsKey("upgrade_direction"));
assertEquals("downgrade", map.get("upgrade_direction"));
}
}
/**
* Test Downgrade from the partially completed upgrade
*/
@Test
public void testNotFullDowngrade() throws Exception {
Cluster cluster = clusters.getCluster("c1");
// add additional service for the test
Service service = cluster.addService("HIVE");
service.setDesiredStackVersion(cluster.getDesiredStackVersion());
ServiceComponent component = service.addServiceComponent("HIVE_SERVER");
ServiceComponentHost sch = component.addServiceComponentHost("h1");
sch.setVersion("2.1.1.0");
// create upgrade request
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
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);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
// check that upgrade was created and groups for the tested services are on place
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity upgrade = upgrades.get(0);
List<UpgradeGroupEntity> groups = upgrade.getUpgradeGroups();
boolean isHiveGroupFound = false;
boolean isZKGroupFound = false;
// look only for testing groups
for (UpgradeGroupEntity group: groups) {
if (group.getName().equalsIgnoreCase("hive")) {
isHiveGroupFound = true;
} else if (group.getName().equalsIgnoreCase("zookeeper")){
isZKGroupFound = true;
}
}
assertTrue(isHiveGroupFound);
assertTrue(isZKGroupFound);
isHiveGroupFound = false;
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);
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.0");
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<>();
request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties);
RequestStatus status = upgradeResourceProvider.createResources(request);
UpgradeEntity upgradeEntity = upgradeDao.findUpgradeByRequestId(getRequestId(status));
for (UpgradeGroupEntity group: upgradeEntity.getUpgradeGroups()) {
if (group.getName().equalsIgnoreCase("hive")) {
isHiveGroupFound = true;
} else if (group.getName().equalsIgnoreCase("zookeeper")){
isZKGroupFound = true;
}
}
// as services not updated, nothing to downgrade
assertTrue(isHiveGroupFound);
assertFalse(isZKGroupFound);
}
@Test
public void testAbort() throws Exception {
RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
Resource res = createdResources.iterator().next();
Long id = (Long) res.getPropertyValue("Upgrade/request_id");
assertNotNull(id);
assertEquals(Long.valueOf(1), id);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, id.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_STATUS, "ABORTED");
requestProps.put(UpgradeResourceProvider.UPGRADE_SUSPENDED, "true");
UpgradeResourceProvider urp = createProvider(amc);
// !!! make sure we can. actual abort is tested elsewhere
Request req = PropertyHelper.getUpdateRequest(requestProps, null);
urp.updateResources(req, null);
}
@Test
public void testRetry() throws Exception {
RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
Resource res = createdResources.iterator().next();
Long id = (Long) res.getPropertyValue("Upgrade/request_id");
assertNotNull(id);
assertEquals(Long.valueOf(1), id);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, id.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_STATUS, "ABORTED");
requestProps.put(UpgradeResourceProvider.UPGRADE_SUSPENDED, "true");
UpgradeResourceProvider urp = createProvider(amc);
// !!! make sure we can. actual abort is tested elsewhere
Request req = PropertyHelper.getUpdateRequest(requestProps, null);
urp.updateResources(req, null);
ActionManager am = injector.getInstance(ActionManager.class);
List<HostRoleCommand> commands = am.getRequestTasks(id);
boolean foundOne = false;
for (HostRoleCommand hrc : commands) {
if (hrc.getRole().equals(Role.AMBARI_SERVER_ACTION)) {
assertEquals(-1L, hrc.getHostId());
assertNull(hrc.getHostName());
foundOne = true;
}
}
assertTrue("Expected at least one server-side action", foundOne);
HostRoleCommand cmd = commands.get(commands.size()-1);
HostRoleCommandDAO dao = injector.getInstance(HostRoleCommandDAO.class);
HostRoleCommandEntity entity = dao.findByPK(cmd.getTaskId());
entity.setStatus(HostRoleStatus.ABORTED);
dao.merge(entity);
requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, id.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_STATUS, "PENDING");
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_SUSPENDED, "false");
// !!! make sure we can. actual reset is tested elsewhere
req = PropertyHelper.getUpdateRequest(requestProps, null);
urp.updateResources(req, null);
}
@Test(expected = IllegalArgumentException.class)
public void testAbortWithoutSuspendFlag() throws Exception {
RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
Resource res = createdResources.iterator().next();
Long id = (Long) res.getPropertyValue("Upgrade/request_id");
assertNotNull(id);
assertEquals(Long.valueOf(1), id);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, id.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_STATUS, "ABORTED");
UpgradeResourceProvider urp = createProvider(amc);
Request req = PropertyHelper.getUpdateRequest(requestProps, null);
urp.updateResources(req, null);
}
@Test
public void testDirectionUpgrade() throws Exception {
Cluster cluster = clusters.getCluster("c1");
StackEntity stackEntity = stackDAO.find("HDP", "2.1.1");
RepositoryVersionEntity repoVersionEntity = new RepositoryVersionEntity();
repoVersionEntity.setDisplayName("My New Version 3");
repoVersionEntity.setOperatingSystems("");
repoVersionEntity.setStack(stackEntity);
repoVersionEntity.setVersion("2.2.2.3");
repoVersionDao.create(repoVersionEntity);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
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);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity upgrade = upgrades.get(0);
Long id = upgrade.getRequestId();
assertEquals(3, upgrade.getUpgradeGroups().size());
// Ensure that there are no items related to downgrade in the upgrade direction
UpgradeGroupEntity group = upgrade.getUpgradeGroups().get(2);
Assert.assertEquals("POST_CLUSTER", group.getName());
Assert.assertTrue(!group.getItems().isEmpty());
for (UpgradeItemEntity item : group.getItems()) {
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
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2");
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());
request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(2, upgrades.size());
upgrade = null;
for (UpgradeEntity u : upgrades) {
if (!u.getRequestId().equals(id)) {
upgrade = u;
}
}
assertNotNull(upgrade);
assertEquals("Downgrade groups reduced from 3 to 2", 2, upgrade.getUpgradeGroups().size());
group = upgrade.getUpgradeGroups().get(1);
assertEquals("Execution items increased from 1 to 2", 2, group.getItems().size());
}
@Test
public void testPercents() throws Exception {
RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
Resource res = createdResources.iterator().next();
Long id = (Long) res.getPropertyValue("Upgrade/request_id");
assertNotNull(id);
assertEquals(Long.valueOf(1), id);
StageDAO stageDao = injector.getInstance(StageDAO.class);
HostRoleCommandDAO hrcDao = injector.getInstance(HostRoleCommandDAO.class);
List<StageEntity> stages = stageDao.findByRequestId(id);
List<HostRoleCommandEntity> tasks = hrcDao.findByRequest(id);
Set<Long> stageIds = new HashSet<>();
for (StageEntity se : stages) {
stageIds.add(se.getStageId());
}
CalculatedStatus calc = null;
int i = 0;
for (HostRoleCommandEntity hrce : tasks) {
hrce.setStatus(HostRoleStatus.IN_PROGRESS);
hrcDao.merge(hrce);
calc = CalculatedStatus.statusFromStageSummary(hrcDao.findAggregateCounts(id), stageIds);
assertEquals(((i++) + 1) * 4.375d, calc.getPercent(), 0.01d);
assertEquals(HostRoleStatus.IN_PROGRESS, calc.getStatus());
}
i = 0;
for (HostRoleCommandEntity hrce : tasks) {
hrce.setStatus(HostRoleStatus.COMPLETED);
hrcDao.merge(hrce);
calc = CalculatedStatus.statusFromStageSummary(hrcDao.findAggregateCounts(id), stageIds);
assertEquals(35 + (((i++) + 1) * 8.125), calc.getPercent(), 0.01d);
if (i < 8) {
assertEquals(HostRoleStatus.IN_PROGRESS, calc.getStatus());
}
}
calc = CalculatedStatus.statusFromStageSummary(hrcDao.findAggregateCounts(id), stageIds);
assertEquals(HostRoleStatus.COMPLETED, calc.getStatus());
assertEquals(100d, calc.getPercent(), 0.01d);
}
@Test
public void testCreateCrossStackUpgrade() throws Exception {
Cluster cluster = clusters.getCluster("c1");
StackId oldStack = cluster.getDesiredStackVersion();
for (Service s : cluster.getServices().values()) {
assertEquals(oldStack, s.getDesiredStackVersion());
for (ServiceComponent sc : s.getServiceComponents().values()) {
assertEquals(oldStack, sc.getDesiredStackVersion());
for (ServiceComponentHost sch : sc.getServiceComponentHosts().values()) {
assertEquals(oldStack, sch.getDesiredStackVersion());
}
}
}
Config config = configFactory.createNew(cluster, "zoo.cfg", "abcdefg", Collections.singletonMap("a", "b"), null);
cluster.addDesiredConfig("admin", Collections.singleton(config));
Map<String, Object> requestProps = new HashMap<>();
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_DIRECTION, Direction.UPGRADE.name());
ResourceProvider upgradeResourceProvider = createProvider(amc);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity upgrade = upgrades.get(0);
assertEquals(3, upgrade.getUpgradeGroups().size());
UpgradeGroupEntity group = upgrade.getUpgradeGroups().get(2);
assertEquals(2, group.getItems().size());
group = upgrade.getUpgradeGroups().get(0);
assertEquals(2, group.getItems().size());
assertTrue(cluster.getDesiredConfigs().containsKey("zoo.cfg"));
StackId newStack = cluster.getDesiredStackVersion();
assertFalse(oldStack.equals(newStack));
for (Service s : cluster.getServices().values()) {
assertEquals(newStack, s.getDesiredStackVersion());
for (ServiceComponent sc : s.getServiceComponents().values()) {
assertEquals(newStack, sc.getDesiredStackVersion());
for (ServiceComponentHost sch : sc.getServiceComponentHosts().values()) {
assertEquals(newStack, sch.getDesiredStackVersion());
}
}
}
}
/**
* Tests merging configurations between existing and new stack values on
* upgrade.
*
* @throws Exception
*/
@Test
public void testMergeConfigurations() throws Exception {
StackId stack211 = new StackId("HDP-2.1.1");
StackId stack220 = new StackId("HDP-2.2.0");
Map<String, Map<String, String>> stack211Configs = new HashMap<>();
Map<String, String> stack211FooType = new HashMap<>();
Map<String, String> stack211BarType = new HashMap<>();
Map<String, String> stack211BazType = new HashMap<>();
stack211Configs.put("foo-site", stack211FooType);
stack211Configs.put("bar-site", stack211BarType);
stack211Configs.put("baz-site", stack211BazType);
stack211FooType.put("1", "one");
stack211FooType.put("11", "one-one");
stack211BarType.put("2", "two");
stack211BazType.put("3", "three");
Map<String, Map<String, String>> stack220Configs = new HashMap<>();
Map<String, String> stack220FooType = new HashMap<>();
Map<String, String> stack220BazType = new HashMap<>();
Map<String, String> stack220FlumeEnvType = new HashMap<>();
stack220Configs.put("foo-site", stack220FooType);
stack220Configs.put("baz-site", stack220BazType);
stack220Configs.put("flume-env", stack220FlumeEnvType);
stack220FooType.put("1", "one-new");
stack220FooType.put("111", "one-one-one");
stack220BazType.put("3", "three-new");
stack220FlumeEnvType.put("flume_env_key", "flume-env-value");
Map<String, String> clusterFooType = new HashMap<>();
Map<String, String> clusterBarType = new HashMap<>();
Map<String, String> clusterBazType = new HashMap<>();
Config fooConfig = EasyMock.createNiceMock(Config.class);
Config barConfig = EasyMock.createNiceMock(Config.class);
Config bazConfig = EasyMock.createNiceMock(Config.class);
clusterFooType.put("1", "one");
clusterFooType.put("11", "one-one");
clusterBarType.put("2", "two");
clusterBazType.put("3", "three-changed");
expect(fooConfig.getProperties()).andReturn(clusterFooType);
expect(barConfig.getProperties()).andReturn(clusterBarType);
expect(bazConfig.getProperties()).andReturn(clusterBazType);
Map<String, DesiredConfig> desiredConfigurations = new HashMap<>();
desiredConfigurations.put("foo-site", null);
desiredConfigurations.put("bar-site", null);
desiredConfigurations.put("baz-site", null);
Cluster cluster = EasyMock.createNiceMock(Cluster.class);
expect(cluster.getCurrentStackVersion()).andReturn(stack211);
expect(cluster.getDesiredStackVersion()).andReturn(stack220);
expect(cluster.getDesiredConfigs()).andReturn(desiredConfigurations);
expect(cluster.getDesiredConfigByType("foo-site")).andReturn(fooConfig);
expect(cluster.getDesiredConfigByType("bar-site")).andReturn(barConfig);
expect(cluster.getDesiredConfigByType("baz-site")).andReturn(bazConfig);
// setup the config helper for placeholder resolution
EasyMock.reset(configHelper);
expect(
configHelper.getDefaultProperties(EasyMock.eq(stack211), EasyMock.anyObject(Cluster.class), EasyMock.anyBoolean())).andReturn(
stack211Configs).anyTimes();
expect(
configHelper.getDefaultProperties(EasyMock.eq(stack220), EasyMock.anyObject(Cluster.class), EasyMock.anyBoolean())).andReturn(
stack220Configs).anyTimes();
Capture<Map<String, Map<String, String>>> expectedConfigurationsCapture = EasyMock.newCapture();
configHelper.createConfigTypes(EasyMock.anyObject(Cluster.class),
EasyMock.anyObject(AmbariManagementController.class),
EasyMock.capture(expectedConfigurationsCapture),
EasyMock.anyObject(String.class), EasyMock.anyObject(String.class));
EasyMock.expectLastCall().once();
EasyMock.replay(configHelper, cluster, fooConfig, barConfig, bazConfig);
UpgradeResourceProvider upgradeResourceProvider = createProvider(amc);
Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
UpgradePack upgrade = upgradePacks.get("upgrade_to_new_stack");
upgradeResourceProvider.applyStackAndProcessConfigurations(stack211.getStackName(), cluster, "2.2.0.0", Direction.UPGRADE, upgrade, "admin");
Map<String, Map<String, String>> expectedConfigurations = expectedConfigurationsCapture.getValue();
Map<String, String> expectedFooType = expectedConfigurations.get("foo-site");
Map<String, String> expectedBarType = expectedConfigurations.get("bar-site");
Map<String, String> expectedBazType = expectedConfigurations.get("baz-site");
// As the upgrade pack did not have any Flume updates, its configs should not be updated.
assertFalse(expectedConfigurations.containsKey("flume-env"));
// the really important values are one-new and three-changed; one-new
// indicates that the new stack value is changed since it was not customized
// while three-changed represents that the customized value was preserved
// even though the stack value changed
assertEquals("one-new", expectedFooType.get("1"));
assertEquals("one-one", expectedFooType.get("11"));
assertEquals("two", expectedBarType.get("2"));
assertEquals("three-changed", expectedBazType.get("3"));
}
/**
* @param amc
* @return the provider
*/
private UpgradeResourceProvider createProvider(AmbariManagementController 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 {
Cluster cluster = clusters.getCluster("c1");
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(0, upgrades.size());
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
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);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
RequestStatus status = upgradeResourceProvider.createResources(request);
upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity entity = upgrades.get(0);
assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
assertEquals(UpgradeType.ROLLING, entity.getUpgradeType());
StageDAO stageDAO = injector.getInstance(StageDAO.class);
List<StageEntity> stageEntities = stageDAO.findByRequestId(entity.getRequestId());
Gson gson = new Gson();
for (StageEntity se : stageEntities) {
Map<String, String> map = gson.<Map<String, String>> fromJson(se.getCommandParamsStage(),Map.class);
assertTrue(map.containsKey("upgrade_direction"));
assertEquals("upgrade", map.get("upgrade_direction"));
if(map.containsKey("upgrade_type")){
assertEquals("rolling_upgrade", map.get("upgrade_type"));
}
}
List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
assertEquals(3, upgradeGroups.size());
UpgradeGroupEntity group = upgradeGroups.get(1);
assertEquals(4, group.getItems().size());
assertTrue(
group.getItems().get(0).getText().contains("placeholder of placeholder-rendered-properly"));
assertTrue(group.getItems().get(1).getText().contains("Restarting"));
assertTrue(group.getItems().get(2).getText().contains("Updating"));
assertTrue(group.getItems().get(3).getText().contains("Service Check"));
ActionManager am = injector.getInstance(ActionManager.class);
List<Long> requests = am.getRequestsByStatus(
org.apache.ambari.server.actionmanager.RequestStatus.IN_PROGRESS, 100, true);
assertEquals(1, requests.size());
assertEquals(requests.get(0), entity.getRequestId());
List<Stage> stages = am.getRequestStatus(requests.get(0).longValue());
assertEquals(8, stages.size());
List<HostRoleCommand> tasks = am.getRequestTasks(requests.get(0).longValue());
// same number of tasks as stages here
assertEquals(8, tasks.size());
Set<Long> slaveStageIds = new HashSet<>();
UpgradeGroupEntity coreSlavesGroup = upgradeGroups.get(1);
for (UpgradeItemEntity itemEntity : coreSlavesGroup.getItems()) {
slaveStageIds.add(itemEntity.getStageId());
}
for (Stage stage : stages) {
// For this test the core slaves group stages should be skippable and NOT
// allow retry.
assertEquals(slaveStageIds.contains(stage.getStageId()), stage.isSkippable());
for (Map<String, HostRoleCommand> taskMap : stage.getHostRoleCommands().values()) {
for (HostRoleCommand task : taskMap.values()) {
assertEquals(!slaveStageIds.contains(stage.getStageId()), task.isRetryAllowed());
}
}
}
return status;
}
@Test
public void testUpdateSkipFailures() throws Exception {
testCreateResourcesWithAutoSkipFailures();
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(1);
assertEquals(1, upgrades.size());
UpgradeEntity entity = upgrades.get(0);
HostRoleCommandDAO dao = injector.getInstance(HostRoleCommandDAO.class);
List<HostRoleCommandEntity> tasks = dao.findByRequest(entity.getRequestId());
for (HostRoleCommandEntity task : tasks) {
StageEntity stage = task.getStage();
if (stage.isSkippable() && stage.isAutoSkipOnFailureSupported()) {
assertTrue(task.isFailureAutoSkipped());
} else {
assertFalse(task.isFailureAutoSkipped());
}
}
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.TRUE.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.FALSE.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, "" + entity.getRequestId());
ResourceProvider upgradeResourceProvider = createProvider(amc);
Request request = PropertyHelper.getUpdateRequest(requestProps, null);
upgradeResourceProvider.updateResources(request, null);
tasks = dao.findByRequest(entity.getRequestId());
for (HostRoleCommandEntity task : tasks) {
if (task.getRoleCommand() == RoleCommand.SERVICE_CHECK) {
assertFalse(task.isFailureAutoSkipped());
} else {
StageEntity stage = task.getStage();
if (stage.isSkippable() && stage.isAutoSkipOnFailureSupported()) {
assertTrue(task.isFailureAutoSkipped());
} else {
assertFalse(task.isFailureAutoSkipped());
}
}
}
requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.FALSE.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.TRUE.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, "" + entity.getRequestId());
request = PropertyHelper.getUpdateRequest(requestProps, null);
upgradeResourceProvider.updateResources(request, null);
tasks = dao.findByRequest(entity.getRequestId());
for (HostRoleCommandEntity task : tasks) {
if (task.getRoleCommand() == RoleCommand.SERVICE_CHECK) {
StageEntity stage = task.getStage();
if (stage.isSkippable() && stage.isAutoSkipOnFailureSupported()) {
assertTrue(task.isFailureAutoSkipped());
} else {
assertFalse(task.isFailureAutoSkipped());
}
} else {
assertFalse(task.isFailureAutoSkipped());
}
}
requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.FALSE.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.FALSE.toString());
requestProps.put(UpgradeResourceProvider.UPGRADE_REQUEST_ID, "" + entity.getRequestId());
request = PropertyHelper.getUpdateRequest(requestProps, null);
upgradeResourceProvider.updateResources(request, null);
tasks = dao.findByRequest(entity.getRequestId());
for (HostRoleCommandEntity task : tasks) {
assertFalse(task.isFailureAutoSkipped());
}
}
/**
* Tests that an error while commiting the data cleanly rolls back the transaction so that
* no request/stage/tasks are created.
*
* @throws Exception
*/
@Test
public void testRollback() throws Exception {
Cluster cluster = clusters.getCluster("c1");
Map<String, Object> requestProps = new HashMap<>();
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_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;
try {
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
Assert.fail("Expected a NullPointerException");
} catch (NullPointerException npe) {
// expected
}
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(0, upgrades.size());
List<Long> requestIds = requestDao.findAllRequestIds(1, true, cluster.getClusterId());
assertEquals(0, requestIds.size());
}
/**
* Tests that a {@link UpgradeType#HOST_ORDERED} upgrade throws an exception
* on missing hosts.
*
* @throws Exception
*/
@Test()
public void testCreateHostOrderedUpgradeThrowsExceptions() throws Exception {
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
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);
try {
upgradeResourceProvider.createResources(request);
Assert.fail("The request should have failed due to the missing Upgrade/host_order property");
} catch( SystemException systemException ){
// expected
}
// stick a bad host_ordered_hosts in there which has the wrong hosts
Set<Map<String, List<String>>> hostsOrder = new LinkedHashSet<>();
Map<String, List<String>> hostGrouping = new HashMap<>();
hostGrouping.put("hosts", Lists.newArrayList("invalid-host"));
hostsOrder.add(hostGrouping);
requestProps.put(UpgradeResourceProvider.UPGRADE_HOST_ORDERED_HOSTS, hostsOrder);
try {
upgradeResourceProvider.createResources(request);
Assert.fail("The request should have failed due to invalid hosts");
} catch (SystemException systemException) {
// expected
}
// use correct hosts now
hostsOrder = new LinkedHashSet<>();
hostGrouping = new HashMap<>();
hostGrouping.put("hosts", Lists.newArrayList("h1"));
hostsOrder.add(hostGrouping);
requestProps.put(UpgradeResourceProvider.UPGRADE_HOST_ORDERED_HOSTS, hostsOrder);
upgradeResourceProvider.createResources(request);
}
/**
* Exercises that a component that goes from upgrade->downgrade that switches
* {@code versionAdvertised} between will go to UKNOWN. This exercises
* {@link UpgradeHelper#putComponentsToUpgradingState(String, Map, StackId)}
* @throws Exception
*/
@Test
public void testCreateUpgradeDowngradeCycleAdvertisingVersion() throws Exception {
Cluster cluster = clusters.getCluster("c1");
Service service = cluster.addService("STORM");
service.setDesiredStackVersion(cluster.getDesiredStackVersion());
ServiceComponent component = service.addServiceComponent("DRPC_SERVER");
ServiceComponentHost sch = component.addServiceComponentHost("h1");
sch.setVersion("2.1.1.0");
ResourceProvider upgradeResourceProvider = createProvider(amc);
Map<String, Object> requestProps = new HashMap<>();
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.UPGRADE.name());
Map<String, String> requestInfoProperties = new HashMap<>();
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties);
RequestStatus status = upgradeResourceProvider.createResources(request);
assertEquals(1, status.getAssociatedResources().size());
Resource r = status.getAssociatedResources().iterator().next();
String id = r.getPropertyValue("Upgrade/request_id").toString();
component = service.getServiceComponent("DRPC_SERVER");
assertNotNull(component);
assertEquals("2.2.0.0", component.getDesiredVersion());
ServiceComponentHost hostComponent = component.getServiceComponentHost("h1");
assertEquals(UpgradeState.IN_PROGRESS, hostComponent.getUpgradeState());
// !!! can't start a downgrade until cancelling the previous upgrade
abortUpgrade(Long.parseLong(id));
requestProps.clear();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.0");
requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test");
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());
request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), requestInfoProperties);
status = upgradeResourceProvider.createResources(request);
component = service.getServiceComponent("DRPC_SERVER");
assertNotNull(component);
assertEquals("UNKNOWN", component.getDesiredVersion());
hostComponent = component.getServiceComponentHost("h1");
assertEquals(UpgradeState.NONE, hostComponent.getUpgradeState());
assertEquals("UNKNOWN", hostComponent.getVersion());
}
/**
* Ensures that stages created with an HOU are sequential and do not skip any
* IDs. When there are stages with IDs like (1,2,3,5,6,7,10), the request will
* get stuck in a PENDING state. This affects HOU specifically since they can
* potentially try to create empty stages which won't get persisted (such as a
* STOP on client-only hosts).
*
* @throws Exception
*/
@Test()
public void testEmptyGroupingsDoNotSkipStageIds() throws Exception {
StageDAO stageDao = injector.getInstance(StageDAO.class);
Assert.assertEquals(0, stageDao.findAll().size());
// strip out all non-client components - clients don't have STOP commands
Cluster cluster = clusters.getCluster("c1");
List<ServiceComponentHost> schs = cluster.getServiceComponentHosts("h1");
for (ServiceComponentHost sch : schs) {
if (sch.isClientComponent()) {
continue;
}
cluster.removeServiceComponentHost(sch);
}
// define host order
Set<Map<String, List<String>>> hostsOrder = new LinkedHashSet<>();
Map<String, List<String>> hostGrouping = new HashMap<>();
hostGrouping = new HashMap<>();
hostGrouping.put("hosts", Lists.newArrayList("h1"));
hostsOrder.add(hostGrouping);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
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());
requestProps.put(UpgradeResourceProvider.UPGRADE_HOST_ORDERED_HOSTS, hostsOrder);
ResourceProvider upgradeResourceProvider = createProvider(amc);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
upgradeResourceProvider.createResources(request);
List<StageEntity> stages = stageDao.findByRequestId(cluster.getUpgradeInProgress().getRequestId());
Assert.assertEquals(3, stages.size());
long expectedStageId = 1L;
for (StageEntity stage : stages) {
Assert.assertEquals(expectedStageId++, stage.getStageId().longValue());
}
}
private String parseSingleMessage(String msgStr){
JsonParser parser = new JsonParser();
JsonArray msgArray = (JsonArray) parser.parse(msgStr);
JsonObject msg = (JsonObject) msgArray.get(0);
return msg.get("message").getAsString();
}
/**
* 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);
}
@Test
public void testTimeouts() throws Exception {
Cluster cluster = clusters.getCluster("c1");
StackEntity stackEntity = stackDAO.find("HDP", "2.1.1");
RepositoryVersionEntity repoVersionEntity = new RepositoryVersionEntity();
repoVersionEntity.setDisplayName("My New Version 3");
repoVersionEntity.setOperatingSystems("");
repoVersionEntity.setStack(stackEntity);
repoVersionEntity.setVersion("2.2.2.3");
repoVersionDao.create(repoVersionEntity);
Map<String, Object> requestProps = new HashMap<>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.2.3");
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);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
RequestStatus status = upgradeResourceProvider.createResources(request);
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
Resource res = createdResources.iterator().next();
Long id = (Long) res.getPropertyValue("Upgrade/request_id");
assertNotNull(id);
assertEquals(Long.valueOf(1), id);
ActionManager am = injector.getInstance(ActionManager.class);
List<HostRoleCommand> commands = am.getRequestTasks(id);
boolean found = false;
for (HostRoleCommand command : commands) {
ExecutionCommandWrapper wrapper = command.getExecutionCommandWrapper();
if (command.getRole().equals(Role.ZOOKEEPER_SERVER) && command.getRoleCommand().equals(RoleCommand.CUSTOM_COMMAND)) {
Map<String, String> commandParams = wrapper.getExecutionCommand().getCommandParams();
assertTrue(commandParams.containsKey(KeyNames.COMMAND_TIMEOUT));
assertEquals("824",commandParams.get(KeyNames.COMMAND_TIMEOUT));
found = true;
}
}
assertTrue("ZooKeeper timeout override was found", found);
}
/**
*
*/
private class MockModule implements Module {
/**
*
*/
@Override
public void configure(Binder binder) {
binder.bind(ConfigHelper.class).toInstance(configHelper);
}
}
}