Repository: ambari Updated Branches: refs/heads/trunk b305aecae -> c4e5cdf5c
AMBARI-15203. Add pre-upgrade check that warns about components with VERSION_MISMATCH (dlysnichenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c4e5cdf5 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c4e5cdf5 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c4e5cdf5 Branch: refs/heads/trunk Commit: c4e5cdf5c68563f3b8a5c7e0d1043eddfc236ae0 Parents: b305aec Author: Lisnichenko Dmitro <[email protected]> Authored: Mon Feb 29 13:34:40 2016 +0200 Committer: Lisnichenko Dmitro <[email protected]> Committed: Mon Feb 29 13:34:40 2016 +0200 ---------------------------------------------------------------------- .../ambari/server/checks/CheckDescription.java | 7 ++ .../ambari/server/checks/UpgradeCheckGroup.java | 5 + .../server/checks/VersionMismatchCheck.java | 105 +++++++++++++++++++ .../server/checks/VersionMismatchCheckTest.java | 80 ++++++++++++++ 4 files changed, 197 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c4e5cdf5/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java index ba987aa..b06848a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java @@ -224,6 +224,13 @@ public enum CheckDescription { " That is a potential problem when doing stack update."); }}), + VERSION_MISMATCH(PrereqCheckType.HOST, + "All components must be reporting the expected version", + new HashMap<String, String>() {{ + put(AbstractCheckDescriptor.DEFAULT, + "There are components which are not reporting the expected stack version: \n%s"); + }}), + SERVICES_RANGER_PASSWORD_VERIFY(PrereqCheckType.SERVICE, "Verify Ambari and Ranger Password Synchronization", new HashMap<String, String>() {{ http://git-wip-us.apache.org/repos/asf/ambari/blob/c4e5cdf5/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java index 0be5be1..0b24426 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckGroup.java @@ -69,6 +69,11 @@ public enum UpgradeCheckGroup { */ CONFIGURATION_WARNING(8.0f), + /*** + * Checks the component version on the hosts. + */ + COMPONENT_VERSION(9.0f), + /** * All other checks. */ http://git-wip-us.apache.org/repos/asf/ambari/blob/c4e5cdf5/ambari-server/src/main/java/org/apache/ambari/server/checks/VersionMismatchCheck.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/VersionMismatchCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/VersionMismatchCheck.java new file mode 100644 index 0000000..e37dc33 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/VersionMismatchCheck.java @@ -0,0 +1,105 @@ +package org.apache.ambari.server.checks; + +import com.google.inject.Singleton; +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.controller.PrereqCheckRequest; +import org.apache.ambari.server.state.Cluster; +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.UpgradeState; +import org.apache.ambari.server.state.stack.PrereqCheckStatus; +import org.apache.ambari.server.state.stack.PrerequisiteCheck; +import org.apache.commons.lang.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Warns about host components whose upgrade state is VERSION_MISMATCH. Never triggers + * fail. In failure description, lists actual and expected component versions. + */ +@Singleton +@UpgradeCheck(group = UpgradeCheckGroup.COMPONENT_VERSION, order = 7.0f, required = true) +public class VersionMismatchCheck extends AbstractCheckDescriptor { + + public VersionMismatchCheck() { + super(CheckDescription.VERSION_MISMATCH); + } + + @Override + public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException { + final String clusterName = request.getClusterName(); + final Cluster cluster = clustersProvider.get().getCluster(clusterName); + Map<String, Service> services = cluster.getServices(); + List<String> errorMessages = new ArrayList<String>(); + for (Service service : services.values()) { + validateService(service, prerequisiteCheck, errorMessages); + } + + if (!prerequisiteCheck.getFailedOn().isEmpty()) { + prerequisiteCheck.setStatus(PrereqCheckStatus.WARNING); + String failReason = getFailReason(prerequisiteCheck, request); + prerequisiteCheck.setFailReason(String.format(failReason, StringUtils.join(errorMessages, "\n"))); + prerequisiteCheck.setFailReason(StringUtils.join(errorMessages, "\n")); + } + } + + /** + * Iterates over all service components belonging to a service and validates them. + * @param service + * @param prerequisiteCheck + * @param errorMessages + * @throws AmbariException + */ + private void validateService(Service service, PrerequisiteCheck prerequisiteCheck, + List<String> errorMessages) throws AmbariException { + Map<String, ServiceComponent> serviceComponents = service.getServiceComponents(); + for (ServiceComponent serviceComponent : serviceComponents.values()) { + validateServiceComponent(serviceComponent, prerequisiteCheck, errorMessages); + } + } + + /** + * Iterates over all host components belonging to a service component and validates them. + * @param serviceComponent + * @param prerequisiteCheck + * @param errorMessages + */ + private void validateServiceComponent(ServiceComponent serviceComponent, + PrerequisiteCheck prerequisiteCheck, List<String> errorMessages) { + Map<String, ServiceComponentHost> serviceComponentHosts = serviceComponent.getServiceComponentHosts(); + for (ServiceComponentHost serviceComponentHost : serviceComponentHosts.values()) { + validateServiceComponentHost(serviceComponent, serviceComponentHost, + prerequisiteCheck, errorMessages); + } + } + + /** + * Validates host component. If upgrade state of host component is VERSION_MISMATCH, + * adds hostname to a Failed On map of prerequisite check, and adds all other + * host component version details to errorMessages + * @param serviceComponent + * @param serviceComponentHost + * @param prerequisiteCheck + * @param errorMessages + */ + private void validateServiceComponentHost(ServiceComponent serviceComponent, + ServiceComponentHost serviceComponentHost, + PrerequisiteCheck prerequisiteCheck, + List<String> errorMessages) { + if (serviceComponentHost.getUpgradeState().equals(UpgradeState.VERSION_MISMATCH)) { + String hostName = serviceComponentHost.getHostName(); + String serviceComponentName = serviceComponentHost.getServiceComponentName(); + String desiredVersion = serviceComponent.getDesiredVersion(); + String actualVersion = serviceComponentHost.getVersion(); + + String message = hostName + "/" + serviceComponentName + + " desired version: " + desiredVersion + + ", actual version: " + actualVersion; + prerequisiteCheck.getFailedOn().add(hostName); + errorMessages.add(message); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/c4e5cdf5/ambari-server/src/test/java/org/apache/ambari/server/checks/VersionMismatchCheckTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/VersionMismatchCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/VersionMismatchCheckTest.java new file mode 100644 index 0000000..42aef30 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/VersionMismatchCheckTest.java @@ -0,0 +1,80 @@ +package org.apache.ambari.server.checks; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Provider; +import org.apache.ambari.server.controller.PrereqCheckRequest; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +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.stack.PrereqCheckStatus; +import org.apache.ambari.server.state.stack.PrerequisiteCheck; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.apache.ambari.server.state.UpgradeState.IN_PROGRESS; +import static org.apache.ambari.server.state.UpgradeState.VERSION_MISMATCH; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Checks VersionMismatchCheck pre-upgrade check. Includes tests that emulate both + * clusters with and without host components in VERSION_MISMATCH upgrade state. + */ +public class VersionMismatchCheckTest { + private static final String CLUSTER_NAME = "cluster1"; + private static final String FIRST_SERVICE_NAME = "service1"; + private static final String FIRST_SERVICE_COMPONENT_NAME = "component1"; + private static final String FIRST_SERVICE_COMPONENT_HOST_NAME = "host1"; + private VersionMismatchCheck versionMismatchCheck; + private Map<String, ServiceComponentHost> firstServiceComponentHosts; + + @Before + public void setUp() throws Exception { + final Clusters clusters = mock(Clusters.class); + versionMismatchCheck = new VersionMismatchCheck(); + versionMismatchCheck.clustersProvider = new Provider<Clusters>() { + @Override + public Clusters get() { + return clusters; + } + }; + + Cluster cluster = mock(Cluster.class); + when(clusters.getCluster(CLUSTER_NAME)).thenReturn(cluster); + + Service firstService = mock(Service.class); + Map<String, Service> services = ImmutableMap.of(FIRST_SERVICE_NAME, firstService); + when(cluster.getServices()).thenReturn(services); + + ServiceComponent firstServiceComponent = mock(ServiceComponent.class); + Map<String, ServiceComponent> components = ImmutableMap.of(FIRST_SERVICE_COMPONENT_NAME, firstServiceComponent); + when(firstService.getServiceComponents()).thenReturn(components); + + ServiceComponentHost firstServiceComponentHost = mock(ServiceComponentHost.class); + firstServiceComponentHosts = ImmutableMap.of(FIRST_SERVICE_COMPONENT_HOST_NAME, firstServiceComponentHost); + when(firstServiceComponent.getServiceComponentHosts()).thenReturn(firstServiceComponentHosts); + } + + @Test + public void testWarningWhenHostWithVersionMismatchExists() throws Exception { + when(firstServiceComponentHosts.get(FIRST_SERVICE_COMPONENT_HOST_NAME).getUpgradeState()).thenReturn(VERSION_MISMATCH); + + PrerequisiteCheck check = new PrerequisiteCheck(null, CLUSTER_NAME); + versionMismatchCheck.perform(check, new PrereqCheckRequest(CLUSTER_NAME)); + Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus()); + } + + @Test + public void testWarningWhenHostWithVersionMismatchDoesNotExist() throws Exception { + when(firstServiceComponentHosts.get(FIRST_SERVICE_COMPONENT_HOST_NAME).getUpgradeState()).thenReturn(IN_PROGRESS); + + PrerequisiteCheck check = new PrerequisiteCheck(null, CLUSTER_NAME); + versionMismatchCheck.perform(check, new PrereqCheckRequest(CLUSTER_NAME)); + Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus()); + } +} \ No newline at end of file
