You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2015/11/11 20:48:48 UTC

[2/2] ambari git commit: AMBARI-13818. SKIPPED_FAILED state should not be bubbled up to the Upgrade level (dlysnichenko)

AMBARI-13818. SKIPPED_FAILED state should not be bubbled up to the Upgrade level (dlysnichenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/85647998
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/85647998
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/85647998

Branch: refs/heads/trunk
Commit: 85647998806346379042535692349c1b492e4bf6
Parents: a1e5b23
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Wed Nov 11 21:48:11 2015 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Wed Nov 11 21:49:05 2015 +0200

----------------------------------------------------------------------
 .../controller/internal/CalculatedStatus.java   | 53 ++++++++++++++-
 .../internal/UpgradeGroupResourceProvider.java  |  3 +
 .../internal/CalculatedStatusTest.java          | 69 +++++++++++++++++---
 3 files changed, 113 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/85647998/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
index f87c32c..cf9d952 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
@@ -44,6 +44,11 @@ public class CalculatedStatus {
   private final HostRoleStatus status;
 
   /**
+   * The display status.
+   */
+  private final HostRoleStatus displayStatus;
+
+  /**
    * The calculated percent complete.
    */
   private final double percent;
@@ -58,7 +63,19 @@ public class CalculatedStatus {
    * @param percent  the calculated percent complete
    */
   private CalculatedStatus(HostRoleStatus status, double percent) {
+    this(status, null, percent);
+  }
+
+  /**
+   * Overloaded constructor that allows to set the display status if required.
+   *
+   * @param status   the calculated overall status
+   * @param displayStatus the calculated display status
+   * @param percent  the calculated percent complete
+   */
+  private CalculatedStatus(HostRoleStatus status, HostRoleStatus displayStatus, double percent) {
     this.status  = status;
+    this.displayStatus  = displayStatus;
     this.percent = percent;
   }
 
@@ -75,6 +92,19 @@ public class CalculatedStatus {
   }
 
   /**
+   * Get the calculated display status. The display_status field is used as
+   * a hint for UI. It's effective only on UpgradeGroup level.
+   * We should expose it for the following states:
+   * SKIPPED_FAILED
+   * FAILED
+   *
+   * @return the display status
+   */
+  public HostRoleStatus getDisplayStatus() {
+    return displayStatus;
+  }
+
+  /**
    * Get the calculated percent complete.
    *
    * @return the percent complete
@@ -267,6 +297,8 @@ public class CalculatedStatus {
     Collection<HostRoleStatus> stageStatuses = new HashSet<HostRoleStatus>();
     Collection<HostRoleStatus> taskStatuses = new ArrayList<HostRoleStatus>();
 
+    HostRoleStatus displayStatus = null;
+
     for (Long stageId : stageIds) {
       if (!stageDto.containsKey(stageId)) {
         continue;
@@ -277,6 +309,7 @@ public class CalculatedStatus {
       int total = summary.getTaskTotal();
       boolean skip = summary.isStageSkippable();
       Map<HostRoleStatus, Integer> counts = calculateStatusCounts(summary.getTaskStatuses());
+      displayStatus = calculateDisplayStatus(counts, displayStatus);
 
       HostRoleStatus stageStatus = calculateSummaryStatus(counts, total, skip);
 
@@ -290,7 +323,7 @@ public class CalculatedStatus {
 
     double progressPercent = calculateProgressPercent(calculateStatusCounts(taskStatuses), taskStatuses.size());
 
-    return new CalculatedStatus(status, progressPercent);
+    return new CalculatedStatus(status, displayStatus, progressPercent);
   }
 
   /**
@@ -342,10 +375,26 @@ public class CalculatedStatus {
         counters.get(HostRoleStatus.HOLDING) > 0 ? HostRoleStatus.HOLDING :
         counters.get(HostRoleStatus.HOLDING_FAILED) > 0 ? HostRoleStatus.HOLDING_FAILED :
         counters.get(HostRoleStatus.HOLDING_TIMEDOUT) > 0 ? HostRoleStatus.HOLDING_TIMEDOUT :
-        counters.get(HostRoleStatus.SKIPPED_FAILED) > 0 ? HostRoleStatus.SKIPPED_FAILED :
         counters.get(HostRoleStatus.FAILED) > 0 && !skippable ? HostRoleStatus.FAILED :
         counters.get(HostRoleStatus.ABORTED) > 0 ? HostRoleStatus.ABORTED:
         counters.get(HostRoleStatus.TIMEDOUT) > 0 && !skippable ? HostRoleStatus.TIMEDOUT :
         counters.get(HostRoleStatus.COMPLETED) == total ? HostRoleStatus.COMPLETED : HostRoleStatus.IN_PROGRESS;
   }
+
+  /**
+   * Calculate a display status for upgrade group.
+   * Since we iterate over all tasks in all stages that belong to group, we have to
+   * pass a previous status from previous stages, so the most severe status is selected
+   *
+   * @param counters   counts of resources that are in various states
+   * @param previousStatus previous status (from previous stages)
+   *
+   * @return display status based on statuses of tasks in different states. May be SKIPPED_FAILED, FAILED
+   * or null if there is no failures at all
+   */
+  private static HostRoleStatus calculateDisplayStatus(Map<HostRoleStatus, Integer> counters, HostRoleStatus previousStatus) {
+    return previousStatus != null && previousStatus.equals(HostRoleStatus.SKIPPED_FAILED) || counters.get(HostRoleStatus.SKIPPED_FAILED) > 0 ? HostRoleStatus.SKIPPED_FAILED :
+           previousStatus != null && previousStatus.equals(HostRoleStatus.FAILED) || counters.get(HostRoleStatus.FAILED) > 0 ? HostRoleStatus.FAILED :
+           null;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85647998/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
index c4dcd27..e7ca9aa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeGroupResourceProvider.java
@@ -59,6 +59,7 @@ public class UpgradeGroupResourceProvider extends AbstractControllerResourceProv
   protected static final String UPGRADE_GROUP_TITLE = "UpgradeGroup/title";
   protected static final String UPGRADE_GROUP_PROGRESS_PERCENT = "UpgradeGroup/progress_percent";
   protected static final String UPGRADE_GROUP_STATUS = "UpgradeGroup/status";
+  protected static final String UPGRADE_GROUP_DISPLAY_STATUS = "UpgradeGroup/display_status";
 
   protected static final String UPGRADE_GROUP_TOTAL_TASKS = "UpgradeGroup/total_task_count";
   protected static final String UPGRADE_GROUP_IN_PROGRESS_TASKS = "UpgradeGroup/in_progress_task_count";
@@ -85,6 +86,7 @@ public class UpgradeGroupResourceProvider extends AbstractControllerResourceProv
     PROPERTY_IDS.add(UPGRADE_GROUP_TITLE);
     PROPERTY_IDS.add(UPGRADE_GROUP_PROGRESS_PERCENT);
     PROPERTY_IDS.add(UPGRADE_GROUP_STATUS);
+    PROPERTY_IDS.add(UPGRADE_GROUP_DISPLAY_STATUS);
     PROPERTY_IDS.add(UPGRADE_GROUP_TOTAL_TASKS);
     PROPERTY_IDS.add(UPGRADE_GROUP_IN_PROGRESS_TASKS);
     PROPERTY_IDS.add(UPGRADE_GROUP_COMPLETED_TASKS);
@@ -221,6 +223,7 @@ public class UpgradeGroupResourceProvider extends AbstractControllerResourceProv
     setResourceProperty(upgradeGroup, UPGRADE_GROUP_COMPLETED_TASKS, completed, requestedIds);
 
     setResourceProperty(upgradeGroup, UPGRADE_GROUP_STATUS, stageStatus.getStatus(), requestedIds);
+    setResourceProperty(upgradeGroup, UPGRADE_GROUP_DISPLAY_STATUS, stageStatus.getDisplayStatus(), requestedIds);
     setResourceProperty(upgradeGroup, UPGRADE_GROUP_PROGRESS_PERCENT, stageStatus.getPercent(), requestedIds);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/85647998/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
index 4b8587f..22f43c2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
@@ -18,14 +18,11 @@
 package org.apache.ambari.server.controller.internal;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.easymock.EasyMock.*;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
@@ -35,8 +32,10 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.apache.ambari.server.orm.entities.StageEntity;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -440,6 +439,7 @@ public class CalculatedStatusTest {
     status = CalculatedStatus.statusFromStages(stages);
 
     assertEquals(HostRoleStatus.HOLDING, status.getStatus());
+    assertNull(status.getDisplayStatus());
     assertEquals(47.5, status.getPercent(), 0.1);
   }
 
@@ -498,20 +498,69 @@ public class CalculatedStatusTest {
     assertEquals(80d, calc.getPercent(), 0.1d);
   }
 
-
-
   /**
    * Tests that a SKIPPED_FAILED status means the stage has completed.
    *
    * @throws Exception
    */
   @Test
-  public void testSkippedFailed() throws Exception {
+  public void testSkippedFailed_Stage() throws Exception {
     Collection<HostRoleCommandEntity> tasks = getTaskEntities(HostRoleStatus.SKIPPED_FAILED);
 
     CalculatedStatus status = CalculatedStatus.statusFromTaskEntities(tasks, false);
 
-    assertEquals(HostRoleStatus.SKIPPED_FAILED, status.getStatus());
+    assertEquals(HostRoleStatus.COMPLETED, status.getStatus());
+  }
+
+  /**
+   * Tests that a SKIPPED_FAILED status of any task means the
+   * summary display status for is SKIPPED_FAILED, but summary status is
+   * still COMPLETED
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testSkippedFailed_UpgradeGroup() throws Exception {
+
+    final HostRoleCommandStatusSummaryDTO summary1 = createNiceMock(HostRoleCommandStatusSummaryDTO.class);
+    ArrayList<HostRoleStatus> taskStatuses1 = new ArrayList<HostRoleStatus>() {{
+      add(HostRoleStatus.COMPLETED);
+      add(HostRoleStatus.COMPLETED);
+      add(HostRoleStatus.COMPLETED);
+    }};
+
+    final HostRoleCommandStatusSummaryDTO summary2 = createNiceMock(HostRoleCommandStatusSummaryDTO.class);
+    ArrayList<HostRoleStatus> taskStatuses2 = new ArrayList<HostRoleStatus>() {{
+      add(HostRoleStatus.COMPLETED);
+      add(HostRoleStatus.SKIPPED_FAILED);
+      add(HostRoleStatus.COMPLETED);
+    }};
+
+    Map<Long, HostRoleCommandStatusSummaryDTO> stageDto = new HashMap<Long, HostRoleCommandStatusSummaryDTO>(){{
+        put(1l, summary1);
+        put(2l, summary2);
+      }};
+
+    Set<Long> stageIds = new HashSet<Long>() {{
+      add(1l);
+      add(2l);
+    }};
+
+    expect(summary1.getTaskTotal()).andReturn(taskStatuses1.size()).anyTimes();
+    expect(summary2.getTaskTotal()).andReturn(taskStatuses2.size()).anyTimes();
+
+    expect(summary1.isStageSkippable()).andReturn(true).anyTimes();
+    expect(summary2.isStageSkippable()).andReturn(true).anyTimes();
+
+    expect(summary1.getTaskStatuses()).andReturn(taskStatuses1).anyTimes();
+    expect(summary2.getTaskStatuses()).andReturn(taskStatuses2).anyTimes();
+
+    replay(summary1, summary2);
+
+    CalculatedStatus calc = CalculatedStatus.statusFromStageSummary(stageDto, stageIds);
+
+    assertEquals(HostRoleStatus.SKIPPED_FAILED, calc.getDisplayStatus());
+    assertEquals(HostRoleStatus.COMPLETED, calc.getStatus());
   }
 
   private Collection<HostRoleCommandEntity> getTaskEntities(HostRoleStatus... statuses) {