Browse Source

AMBARI-785. Action response unit test.

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1392770 13f79535-47bb-0310-9956-ffa450edef68
Jitendra Nath Pandey 13 years ago
parent
commit
a992578aaf

+ 2 - 0
AMBARI-666-CHANGES.txt

@@ -12,6 +12,8 @@ AMBARI-666 branch (unreleased changes)
 
 
   NEW FEATURES
   NEW FEATURES
 
 
+  AMBARI-785. Action response unit test. (jitendra)
+
   AMBARI-783. Fix guice injection in the server. (mahadev)
   AMBARI-783. Fix guice injection in the server. (mahadev)
 
 
   AMBARI-784. Add Resource download API on the server. (mahadev)
   AMBARI-784. Add Resource download API on the server. (mahadev)

+ 4 - 0
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessor.java

@@ -20,6 +20,7 @@ package org.apache.ambari.server.actionmanager;
 import java.util.List;
 import java.util.List;
 
 
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.Role;
+import org.apache.ambari.server.agent.CommandReport;
 
 
 public interface ActionDBAccessor {
 public interface ActionDBAccessor {
 
 
@@ -39,4 +40,7 @@ public interface ActionDBAccessor {
 
 
   public void persistActions(List<Stage> stages);
   public void persistActions(List<Stage> stages);
 
 
+  public void updateHostRoleState(String hostname, long requestId,
+      long stageId, String role, CommandReport report);
+
 }
 }

+ 8 - 0
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java

@@ -20,6 +20,7 @@ package org.apache.ambari.server.actionmanager;
 import java.util.List;
 import java.util.List;
 
 
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.Role;
+import org.apache.ambari.server.agent.CommandReport;
 
 
 public class ActionDBAccessorImpl implements ActionDBAccessor {
 public class ActionDBAccessorImpl implements ActionDBAccessor {
 
 
@@ -77,4 +78,11 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
     // TODO Auto-generated method stub
     // TODO Auto-generated method stub
 
 
   }
   }
+
+  @Override
+  public void updateHostRoleState(String hostname, long requestId,
+      long stageId, String role, CommandReport report) {
+    // TODO Auto-generated method stub
+    
+  }
 }
 }

+ 15 - 0
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBInMemoryImpl.java

@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.Role;
+import org.apache.ambari.server.agent.CommandReport;
 
 
 public class ActionDBInMemoryImpl implements ActionDBAccessor {
 public class ActionDBInMemoryImpl implements ActionDBAccessor {
 
 
@@ -88,4 +89,18 @@ public class ActionDBInMemoryImpl implements ActionDBAccessor {
       stageList.add(s);
       stageList.add(s);
     }
     }
   }
   }
+  @Override
+  public synchronized void updateHostRoleState(String hostname, long requestId,
+      long stageId, String role, CommandReport report) {
+    for (Stage s : stageList) {
+      for (HostRoleCommand r : s.getHostActions().get(hostname).getRoleCommands()) {
+        if (r.getRole().toString().equals(role)) {
+          r.setStatus(HostRoleStatus.valueOf(report.getStatus()));
+          r.setExitCode(report.getExitCode());
+          r.setStderr(report.getStdErr());
+          r.setStdout(report.getStdOut());
+        }
+      }
+    }
+  }
 }
 }

+ 18 - 9
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java

@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.ambari.server.agent.ActionQueue;
 import org.apache.ambari.server.agent.ActionQueue;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.state.live.Clusters;
 import org.apache.ambari.server.state.live.Clusters;
+import org.apache.ambari.server.utils.StageUtils;
 
 
 import com.google.inject.Inject;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.google.inject.Singleton;
@@ -61,22 +62,30 @@ public class ActionManager {
     db.persistActions(stages);
     db.persistActions(stages);
   }
   }
 
 
-  public List<Stage> getRequestStatus(String requestId) {
-    //fetch status from db
-    return null;
+  public List<Stage> getRequestStatus(long requestId) {
+    return db.getAllStages(requestId);
   }
   }
 
 
