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

Reply via email to