AMBARI-22025. Service auto start broken due to incomplete execution command
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7c687bbc Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7c687bbc Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7c687bbc Branch: refs/heads/branch-3.0-ams Commit: 7c687bbc226b19f85a6f6f292537760e5d6d8048 Parents: f9c0c90 Author: Attila Doroszlai <adorosz...@hortonworks.com> Authored: Thu Sep 21 16:24:04 2017 +0200 Committer: Attila Doroszlai <adorosz...@hortonworks.com> Committed: Thu Sep 21 23:22:19 2017 +0200 ---------------------------------------------------------------------- .../actionmanager/ExecutionCommandWrapper.java | 122 ++++++++++--------- .../AmbariManagementControllerImpl.java | 8 +- .../server/agent/TestHeartbeatMonitor.java | 20 ++- 3 files changed, 87 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/7c687bbc/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java index 5f9300a..47aa093 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java @@ -19,6 +19,7 @@ package org.apache.ambari.server.actionmanager; import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER; import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER; +import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION; import java.util.HashMap; import java.util.Map; @@ -30,7 +31,6 @@ import org.apache.ambari.server.RoleCommand; import org.apache.ambari.server.ServiceNotFoundException; import org.apache.ambari.server.agent.AgentCommand.AgentCommandType; import org.apache.ambari.server.agent.ExecutionCommand; -import org.apache.ambari.server.agent.ExecutionCommand.KeyNames; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; @@ -206,89 +206,93 @@ public class ExecutionCommandWrapper { } } - // set the repository version for the component this command is for - - // always use the current desired version - try { - RepositoryVersionEntity repositoryVersion = null; - String serviceName = executionCommand.getServiceName(); - if (!StringUtils.isEmpty(serviceName)) { - Service service = cluster.getService(serviceName); - if (null != service) { - repositoryVersion = service.getDesiredRepositoryVersion(); - } + setVersions(cluster); + + // provide some basic information about a cluster upgrade if there is one + // in progress + UpgradeEntity upgrade = cluster.getUpgradeInProgress(); + if (null != upgrade) { + UpgradeContext upgradeContext = upgradeContextFactory.create(cluster, upgrade); + UpgradeSummary upgradeSummary = upgradeContext.getUpgradeSummary(); + executionCommand.setUpgradeSummary(upgradeSummary); + } + + } catch (ClusterNotFoundException cnfe) { + // it's possible that there are commands without clusters; in such cases, + // just return the de-serialized command and don't try to read configs + LOG.warn( + "Unable to lookup the cluster by ID; assuming that there is no cluster and therefore no configs for this execution command: {}", + cnfe.getMessage()); + + return executionCommand; + } catch (AmbariException e) { + throw new RuntimeException(e); + } + + return executionCommand; + } + + public void setVersions(Cluster cluster) { + // set the repository version for the component this command is for - + // always use the current desired version + String serviceName = executionCommand.getServiceName(); + try { + RepositoryVersionEntity repositoryVersion = null; + if (!StringUtils.isEmpty(serviceName)) { + Service service = cluster.getService(serviceName); + if (null != service) { + repositoryVersion = service.getDesiredRepositoryVersion(); String componentName = executionCommand.getComponentName(); if (!StringUtils.isEmpty(componentName)) { - ServiceComponent serviceComponent = service.getServiceComponent( - executionCommand.getComponentName()); - + ServiceComponent serviceComponent = service.getServiceComponent(componentName); if (null != serviceComponent) { repositoryVersion = serviceComponent.getDesiredRepositoryVersion(); } } } + } - Map<String, String> commandParams = executionCommand.getCommandParams(); + Map<String, String> commandParams = executionCommand.getCommandParams(); - if (null != repositoryVersion) { - // only set the version if it's not set and this is NOT an install - // command - if (!commandParams.containsKey(KeyNames.VERSION) - && executionCommand.getRoleCommand() != RoleCommand.INSTALL) { - commandParams.put(KeyNames.VERSION, repositoryVersion.getVersion()); - } + if (null != repositoryVersion) { + // only set the version if it's not set and this is NOT an install + // command + if (!commandParams.containsKey(VERSION) + && executionCommand.getRoleCommand() != RoleCommand.INSTALL) { + commandParams.put(VERSION, repositoryVersion.getVersion()); + } - StackId stackId = repositoryVersion.getStackId(); - StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), - stackId.getStackVersion()); + StackId stackId = repositoryVersion.getStackId(); + StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), + stackId.getStackVersion()); - if (!commandParams.containsKey(HOOKS_FOLDER)) { - commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder()); - } + if (!commandParams.containsKey(HOOKS_FOLDER)) { + commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder()); + } - if (!commandParams.containsKey(SERVICE_PACKAGE_FOLDER)) { - if (!StringUtils.isEmpty(serviceName)) { - ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(), - stackId.getStackVersion(), serviceName); + if (!commandParams.containsKey(SERVICE_PACKAGE_FOLDER)) { + if (!StringUtils.isEmpty(serviceName)) { + ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(), + stackId.getStackVersion(), serviceName); - commandParams.put(SERVICE_PACKAGE_FOLDER, serviceInfo.getServicePackageFolder()); - } + commandParams.put(SERVICE_PACKAGE_FOLDER, serviceInfo.getServicePackageFolder()); } } - } catch (ServiceNotFoundException serviceNotFoundException) { - // it's possible that there are commands specified for a service where - // the service doesn't exist yet - LOG.warn( - "The service {} is not installed in the cluster. No repository version will be sent for this command.", - executionCommand.getServiceName()); } // set the desired versions of versionable components. This is safe even during an upgrade because // we are "loading-late": components that have not yet upgraded in an EU will have the correct versions. executionCommand.setComponentVersions(cluster); - - // provide some basic information about a cluster upgrade if there is one - // in progress - UpgradeEntity upgrade = cluster.getUpgradeInProgress(); - if (null != upgrade) { - UpgradeContext upgradeContext = upgradeContextFactory.create(cluster, upgrade); - UpgradeSummary upgradeSummary = upgradeContext.getUpgradeSummary(); - executionCommand.setUpgradeSummary(upgradeSummary); - } - - } catch (ClusterNotFoundException cnfe) { - // it's possible that there are commands without clusters; in such cases, - // just return the de-serialized command and don't try to read configs + } catch (ServiceNotFoundException serviceNotFoundException) { + // it's possible that there are commands specified for a service where + // the service doesn't exist yet LOG.warn( - "Unable to lookup the cluster by ID; assuming that there is no cluster and therefore no configs for this execution command: {}", - cnfe.getMessage()); - - return executionCommand; + "The service {} is not installed in the cluster. No repository version will be sent for this command.", + serviceName); } catch (AmbariException e) { throw new RuntimeException(e); } - - return executionCommand; } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/7c687bbc/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java index d458675..b2993e3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java @@ -82,6 +82,7 @@ import org.apache.ambari.server.ServiceNotFoundException; import org.apache.ambari.server.StackAccessException; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.CommandExecutionType; +import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper; import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.Stage; @@ -2323,8 +2324,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle stackId.getStackVersion()); Map<String, ServiceInfo> servicesMap = ambariMetaInfo.getServices(stackInfo.getName(), stackInfo.getVersion()); - ExecutionCommand execCmd = stage.getExecutionCommandWrapper(scHost.getHostName(), - scHost.getServiceComponentName()).getExecutionCommand(); + ExecutionCommandWrapper execCmdWrapper = stage.getExecutionCommandWrapper(hostname, componentName); + ExecutionCommand execCmd = execCmdWrapper.getExecutionCommand(); execCmd.setConfigurations(configurations); execCmd.setConfigurationAttributes(configurationAttributes); @@ -2552,8 +2553,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle execCmd.setCommandParams(commandParams); execCmd.setRepositoryFile(customCommandExecutionHelper.getCommandRepository(cluster, component, host)); + execCmdWrapper.setVersions(cluster); - if ((execCmd != null) && (execCmd.getConfigurationTags().containsKey("cluster-env"))) { + if (execCmd.getConfigurationTags().containsKey("cluster-env")) { LOG.debug("AmbariManagementControllerImpl.createHostAction: created ExecutionCommand for host {}, role {}, roleCommand {}, and command ID {}, with cluster-env tags {}", execCmd.getHostname(), execCmd.getRole(), execCmd.getRoleCommand(), execCmd.getCommandId(), execCmd.getConfigurationTags().get("cluster-env").get("tag")); } http://git-wip-us.apache.org/repos/asf/ambari/blob/7c687bbc/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java index 1021175..374774a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java @@ -17,6 +17,8 @@ */ package org.apache.ambari.server.agent; +import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER; +import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -38,6 +40,7 @@ import org.apache.ambari.server.H2DatabaseCleaner; import org.apache.ambari.server.Role; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.OrmTestHelper; @@ -58,6 +61,8 @@ import org.apache.ambari.server.state.svccomphost.ServiceComponentHostDisableEve import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent; import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpSucceededEvent; import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartedEvent; +import org.apache.ambari.server.topology.TopologyManager; +import org.apache.ambari.server.utils.StageUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -89,6 +94,8 @@ public class TestHeartbeatMonitor { injector.getInstance(GuiceJpaInitializer.class); helper = injector.getInstance(OrmTestHelper.class); ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); + StageUtils.setTopologyManager(injector.getInstance(TopologyManager.class)); + StageUtils.setConfiguration(injector.getInstance(Configuration.class)); } @After @@ -200,6 +207,8 @@ public class TestHeartbeatMonitor { hb.setResponseId(12); handler.handleHeartBeat(hb); + hm.getAgentRequests().setExecutionDetailsRequest(hostname1, "DATANODE", Boolean.TRUE.toString()); + List<StatusCommand> cmds = hm.generateStatusCommands(hostname1); assertTrue("HeartbeatMonitor should generate StatusCommands for host1", cmds.size() == 3); assertEquals("HDFS", cmds.get(0).getServiceName()); @@ -208,10 +217,19 @@ public class TestHeartbeatMonitor { boolean containsSECONDARY_NAMENODEStatus = false; for (StatusCommand cmd : cmds) { - containsDATANODEStatus |= cmd.getComponentName().equals("DATANODE"); + boolean isDataNode = cmd.getComponentName().equals("DATANODE"); + containsDATANODEStatus |= isDataNode; containsNAMENODEStatus |= cmd.getComponentName().equals("NAMENODE"); containsSECONDARY_NAMENODEStatus |= cmd.getComponentName().equals("SECONDARY_NAMENODE"); assertTrue(cmd.getConfigurations().size() > 0); + + ExecutionCommand execCmd = cmd.getExecutionCommand(); + assertEquals(isDataNode, execCmd != null); + if (execCmd != null) { + Map<String, String> commandParams = execCmd.getCommandParams(); + assertTrue(SERVICE_PACKAGE_FOLDER + " should be included", commandParams.containsKey(SERVICE_PACKAGE_FOLDER)); + assertTrue(HOOKS_FOLDER + " should be included", commandParams.containsKey(HOOKS_FOLDER)); + } } assertEquals(true, containsDATANODEStatus);