-  public Stage getActionStatus(String actionId) {
-    //fetch the action information from the db
-    return null;
+  public Stage getAction(long requestId, long stageId) {
+    return db.getAction(StageUtils.getActionId(requestId, stageId));
   }
   }
 
 
-  public void actionResponse(String hostname, List<CommandReport> report) {
+  public void actionResponse(String hostname, List<CommandReport> reports) {
     //persist the action response into the db.
     //persist the action response into the db.
+    for (CommandReport report : reports) {
+      String actionId = report.getActionId();
+      long [] requestStageIds = StageUtils.getRequestStage(actionId);
+      long requestId = requestStageIds[0];    
+      long stageId = requestStageIds[1];
+      db.updateHostRoleState(hostname, requestId, stageId, report.getRole(),
+          report);
+    }
   }
   }
 
 
   public void handleLostHost(String host) {
   public void handleLostHost(String host) {
-    // TODO Auto-generated method stub
-
+    //Do nothing, the task will timeout anyway.
+    //The actions can be failed faster as an optimization
+    //if action timeout happens to be much larger than
+    //heartbeat timeout.
   }
   }
 }
 }

+ 29 - 2
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java

@@ -17,19 +17,22 @@
  */
  */
 package org.apache.ambari.server.actionmanager;
 package org.apache.ambari.server.actionmanager;
 
 
-
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostEvent;
 import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostEvent;
 
 
 /**
 /**
  * This class encapsulates the information for an task on a host for a
  * This class encapsulates the information for an task on a host for a
  * particular role which action manager needs. It doesn't capture actual
  * particular role which action manager needs. It doesn't capture actual
- * command and parameters, but just the stuff enough for action manager.
+ * command and parameters, but just the stuff enough for action manager to
+ * track the request.
  * For the actual command refer {@link HostAction#commandToHost}
  * For the actual command refer {@link HostAction#commandToHost}
  */
  */
 public class HostRoleCommand {
 public class HostRoleCommand {
   private final Role role;
   private final Role role;
   private HostRoleStatus status = HostRoleStatus.PENDING;
   private HostRoleStatus status = HostRoleStatus.PENDING;
+  private String stdout = "";
+  private String stderr = "";
+  private int exitCode = 999; //Default is unknown
   private final ServiceComponentHostEvent event;
   private final ServiceComponentHostEvent event;
 
 
   public HostRoleCommand(Role role, ServiceComponentHostEvent event) {
   public HostRoleCommand(Role role, ServiceComponentHostEvent event) {
@@ -52,4 +55,28 @@ public class HostRoleCommand {
   void setStatus(HostRoleStatus status) {
   void setStatus(HostRoleStatus status) {
     this.status = status;
     this.status = status;
   }
   }
+
+  public String getStdout() {
+    return stdout;
+  }
+
+  public void setStdout(String stdout) {
+    this.stdout = stdout;
+  }
+
+  public String getStderr() {
+    return stderr;
+  }
+
+  public void setStderr(String stderr) {
+    this.stderr = stderr;
+  }
+
+  public int getExitCode() {
+    return exitCode;
+  }
+
+  public void setExitCode(int exitCode) {
+    this.exitCode = exitCode;
+  }
 }
 }

+ 2 - 1
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java

@@ -23,6 +23,7 @@ import java.util.TreeMap;
 
 
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.agent.AgentCommand;
 import org.apache.ambari.server.agent.AgentCommand;
+import org.apache.ambari.server.utils.StageUtils;
 
 
 //This class encapsulates the stage. The stage encapsulates all the information
 //This class encapsulates the stage. The stage encapsulates all the information
 //required to persist an action.
 //required to persist an action.
@@ -59,7 +60,7 @@ public class Stage {
   }
   }
 
 
   public String getActionId() {
   public String getActionId() {
-    return "" + requestId + "-" + stageId;
+    return StageUtils.getActionId(requestId, stageId);
   }
   }
 
 
   synchronized void addHostAction(String host, HostAction ha) {
   synchronized void addHostAction(String host, HostAction ha) {

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java

@@ -27,6 +27,8 @@ import javax.xml.bind.annotation.XmlType;
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {})
 @XmlType(name = "", propOrder = {})
 public class CommandReport {
 public class CommandReport {
+  @XmlElement
+  String role;
   @XmlElement
   @XmlElement
   String actionId;
   String actionId;
   @XmlElement
   @XmlElement
@@ -72,4 +74,20 @@ public class CommandReport {
   public void setStdOut(String stdout) {
   public void setStdOut(String stdout) {
     this.stdout = stdout;
     this.stdout = stdout;
   }
   }
+
+  public String getRole() {
+    return role;
+  }
+
+  public void setRole(String role) {
+    this.role = role;
+  }
+
+  public String getStatus() {
+    return status;
+  }
+
+  public void setStatus(String status) {
+    this.status = status;
+  }
 }
 }

+ 32 - 0
ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java

@@ -0,0 +1,32 @@
+/**
+ * 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.utils;
+
+public class StageUtils {
+  public static String getActionId(long requestId, long stageId) {
+    return requestId + "-" + stageId;
+  }
+
+  public static long[] getRequestStage(String actionId) {
+    String [] fields = actionId.split("-");
+    long[] requestStageIds = new long[2];
+    requestStageIds[0] = Long.parseLong(fields[0]);
+    requestStageIds[1] = Long.parseLong(fields[1]);
+    return requestStageIds;
+  }
+}

+ 72 - 0
ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java

@@ -0,0 +1,72 @@
+/**
+ * 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.actionmanager;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.agent.ActionQueue;
+import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.state.live.ClustersImpl;
+import org.apache.ambari.server.state.live.svccomphost.ServiceComponentHostStartEvent;
+import org.apache.ambari.server.utils.StageUtils;
+import org.junit.Test;
+
+public class TestActionManager {
+
+  private long requestId = 23;
+  private long stageId = 31;
+  
+  @Test
+  public void testActionResponse() {
+    ActionDBAccessor db = new ActionDBInMemoryImpl();
+    ActionManager am = new ActionManager(5000, 1200000, new ActionQueue(),
+        new ClustersImpl(), db);
+    String hostname = "host1";
+    populateActionDB(db, hostname);
+    List<CommandReport> reports = new ArrayList<CommandReport>();
+    CommandReport cr = new CommandReport();
+    cr.setActionId(StageUtils.getActionId(requestId, stageId));
+    cr.setRole("HBASE_MASTER");
+    cr.setStatus("COMPLETED");
+    cr.setExitCode(215);
+    reports.add(cr);
+    am.actionResponse(hostname, reports);
+    assertEquals(215, am.getAction(requestId, stageId).getHostAction(hostname)
+        .getRoleCommands().get(0).getExitCode());
+    assertEquals(HostRoleStatus.COMPLETED, am.getAction(requestId, stageId)
+        .getHostAction(hostname).getRoleCommands().get(0).getStatus());
+  }
+
+  private void populateActionDB(ActionDBAccessor db, String hostname) {
+    Stage s = new Stage(requestId, "/a/b", "cluster1");
+    s.setStageId(stageId);
+    HostAction ha = new HostAction(hostname);
+    HostRoleCommand cmd = new HostRoleCommand(Role.HBASE_MASTER,
+        new ServiceComponentHostStartEvent(Role.HBASE_MASTER.toString(),
+            hostname, System.currentTimeMillis()));
+    ha.addHostRoleCommand(cmd);
+    s.addHostAction(hostname, ha);
+    List<Stage> stages = new ArrayList<Stage>();
+    stages.add(s);
+    db.persistActions(stages);
+  }
+}