Browse Source

AMBARI-13974 - Retreiving Failed Service Checks Takes Too Long On Large Clusters (jonathanhurley)

Jonathan Hurley 9 years ago
parent
commit
0a5c9da1dd
15 changed files with 510 additions and 625 deletions
  1. 0 6
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessor.java
  2. 1 13
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
  3. 0 8
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
  4. 6 2
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/HostRoleCommand.java
  5. 5 19
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
  6. 55 82
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
  7. 0 48
      ambari-server/src/main/java/org/apache/ambari/server/controller/TaskStatusRequest.java
  8. 0 140
      ambari-server/src/main/java/org/apache/ambari/server/controller/TaskStatusResponse.java
  9. 96 105
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java
  10. 86 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
  11. 44 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity_.java
  12. 67 1
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity_.java
  13. 99 122
      ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
  14. 16 60
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java
  15. 35 19
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/TaskResourceProviderTest.java

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

@@ -161,12 +161,6 @@ public interface ActionDBAccessor {
    */
   public List<HostRoleCommand> getAllTasksByRequestIds(Collection<Long> requestIds);
 
-  /**
-   * Get a list of host role commands where the request id belongs to the input requestIds and
-   * the task id belongs to the input taskIds
-   */
-  public List<HostRoleCommand> getTasksByRequestAndTaskIds(Collection<Long> requestIds, Collection<Long> taskIds);
-
   /**
    * Given a list of task ids, get all the host role commands
    */

+ 1 - 13
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java

@@ -27,7 +27,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.eventbus.Subscribe;
 import org.apache.ambari.annotations.Experimental;
 import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
@@ -64,6 +63,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
+import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
@@ -605,18 +605,6 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
     );
   }
 
-  @Override
-  public List<HostRoleCommand> getTasksByRequestAndTaskIds(Collection<Long> requestIds, Collection<Long> taskIds) {
-    if (!requestIds.isEmpty() && !taskIds.isEmpty()) {
-      return getTasks(hostRoleCommandDAO.findTaskIdsByRequestAndTaskIds(requestIds, taskIds));
-
-    } else if (requestIds.isEmpty()) {
-      return getTasks(taskIds);
-    } else {
-      return getAllTasksByRequestIds(requestIds);
-    }
-  }
-
   @Override
   public List<HostRoleCommand> getTasks(Collection<Long> taskIds) {
     if (taskIds.isEmpty()) {

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

@@ -201,14 +201,6 @@ public class ActionManager {
     return db.getAllTasksByRequestIds(requestIds);
   }
 
-  public List<HostRoleCommand> getTasksByRequestAndTaskIds(Collection<Long> requestIds, Collection<Long> taskIds) {
-    // wrapping in new list as returned list may be Collections.emptyList() which doesn't support add()
-    List<HostRoleCommand> tasks = new ArrayList<HostRoleCommand>(db.getTasksByRequestAndTaskIds(requestIds, taskIds));
-    tasks.addAll(topologyManager.getTasks(requestIds));
-
-    return tasks;
-  }
-
   public Collection<HostRoleCommand> getTasks(Collection<Long> taskIds) {
     return db.getTasks(taskIds);
   }

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

@@ -139,8 +139,12 @@ public class HostRoleCommand {
     this.executionCommandDAO = executionCommandDAO;
 
     taskId = hostRoleCommandEntity.getTaskId();
-    stageId = hostRoleCommandEntity.getStage().getStageId();
-    requestId = hostRoleCommandEntity.getStage().getRequestId();
+
+    stageId = null != hostRoleCommandEntity.getStageId() ? hostRoleCommandEntity.getStageId()
+        : hostRoleCommandEntity.getStage().getStageId();
+
+    requestId = null != hostRoleCommandEntity.getRequestId() ? hostRoleCommandEntity.getRequestId()
+        : hostRoleCommandEntity.getStage().getRequestId();
 
     if (null != hostRoleCommandEntity.getHostEntity()) {
       hostId = hostRoleCommandEntity.getHostId();

+ 5 - 19
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java

@@ -18,12 +18,16 @@
 
 package org.apache.ambari.server.controller;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.RequestStageContainer;
 import org.apache.ambari.server.controller.metrics.timeline.cache.TimelineMetricCacheProvider;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
@@ -46,12 +50,6 @@ import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Management controller interface.
  */
@@ -165,18 +163,6 @@ public interface AmbariManagementController {
   public Set<ConfigurationResponse> getConfigurations(
       Set<ConfigurationRequest> requests) throws AmbariException;
 
-  /**
-   * Gets the task status identified by the given request objects.
-   *
-   * @param requests   the request objects
-   *
-   * @return  a set of task status responses
-   *
-   * @throws AmbariException if the configurations could not be read
-   */
-  public Set<TaskStatusResponse> getTaskStatus(Set<TaskStatusRequest> requests)
-      throws AmbariException;
-
   /**
    * Get service config version history
    * @param requests service config version requests

+ 55 - 82
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java

@@ -18,16 +18,49 @@
 
 package org.apache.ambari.server.controller;
 
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.GROUP_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MAX_DURATION_OF_RETRIES;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -139,48 +172,16 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.GrantedAuthority;
 
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.net.InetAddress;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.GROUP_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MAX_DURATION_OF_RETRIES;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
 
 @Singleton
 public class AmbariManagementControllerImpl implements AmbariManagementController {
@@ -726,8 +727,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       for(String passwordProperty : propertiesTypes.get(PropertyType.PASSWORD)) {
         if(requestProperties.containsKey(passwordProperty)) {
           String passwordPropertyValue = requestProperties.get(passwordProperty);
-          if (!SecretReference.isSecret(passwordPropertyValue))
+          if (!SecretReference.isSecret(passwordPropertyValue)) {
             continue;
+          }
           SecretReference ref = new SecretReference(passwordPropertyValue, cluster);
           String refValue = ref.getValue();
           requestProperties.put(passwordProperty, refValue);
@@ -3029,35 +3031,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     return response;
   }
 
-  @Override
-  public Set<TaskStatusResponse> getTaskStatus(Set<TaskStatusRequest> requests)
-      throws AmbariException {
-
-    Collection<Long> requestIds = new ArrayList<Long>();
-    Collection<Long> taskIds = new ArrayList<Long>();
-
-    for (TaskStatusRequest request : requests) {
-      if (request.getTaskId() != null) {
-        taskIds.add(request.getTaskId());
-      }
-      if (request.getRequestId() != null) {
-        requestIds.add(request.getRequestId());
-      }
-    }
-
-    Set<TaskStatusResponse> responses = new HashSet<TaskStatusResponse>();
-    for (HostRoleCommand command : actionManager.getTasksByRequestAndTaskIds(requestIds, taskIds)) {
-      TaskStatusResponse taskStatusResponse = new TaskStatusResponse(command);
-      responses.add(taskStatusResponse);
-    }
-
-    if (responses.size() == 0) {
-      throw new ObjectNotFoundException("Task resource doesn't exist.");
-    }
-
-    return responses;
-  }
-
   @Override
   public Set<ClusterResponse> getClusters(Set<ClusterRequest> requests) throws AmbariException {
     Set<ClusterResponse> response = new HashSet<ClusterResponse>();

+ 0 - 48
ambari-server/src/main/java/org/apache/ambari/server/controller/TaskStatusRequest.java

@@ -1,48 +0,0 @@
-/*
- * 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.controller;
-
-public class TaskStatusRequest {
-  protected Long requestId;
-  protected Long taskId;
-
-  public TaskStatusRequest() {
-  }
-
-  public TaskStatusRequest(Long requestId, Long taskId) {
-    this.requestId = requestId;
-    this.taskId = taskId;
-  }
-
-  public Long getRequestId() {
-    return requestId;
-  }
-
-  public void setRequestId(Long requestId) {
-    this.requestId = requestId;
-  }
-
-  public Long getTaskId() {
-    return taskId;
-  }
-
-  public void setTaskId(Long taskId) {
-    this.taskId = taskId;
-  }
-}

+ 0 - 140
ambari-server/src/main/java/org/apache/ambari/server/controller/TaskStatusResponse.java

@@ -1,140 +0,0 @@
-/*
- * 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.controller;
-
-import org.apache.ambari.server.actionmanager.HostRoleCommand;
-
-public class TaskStatusResponse extends ShortTaskStatus {
-  private long requestId;
-  private int exitCode;
-  private String stderr;
-  private String stdout;
-  private String structuredOut;
-  private String commandDetail;
-  private long startTime;
-  private Long endTime;
-  private short attemptCount;
-
-  public TaskStatusResponse() {
-  }
-
-  public TaskStatusResponse(long requestId,
-                            int taskId, long stageId, String hostName, String role, String command, String status,
-                            int exitCode, String stderr, String stdout, long startTime, short attemptCount,
-                            String commandDetail, String customCommandName, String outputLog, String errorLog) {
-    super(taskId, stageId, hostName, role, command, status, customCommandName, outputLog, errorLog);
-    this.requestId = requestId;
-    this.exitCode = exitCode;
-    this.stderr = stderr;
-    this.stdout = stdout;
-    this.startTime = startTime;
-    this.attemptCount = attemptCount;
-    this.commandDetail = commandDetail;
-  }
-
-  public TaskStatusResponse(HostRoleCommand hostRoleCommand) {
-    super(hostRoleCommand);
-    this.requestId = hostRoleCommand.getRequestId();
-    this.exitCode = hostRoleCommand.getExitCode();
-    this.stderr = hostRoleCommand.getStderr();
-    this.stdout = hostRoleCommand.getStdout();
-    this.startTime = hostRoleCommand.getStartTime();
-    this.attemptCount = hostRoleCommand.getAttemptCount();
-    this.structuredOut = hostRoleCommand.getStructuredOut();
-    this.endTime = hostRoleCommand.getEndTime();
-    this.commandDetail = hostRoleCommand.getCommandDetail();
-  }
-
-  public long getRequestId() {
-    return requestId;
-  }
-
-  public void setRequestId(long requestId) {
-    this.requestId = requestId;
-  }
-
-  public int getExitCode() {
-    return exitCode;
-  }
-
-  public void setExitCode(int exitCode) {
-    this.exitCode = exitCode;
-  }
-
-  public String getStderr() {
-    return stderr;
-  }
-
-  public void setStderr(String stderr) {
-    this.stderr = stderr;
-  }
-
-  public String getStdout() {
-    return stdout;
-  }
-
-  public void setStdout(String stdout) {
-    this.stdout = stdout;
-  }
-
-  public long getStartTime() {
-    return startTime;
-  }
-
-  public void setStartTime(long startTime) {
-    this.startTime = startTime;
-  }
-
-  public short getAttemptCount() {
-    return attemptCount;
-  }
-
-  public void setAttemptCount(short attemptCount) {
-    this.attemptCount = attemptCount;
-  }
-
-  public String getStructuredOut() {
-    return structuredOut;
-  }
-
-  public void setStructuredOut(String structuredOut) {
-    this.structuredOut = structuredOut;
-  }
-
-  public Long getEndTime() {
-    return endTime;
-  }
-
-  public void setEndTime(Long endTime) {
-    this.endTime = endTime;
-  }
-
-  public String getCommandDetail() {
-    return commandDetail;
-  }
-
-  public void setCommandDetail(String commandDetail) {
-    this.commandDetail = commandDetail;
-  }
-
-  @Override
-  public String toString() {
-      return super.toString();
-  }
-}

+ 96 - 105
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TaskResourceProvider.java

@@ -18,15 +18,16 @@
 package org.apache.ambari.server.controller.internal;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.TaskStatusRequest;
-import org.apache.ambari.server.controller.TaskStatusResponse;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
@@ -36,40 +37,57 @@ import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.codehaus.jackson.map.ObjectMapper;
 
+import com.google.inject.Inject;
+
 /**
  * Resource provider for task resources.
  */
-class TaskResourceProvider extends AbstractControllerResourceProvider {
+@StaticallyInject
+public class TaskResourceProvider extends AbstractControllerResourceProvider {
 
   // ----- Property ID constants ---------------------------------------------
 
   // Tasks
-  protected static final String TASK_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Tasks", "cluster_name");
-  protected static final String TASK_REQUEST_ID_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "request_id");
-  protected static final String TASK_ID_PROPERTY_ID           = PropertyHelper.getPropertyId("Tasks", "id");
-  protected static final String TASK_STAGE_ID_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "stage_id");
-  protected static final String TASK_HOST_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("Tasks", "host_name");
-  protected static final String TASK_ROLE_PROPERTY_ID         = PropertyHelper.getPropertyId("Tasks", "role");
-  protected static final String TASK_COMMAND_PROPERTY_ID      = PropertyHelper.getPropertyId("Tasks", "command");
-  protected static final String TASK_STATUS_PROPERTY_ID       = PropertyHelper.getPropertyId("Tasks", "status");
-  protected static final String TASK_EXIT_CODE_PROPERTY_ID    = PropertyHelper.getPropertyId("Tasks", "exit_code");
-  protected static final String TASK_STDERR_PROPERTY_ID       = PropertyHelper.getPropertyId("Tasks", "stderr");
-  protected static final String TASK_STOUT_PROPERTY_ID        = PropertyHelper.getPropertyId("Tasks", "stdout");
-  protected static final String TASK_OUTPUTLOG_PROPERTY_ID    = PropertyHelper.getPropertyId("Tasks", "output_log");
-  protected static final String TASK_ERRORLOG_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "error_log");
-  protected static final String TASK_STRUCT_OUT_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "structured_out");
-  protected static final String TASK_START_TIME_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "start_time");
-  protected static final String TASK_END_TIME_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "end_time");
-  protected static final String TASK_ATTEMPT_CNT_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "attempt_cnt");
-  protected static final String TASK_COMMAND_DET_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "command_detail");
-  protected static final String TASK_CUST_CMD_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "custom_command_name");
+  public static final String TASK_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Tasks", "cluster_name");
+  public static final String TASK_REQUEST_ID_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "request_id");
+  public static final String TASK_ID_PROPERTY_ID           = PropertyHelper.getPropertyId("Tasks", "id");
+  public static final String TASK_STAGE_ID_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "stage_id");
+  public static final String TASK_HOST_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("Tasks", "host_name");
+  public static final String TASK_ROLE_PROPERTY_ID         = PropertyHelper.getPropertyId("Tasks", "role");
+  public static final String TASK_COMMAND_PROPERTY_ID      = PropertyHelper.getPropertyId("Tasks", "command");
+  public static final String TASK_STATUS_PROPERTY_ID       = PropertyHelper.getPropertyId("Tasks", "status");
+  public static final String TASK_EXIT_CODE_PROPERTY_ID    = PropertyHelper.getPropertyId("Tasks", "exit_code");
+  public static final String TASK_STDERR_PROPERTY_ID       = PropertyHelper.getPropertyId("Tasks", "stderr");
+  public static final String TASK_STOUT_PROPERTY_ID        = PropertyHelper.getPropertyId("Tasks", "stdout");
+  public static final String TASK_OUTPUTLOG_PROPERTY_ID    = PropertyHelper.getPropertyId("Tasks", "output_log");
+  public static final String TASK_ERRORLOG_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "error_log");
+  public static final String TASK_STRUCT_OUT_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "structured_out");
+  public static final String TASK_START_TIME_PROPERTY_ID   = PropertyHelper.getPropertyId("Tasks", "start_time");
+  public static final String TASK_END_TIME_PROPERTY_ID     = PropertyHelper.getPropertyId("Tasks", "end_time");
+  public static final String TASK_ATTEMPT_CNT_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "attempt_cnt");
+  public static final String TASK_COMMAND_DET_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "command_detail");
+  public static final String TASK_CUST_CMD_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("Tasks", "custom_command_name");
 
   private static Set<String> pkPropertyIds =
       new HashSet<String>(Arrays.asList(new String[]{
           TASK_ID_PROPERTY_ID}));
 
+  /**
+   * Used for querying tasks.
+   */
+  @Inject
+  protected static HostRoleCommandDAO s_dao;
+
+  /**
+   * Used for constructing instances of {@link HostRoleCommand} from {@link HostRoleCommandEntity}.
+   */
+  @Inject
+  private static HostRoleCommandFactory s_hostRoleCommandFactory;
+
   /**
    * Thread-safe Jackson JSON mapper.
    */
@@ -97,101 +115,89 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
     throw new UnsupportedOperationException("Not currently supported.");
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public Set<Resource> getResources(Request request, Predicate predicate)
       throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
 
+    Set<Resource> results = new LinkedHashSet<Resource>();
     Set<String> requestedIds = getRequestPropertyIds(request, predicate);
 
-    Map<String, Set<TaskStatusRequest>> requestsMap = new HashMap<String, Set<TaskStatusRequest>>();
+    List<HostRoleCommandEntity> entities = s_dao.findAll(request, predicate);
+    LOG.debug("Retrieved {} commands for request {}", entities.size(), request);
 
+    // !!! getting the cluster name out of the request property maps is a little
+    // hacky since there could be a different request per cluster name; however
+    // nobody is making task requests across clusters. Overall, this loop could
+    // be called multiple times when using predicates like
+    // tasks/Tasks/status.in(FAILED,ABORTED,TIMEDOUT) which would unnecessarily
+    // make the same call to the API over and over
+    String clusterName = null;
     for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
-      String clusterName = (String) propertyMap.get(TASK_CLUSTER_NAME_PROPERTY_ID);
-
-      Set<TaskStatusRequest> requests = requestsMap.get(clusterName);
-      if (requests == null) {
-        requests = new HashSet<TaskStatusRequest>();
-        requestsMap.put(clusterName, requests);
-      }
-      requests.add(getRequest(propertyMap));
+      clusterName = (String) propertyMap.get(TASK_CLUSTER_NAME_PROPERTY_ID);
     }
 
-    Set<Resource> resources = null;
-
-    for (Map.Entry<String, Set<TaskStatusRequest>> entry : requestsMap.entrySet()) {
+    // convert each entity into a response
+    for (HostRoleCommandEntity entity : entities) {
+      Resource resource = new ResourceImpl(Resource.Type.Task);
 
-      final Set<TaskStatusRequest> requests = entry.getValue();
-
-      Set<TaskStatusResponse> responses = getResources(new Command<Set<TaskStatusResponse>>() {
-        @Override
-        public Set<TaskStatusResponse> invoke() throws AmbariException {
-          return getManagementController().getTaskStatus(requests);
-        }
-      });
+      // !!! shocked this isn't broken.  the key can be null for non-cluster tasks
+      if (null != clusterName) {
+        setResourceProperty(resource, TASK_CLUSTER_NAME_PROPERTY_ID, clusterName, requestedIds);
+      }
 
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Printing size of responses " + responses.size());
-        for (TaskStatusResponse response : responses) {
-          LOG.debug("Printing response from management controller "
-              + response.toString());
-        }
+      HostRoleCommand hostRoleCommand = s_hostRoleCommandFactory.createExisting(entity);
+
+      setResourceProperty(resource, TASK_REQUEST_ID_PROPERTY_ID, hostRoleCommand.getRequestId(), requestedIds);
+      setResourceProperty(resource, TASK_ID_PROPERTY_ID, hostRoleCommand.getTaskId(), requestedIds);
+      setResourceProperty(resource, TASK_STAGE_ID_PROPERTY_ID, hostRoleCommand.getStageId(), requestedIds);
+      setResourceProperty(resource, TASK_HOST_NAME_PROPERTY_ID, hostRoleCommand.getHostName(), requestedIds);
+      setResourceProperty(resource, TASK_ROLE_PROPERTY_ID, hostRoleCommand.getRole().toString(), requestedIds);
+      setResourceProperty(resource, TASK_COMMAND_PROPERTY_ID, hostRoleCommand.getRoleCommand(), requestedIds);
+      setResourceProperty(resource, TASK_STATUS_PROPERTY_ID, hostRoleCommand.getStatus(), requestedIds);
+      setResourceProperty(resource, TASK_EXIT_CODE_PROPERTY_ID, hostRoleCommand.getExitCode(), requestedIds);
+      setResourceProperty(resource, TASK_STDERR_PROPERTY_ID, hostRoleCommand.getStderr(), requestedIds);
+      setResourceProperty(resource, TASK_STOUT_PROPERTY_ID, hostRoleCommand.getStdout(), requestedIds);
+      setResourceProperty(resource, TASK_OUTPUTLOG_PROPERTY_ID, hostRoleCommand.getOutputLog(), requestedIds);
+      setResourceProperty(resource, TASK_ERRORLOG_PROPERTY_ID, hostRoleCommand.getErrorLog(), requestedIds);
+      setResourceProperty(resource, TASK_STRUCT_OUT_PROPERTY_ID, parseStructuredOutput(hostRoleCommand.getStructuredOut()), requestedIds);
+      setResourceProperty(resource, TASK_START_TIME_PROPERTY_ID, hostRoleCommand.getStartTime(), requestedIds);
+      setResourceProperty(resource, TASK_END_TIME_PROPERTY_ID, hostRoleCommand.getEndTime(), requestedIds);
+      setResourceProperty(resource, TASK_ATTEMPT_CNT_PROPERTY_ID, hostRoleCommand.getAttemptCount(), requestedIds);
+
+      if (hostRoleCommand.getCustomCommandName() != null) {
+        setResourceProperty(resource, TASK_CUST_CMD_NAME_PROPERTY_ID, hostRoleCommand.getCustomCommandName(), requestedIds);
       }
 
-      resources = new HashSet<Resource>();
-      for (TaskStatusResponse response : responses) {
-        Resource resource = new ResourceImpl(Resource.Type.Task);
-
-        // !!! shocked this isn't broken.  the key can be null for non-cluster tasks
-        if (null != entry.getKey())
-          setResourceProperty(resource, TASK_CLUSTER_NAME_PROPERTY_ID, entry.getKey(), requestedIds);  
-        
-        setResourceProperty(resource, TASK_REQUEST_ID_PROPERTY_ID, response.getRequestId(), requestedIds);
-        setResourceProperty(resource, TASK_ID_PROPERTY_ID, response.getTaskId(), requestedIds);
-        setResourceProperty(resource, TASK_STAGE_ID_PROPERTY_ID, response.getStageId(), requestedIds);
-        setResourceProperty(resource, TASK_HOST_NAME_PROPERTY_ID, response.getHostName(), requestedIds);
-        setResourceProperty(resource, TASK_ROLE_PROPERTY_ID, response.getRole(), requestedIds);
-        setResourceProperty(resource, TASK_COMMAND_PROPERTY_ID, response.getCommand(), requestedIds);
-        setResourceProperty(resource, TASK_STATUS_PROPERTY_ID, response.getStatus(), requestedIds);
-        setResourceProperty(resource, TASK_EXIT_CODE_PROPERTY_ID, response.getExitCode(), requestedIds);
-        setResourceProperty(resource, TASK_STDERR_PROPERTY_ID, response.getStderr(), requestedIds);
-        setResourceProperty(resource, TASK_STOUT_PROPERTY_ID, response.getStdout(), requestedIds);
-        setResourceProperty(resource, TASK_OUTPUTLOG_PROPERTY_ID, response.getOutputLog(), requestedIds);
-        setResourceProperty(resource, TASK_ERRORLOG_PROPERTY_ID, response.getErrorLog(), requestedIds);
-        setResourceProperty(resource, TASK_STRUCT_OUT_PROPERTY_ID, parseStructuredOutput(response.getStructuredOut()), requestedIds);
-        setResourceProperty(resource, TASK_START_TIME_PROPERTY_ID, response.getStartTime(), requestedIds);
-        setResourceProperty(resource, TASK_END_TIME_PROPERTY_ID, response.getEndTime(), requestedIds);
-        setResourceProperty(resource, TASK_ATTEMPT_CNT_PROPERTY_ID, response.getAttemptCount(), requestedIds);
-
-        if (response.getCustomCommandName() != null) {
-          setResourceProperty(resource, TASK_CUST_CMD_NAME_PROPERTY_ID, response.getCustomCommandName(), requestedIds);
-        }
-
-        if (response.getCommandDetail() == null) {
-          setResourceProperty(resource, TASK_COMMAND_DET_PROPERTY_ID,
-              String.format("%s %s", response.getRole(), response.getCommand()), requestedIds);
-        } else {
-          setResourceProperty(resource, TASK_COMMAND_DET_PROPERTY_ID, response.getCommandDetail(), requestedIds);
-        }
-
-        resources.add(resource);
+      if (hostRoleCommand.getCommandDetail() == null) {
+        setResourceProperty(resource, TASK_COMMAND_DET_PROPERTY_ID,
+            String.format("%s %s", hostRoleCommand.getRole().toString(), hostRoleCommand.getRoleCommand()), requestedIds);
+      } else {
+        setResourceProperty(resource, TASK_COMMAND_DET_PROPERTY_ID, hostRoleCommand.getCommandDetail(), requestedIds);
       }
+
+      results.add(resource);
     }
-    return resources;
+
+    return results;
   }
 
   /**
    * Converts the specified JSON string into a {@link Map}. For now, use Jackson
    * instead of gson since none of the integers will convert properly without a
    * well-defined first-class object to map to.
-   * 
+   *
    * @param structuredOutput
    *          the JSON string to convert.
    * @return the converted JSON as key-value pairs, or {@code null} if an
    *         exception was encountered or if the JSON string was empty.
    */
   Map<?, ?> parseStructuredOutput(String structuredOutput) {
-    if (null == structuredOutput || structuredOutput.isEmpty())
+    if (null == structuredOutput || structuredOutput.isEmpty()) {
       return null;
+    }
 
     Map<?, ?> result = null;
 
@@ -221,19 +227,4 @@ class TaskResourceProvider extends AbstractControllerResourceProvider {
   protected Set<String> getPKPropertyIds() {
     return pkPropertyIds;
   }
-
-  /**
-   * Get a component request object from a map of property values.
-   *
-   * @param properties  the predicate
-   *
-   * @return the component request object
-   */
-  private TaskStatusRequest getRequest(Map<String, Object> properties) {
-    String taskId = (String) properties.get(TASK_ID_PROPERTY_ID);
-    Long task_id = (taskId == null? null: Long.valueOf(taskId));
-    return new TaskStatusRequest(
-        Long.valueOf((String) properties.get(TASK_REQUEST_ID_PROPERTY_ID)),
-        task_id);
-  }
 }

+ 86 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java

@@ -31,12 +31,23 @@ import java.util.Map;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Order;
+import javax.persistence.metamodel.SingularAttribute;
 
 import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.api.query.JpaPredicateVisitor;
+import org.apache.ambari.server.api.query.JpaSortBuilder;
+import org.apache.ambari.server.controller.spi.PageRequest;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.SortRequest;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity_;
 import org.apache.ambari.server.orm.entities.StageEntity;
 
 import com.google.common.collect.Lists;
@@ -525,4 +536,79 @@ public class HostRoleCommandDAO {
       merge(task);
     }
   }
+
+  /**
+   * Finds all {@link HostRoleCommandEntity} that match the provided predicate.
+   * This method will make JPA do the heavy lifting of providing a slice of the
+   * result set.
+   *
+   * @param request
+   * @return
+   */
+  @RequiresSession
+  public List<HostRoleCommandEntity> findAll(Request request, Predicate predicate) {
+    EntityManager entityManager = entityManagerProvider.get();
+
+    // convert the Ambari predicate into a JPA predicate
+    HostRoleCommandPredicateVisitor visitor = new HostRoleCommandPredicateVisitor();
+    PredicateHelper.visit(predicate, visitor);
+
+    CriteriaQuery<HostRoleCommandEntity> query = visitor.getCriteriaQuery();
+    javax.persistence.criteria.Predicate jpaPredicate = visitor.getJpaPredicate();
+
+    if (null != jpaPredicate) {
+      query.where(jpaPredicate);
+    }
+
+    // sorting
+    SortRequest sortRequest = request.getSortRequest();
+    if (null != sortRequest) {
+      JpaSortBuilder<HostRoleCommandEntity> sortBuilder = new JpaSortBuilder<HostRoleCommandEntity>();
+      List<Order> sortOrders = sortBuilder.buildSortOrders(sortRequest, visitor);
+      query.orderBy(sortOrders);
+    }
+
+    TypedQuery<HostRoleCommandEntity> typedQuery = entityManager.createQuery(query);
+
+    // pagination
+    PageRequest pagination = request.getPageRequest();
+    if (null != pagination) {
+      typedQuery.setFirstResult(pagination.getOffset());
+      typedQuery.setMaxResults(pagination.getPageSize());
+    }
+
+    return daoUtils.selectList(typedQuery);
+  }
+
+  /**
+   * The {@link HostRoleCommandPredicateVisitor} is used to convert an Ambari
+   * {@link Predicate} into a JPA {@link javax.persistence.criteria.Predicate}.
+   */
+  private final class HostRoleCommandPredicateVisitor
+      extends JpaPredicateVisitor<HostRoleCommandEntity> {
+
+    /**
+     * Constructor.
+     *
+     */
+    public HostRoleCommandPredicateVisitor() {
+      super(entityManagerProvider.get(), HostRoleCommandEntity.class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<HostRoleCommandEntity> getEntityClass() {
+      return HostRoleCommandEntity.class;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<? extends SingularAttribute<?, ?>> getPredicateMapping(String propertyId) {
+      return HostRoleCommandEntity_.getPredicateMapping().get(propertyId);
+    }
+  }
 }

+ 44 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity_.java

@@ -0,0 +1,44 @@
+/**
+ * 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.orm.entities;
+
+import javax.persistence.metamodel.SingularAttribute;
+
+/**
+ * This class exists so that JPQL can use static singular attributes that are
+ * strongly typed as opposed to Java reflection like HostEntity.get("fieldname")
+ */
+@javax.persistence.metamodel.StaticMetamodel(HostEntity.class)
+public class HostEntity_ {
+  public static volatile SingularAttribute<HostEntity, Long> hostId;
+  public static volatile SingularAttribute<HostEntity, String> hostName;
+  public static volatile SingularAttribute<HostEntity, String> ipv4;
+  public static volatile SingularAttribute<HostEntity, String> ipv6;
+  public static volatile SingularAttribute<HostEntity, String> publicHostName;
+  public static volatile SingularAttribute<HostEntity, Long> totalMem;
+  public static volatile SingularAttribute<HostEntity, Integer> cpuCount;
+  public static volatile SingularAttribute<HostEntity, Integer> phCpuCount;
+  public static volatile SingularAttribute<HostEntity, String> cpuInfo;
+  public static volatile SingularAttribute<HostEntity, String> osArch;
+  public static volatile SingularAttribute<HostEntity, String> osInfo;
+  public static volatile SingularAttribute<HostEntity, String> discoveryStatus;
+  public static volatile SingularAttribute<HostEntity, Long> lastRegistrationTime;
+  public static volatile SingularAttribute<HostEntity, String> rackInfo;
+  public static volatile SingularAttribute<HostEntity, String> hostAttributes;
+}

+ 67 - 1
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity_.java

@@ -18,8 +18,17 @@
 
 package org.apache.ambari.server.orm.entities;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import javax.persistence.metamodel.SingularAttribute;
 
+import org.apache.ambari.server.controller.internal.TaskResourceProvider;
+import org.apache.ambari.server.controller.spi.Predicate;
+
 
 /**
  * This class exists so that JPQL can use static singular attributes that are strongly typed
@@ -30,7 +39,7 @@ public class HostRoleCommandEntity_ {
   public static volatile SingularAttribute<HostRoleCommandEntity, Long> taskId;
   public static volatile SingularAttribute<HostRoleCommandEntity, Long> requestId;
   public static volatile SingularAttribute<HostRoleCommandEntity, Long> stageId;
-  public static volatile SingularAttribute<HostRoleCommandEntity, String> hostName;
+  public static volatile SingularAttribute<HostRoleCommandEntity, Long> hostId;
   public static volatile SingularAttribute<HostRoleCommandEntity, String> role;
   public static volatile SingularAttribute<HostRoleCommandEntity, String> event;
   public static volatile SingularAttribute<HostRoleCommandEntity, Integer> exitcode;
@@ -47,5 +56,62 @@ public class HostRoleCommandEntity_ {
   public static volatile SingularAttribute<HostRoleCommandEntity, String> roleCommand;
   public static volatile SingularAttribute<HostRoleCommandEntity, String> commandDetail;
   public static volatile SingularAttribute<HostRoleCommandEntity, String> customCommandName;
+  public static volatile SingularAttribute<HostRoleCommandEntity, HostEntity> host;
+
+  /**
+   * Gets a mapping of between a resource provider property, like
+   * {@link TaskResourceProvider#TASK_ID_PROPERTY_ID} to a metamodel
+   * {@link SingularAttribute}.
+   * <p/>
+   * This is used when converting an Ambari {@link Predicate} into a JPA
+   * {@link javax.persistence.criteria.Predicate} and we need a type-safe
+   * conversion between "category/property" and JPA field names.
+   * <p/>
+   * Multiple {@link SingularAttribute} instances can be chained together in
+   * order to provide an {@code entity.subEntity.field} reference.
+   *
+   * @return
+   */
+  public static Map<String, List<? extends SingularAttribute<?, ?>>> getPredicateMapping() {
+    Map<String, List<? extends SingularAttribute<?, ?>>> mapping = new HashMap<String, List<? extends SingularAttribute<?, ?>>>();
+
+    mapping.put(TaskResourceProvider.TASK_ID_PROPERTY_ID,
+        Collections.singletonList(taskId));
+
+    mapping.put(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID,
+        Collections.singletonList(requestId));
+
+    mapping.put(TaskResourceProvider.TASK_STAGE_ID_PROPERTY_ID,
+        Collections.singletonList(stageId));
+
+    mapping.put(TaskResourceProvider.TASK_HOST_NAME_PROPERTY_ID,
+        Arrays.asList(host, HostEntity_.hostId));
+
+    mapping.put(TaskResourceProvider.TASK_ROLE_PROPERTY_ID,
+        Collections.singletonList(role));
+
+    mapping.put(TaskResourceProvider.TASK_EXIT_CODE_PROPERTY_ID,
+        Collections.singletonList(exitcode));
+
+    mapping.put(TaskResourceProvider.TASK_STATUS_PROPERTY_ID,
+        Collections.singletonList(status));
+
+    mapping.put(TaskResourceProvider.TASK_START_TIME_PROPERTY_ID,
+        Collections.singletonList(startTime));
+
+    mapping.put(TaskResourceProvider.TASK_END_TIME_PROPERTY_ID,
+        Collections.singletonList(endTime));
+
+    mapping.put(TaskResourceProvider.TASK_ATTEMPT_CNT_PROPERTY_ID,
+        Collections.singletonList(attemptCount));
+
+    mapping.put(TaskResourceProvider.TASK_COMMAND_PROPERTY_ID,
+        Collections.singletonList(roleCommand));
+
+    mapping.put(TaskResourceProvider.TASK_CUST_CMD_NAME_PROPERTY_ID,
+        Collections.singletonList(customCommandName));
+
+    return mapping;
+  }
 }
 

+ 99 - 122
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java

@@ -18,13 +18,41 @@
 
 package org.apache.ambari.server.controller;
 
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.persist.PersistService;
-import junit.framework.Assert;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.StringReader;
+import java.lang.reflect.Type;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -54,7 +82,11 @@ import org.apache.ambari.server.controller.internal.HostResourceProviderTest;
 import org.apache.ambari.server.controller.internal.RequestOperationLevel;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 import org.apache.ambari.server.controller.internal.ServiceResourceProviderTest;
+import org.apache.ambari.server.controller.internal.TaskResourceProvider;
+import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
@@ -63,10 +95,12 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.OrmTestHelper;
 import org.apache.ambari.server.orm.dao.ExecutionCommandDAO;
 import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
 import org.apache.ambari.server.orm.dao.WidgetDAO;
 import org.apache.ambari.server.orm.dao.WidgetLayoutDAO;
 import org.apache.ambari.server.orm.entities.ExecutionCommandEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.apache.ambari.server.orm.entities.WidgetEntity;
 import org.apache.ambari.server.orm.entities.WidgetLayoutEntity;
 import org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity;
@@ -119,39 +153,14 @@ import org.junit.rules.ExpectedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.persistence.EntityManager;
-import java.io.StringReader;
-import java.lang.reflect.Type;
-import java.net.ConnectException;
-import java.net.MalformedURLException;
-import java.net.UnknownHostException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
 
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import junit.framework.Assert;
 
 public class AmbariManagementControllerTest {
 
@@ -200,6 +209,7 @@ public class AmbariManagementControllerTest {
   private OrmTestHelper helper;
   private StageFactory stageFactory;
   private HostDAO hostDAO;
+  private HostRoleCommandDAO hostRoleCommandDAO;
   private TopologyManager topologyManager;
 
   @Rule
@@ -229,7 +239,8 @@ public class AmbariManagementControllerTest {
     helper = injector.getInstance(OrmTestHelper.class);
     stageFactory = injector.getInstance(StageFactory.class);
     hostDAO = injector.getInstance(HostDAO.class);
-     topologyManager = injector.getInstance(TopologyManager.class);
+    hostRoleCommandDAO = injector.getInstance(HostRoleCommandDAO.class);
+    topologyManager = injector.getInstance(TopologyManager.class);
     StageUtils.setTopologyManager(topologyManager);
     ActionManager.setTopologyManager(topologyManager);
   }
@@ -1994,24 +2005,25 @@ public class AmbariManagementControllerTest {
       }
     }
 
-    Set<TaskStatusRequest> taskRequests = new HashSet<TaskStatusRequest>();
-    TaskStatusRequest t1, t2;
-    t1 = new TaskStatusRequest();
-    t2 = new TaskStatusRequest();
-    t1.setRequestId(trackAction.getRequestId());
-    taskRequests.add(t1);
-    Set<TaskStatusResponse> taskResponses =
-        controller.getTaskStatus(taskRequests);
-    Assert.assertEquals(5, taskResponses.size());
-
-    t1.setTaskId(1L);
-    t2.setRequestId(trackAction.getRequestId());
-    t2.setTaskId(2L);
-    taskRequests.clear();
-    taskRequests.add(t1);
-    taskRequests.add(t2);
-    taskResponses = controller.getTaskStatus(taskRequests);
-    Assert.assertEquals(2, taskResponses.size());
+    org.apache.ambari.server.controller.spi.Request request = PropertyHelper.getReadRequest(
+        TaskResourceProvider.TASK_CLUSTER_NAME_PROPERTY_ID,
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID,
+        TaskResourceProvider.TASK_STAGE_ID_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(
+            trackAction.getRequestId()).toPredicate();
+
+    List<HostRoleCommandEntity> entities = hostRoleCommandDAO.findAll(request, predicate);
+    Assert.assertEquals(5, entities.size());
+
+    predicate = new PredicateBuilder().property(
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(
+            trackAction.getRequestId()).and().property(
+                TaskResourceProvider.TASK_ID_PROPERTY_ID).equals(1L).toPredicate();
+
+    entities = hostRoleCommandDAO.findAll(request, predicate);
+    Assert.assertEquals(1, entities.size());
 
     // manually change live state to installed as no running action manager
     for (ServiceComponent sc :
@@ -8094,76 +8106,41 @@ public class AmbariManagementControllerTest {
     request = new Request(stages, clusters);
     actionDB.persistActions(request);
 
+    org.apache.ambari.server.controller.spi.Request spiRequest = PropertyHelper.getReadRequest(
+        TaskResourceProvider.TASK_CLUSTER_NAME_PROPERTY_ID,
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID,
+        TaskResourceProvider.TASK_STAGE_ID_PROPERTY_ID);
 
-    Set<TaskStatusRequest> taskStatusRequests;
-    Set<TaskStatusResponse> taskStatusResponses;
+    // request ID 1 has 3 tasks
+    Predicate predicate = new PredicateBuilder().property(
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(requestId1).toPredicate();
 
-    //check count of tasks by requestId1
-    taskStatusRequests = new HashSet<TaskStatusRequest>(){
-      {
-        add(new TaskStatusRequest(requestId1, null));
-      }
-    };
-    taskStatusResponses = controller.getTaskStatus(taskStatusRequests);
-    assertEquals(3, taskStatusResponses.size());
+    List<HostRoleCommandEntity> entities = hostRoleCommandDAO.findAll(spiRequest, predicate);
+    Assert.assertEquals(3, entities.size());
 
-    //check a taskId that requested by requestId1 and task id
-    taskStatusRequests = new HashSet<TaskStatusRequest>(){
-      {
-        add(new TaskStatusRequest(requestId1, 2L));
-      }
-    };
-    taskStatusResponses = controller.getTaskStatus(taskStatusRequests);
-    assertEquals(1, taskStatusResponses.size());
-    assertEquals(2L, taskStatusResponses.iterator().next().getTaskId());
+    // request just a task by ID
+    predicate = new PredicateBuilder().property(
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(requestId1).and().property(
+            TaskResourceProvider.TASK_ID_PROPERTY_ID).equals(2L).toPredicate();
 
-    //check count of tasks by requestId2
-    taskStatusRequests = new HashSet<TaskStatusRequest>(){
-      {
-        add(new TaskStatusRequest(requestId2, null));
-      }
-    };
-    taskStatusResponses = controller.getTaskStatus(taskStatusRequests);
-    assertEquals(2, taskStatusResponses.size());
+    entities = hostRoleCommandDAO.findAll(spiRequest, predicate);
+    Assert.assertEquals(1, entities.size());
 
-    //check a taskId that requested by requestId2 and task id
-    taskStatusRequests = new HashSet<TaskStatusRequest>(){
-      {
-        add(new TaskStatusRequest(requestId2, 5L));
-      }
-    };
-    taskStatusResponses = controller.getTaskStatus(taskStatusRequests);
-    assertEquals(5L, taskStatusResponses.iterator().next().getTaskId());
-
-    //check that a sever-side action is reported back properly (namely the hostname value of the repsonse)
-    taskStatusResponses = controller.getTaskStatus(Collections.singleton(new TaskStatusRequest(requestId3, null)));
-    assertEquals(1, taskStatusResponses.size());
-    TaskStatusResponse response = taskStatusResponses.iterator().next();
-    assertNotNull(response);
-    assertEquals(6L, response.getTaskId());
-    // The host name for the task should be the same as what StageUtils#getHostName returns since
-    // the host was specified as null when
-    assertEquals(StageUtils.getHostName(), response.getHostName());
-
-    //verify that task from second request (requestId2) does not present in first request (requestId1)
-    taskStatusRequests = new HashSet<TaskStatusRequest>(){
-      {
-        add(new TaskStatusRequest(requestId1, 5L));
-      }
-    };
-    expectedException.expect(ObjectNotFoundException.class);
-    expectedException.expectMessage("Task resource doesn't exist.");
-    controller.getTaskStatus(taskStatusRequests);
+    // request ID 2 has 2 tasks
+    predicate = new PredicateBuilder().property(
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(requestId2).toPredicate();
 
-    //verify that task from first request (requestId1) does not present in second request (requestId2)
-    taskStatusRequests = new HashSet<TaskStatusRequest>(){
-      {
-        add(new TaskStatusRequest(requestId2, 2L));
-      }
-    };
-    expectedException.expect(ObjectNotFoundException.class);
-    expectedException.expectMessage("Task resource doesn't exist.");
-    controller.getTaskStatus(taskStatusRequests);
+    entities = hostRoleCommandDAO.findAll(spiRequest, predicate);
+    Assert.assertEquals(2, entities.size());
+
+    // a single task from request 1 and all tasks from request 2 will total 3
+    predicate = new PredicateBuilder().property(
+        TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(requestId1).and().property(
+            TaskResourceProvider.TASK_ID_PROPERTY_ID).equals(2L).or().property(
+                TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals(requestId2).toPredicate();
+
+    entities = hostRoleCommandDAO.findAll(spiRequest, predicate);
+    Assert.assertEquals(3, entities.size());
   }
 
   @Test

+ 16 - 60
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java

@@ -41,7 +41,6 @@ import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.StackConfigurationDependencyRequest;
 import org.apache.ambari.server.controller.StackConfigurationRequest;
 import org.apache.ambari.server.controller.StackLevelConfigurationRequest;
-import org.apache.ambari.server.controller.TaskStatusRequest;
 import org.apache.ambari.server.controller.UserRequest;
 import org.apache.ambari.server.controller.predicate.AlwaysPredicate;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
@@ -335,12 +334,6 @@ public class AbstractResourceProviderTest {
       return null;
     }
 
-    public static Set<TaskStatusRequest> getTaskRequestSet(Long requestId, Long taskId)
-    {
-      EasyMock.reportMatcher(new TaskRequestSetMatcher(requestId, taskId));
-      return null;
-    }
-
     public static Set<UserRequest> getUserRequestSet(String name)
     {
       EasyMock.reportMatcher(new UserRequestSetMatcher(name));
@@ -475,8 +468,8 @@ public class AbstractResourceProviderTest {
     private final HostRequest hostRequest;
 
     public HostRequestSetMatcher(String hostname, String clusterName, Map<String, String> hostAttributes) {
-      this.hostRequest = new HostRequest(hostname, clusterName, hostAttributes);
-      add(this.hostRequest);
+      hostRequest = new HostRequest(hostname, clusterName, hostAttributes);
+      add(hostRequest);
     }
 
     @Override
@@ -515,10 +508,10 @@ public class AbstractResourceProviderTest {
 
     public HostComponentRequestSetMatcher(String clusterName, String serviceName, String componentName, String hostName,
                                       Map<String, String> configVersions, String desiredState) {
-      this.hostComponentRequest =
+      hostComponentRequest =
           new ServiceComponentHostRequest(clusterName, serviceName, componentName,
               hostName, desiredState);
-      add(this.hostComponentRequest);
+      add(hostComponentRequest);
     }
 
     @Override
@@ -550,43 +543,6 @@ public class AbstractResourceProviderTest {
     }
   }
 
-  /**
-   * Matcher for a TaskStatusRequest set containing a single request.
-   */
-  public static class TaskRequestSetMatcher extends HashSet<TaskStatusRequest> implements IArgumentMatcher {
-
-    private final TaskStatusRequest taskStatusRequest;
-
-    public TaskRequestSetMatcher(Long requestId, Long taskId) {
-      this.taskStatusRequest = new TaskStatusRequest(requestId, taskId);
-      add(this.taskStatusRequest);
-    }
-
-    @Override
-    public boolean matches(Object o) {
-
-      if (!(o instanceof Set)) {
-        return false;
-      }
-
-      Set set = (Set) o;
-
-      if (set.size() != 1) {
-        return false;
-      }
-
-      Object request = set.iterator().next();
-
-      return request instanceof TaskStatusRequest &&
-          eq(((TaskStatusRequest) request).getRequestId(), taskStatusRequest.getRequestId());
-    }
-
-    @Override
-    public void appendTo(StringBuffer stringBuffer) {
-      stringBuffer.append("TaskRequestSetMatcher(").append(taskStatusRequest).append(")");
-    }
-  }
-
   /**
    * Matcher for a UserRequest set containing a single request.
    */
@@ -595,8 +551,8 @@ public class AbstractResourceProviderTest {
     private final UserRequest userRequest;
 
     public UserRequestSetMatcher(String name) {
-      this.userRequest = new UserRequest(name);
-      add(this.userRequest);
+      userRequest = new UserRequest(name);
+      add(userRequest);
     }
 
     @Override
@@ -632,8 +588,8 @@ public class AbstractResourceProviderTest {
     private final GroupRequest groupRequest;
 
     public GroupRequestSetMatcher(String name) {
-      this.groupRequest = new GroupRequest(name);
-      add(this.groupRequest);
+      groupRequest = new GroupRequest(name);
+      add(groupRequest);
     }
 
     @Override
@@ -669,8 +625,8 @@ public class AbstractResourceProviderTest {
     private final MemberRequest memberRequest;
 
     public MemberRequestSetMatcher(String groupname, String username) {
-      this.memberRequest = new MemberRequest(groupname, username);
-      add(this.memberRequest);
+      memberRequest = new MemberRequest(groupname, username);
+      add(memberRequest);
     }
 
     @Override
@@ -708,8 +664,8 @@ public class AbstractResourceProviderTest {
 
     public StackConfigurationRequestSetMatcher(String stackName, String stackVersion,
         String serviceName, String propertyName) {
-      this.stackConfigurationRequest = new StackConfigurationRequest(stackName, stackVersion, serviceName, propertyName);
-      add(this.stackConfigurationRequest);
+      stackConfigurationRequest = new StackConfigurationRequest(stackName, stackVersion, serviceName, propertyName);
+      add(stackConfigurationRequest);
     }
 
     @Override
@@ -749,8 +705,8 @@ public class AbstractResourceProviderTest {
 
     public StackConfigurationDependencyRequestSetMatcher(String stackName, String stackVersion,
         String serviceName, String propertyName, String dependencyName) {
-      this.stackConfigurationDependencyRequest = new StackConfigurationDependencyRequest(stackName, stackVersion, serviceName, propertyName, dependencyName);
-      add(this.stackConfigurationDependencyRequest);
+      stackConfigurationDependencyRequest = new StackConfigurationDependencyRequest(stackName, stackVersion, serviceName, propertyName, dependencyName);
+      add(stackConfigurationDependencyRequest);
     }
 
     @Override
@@ -787,8 +743,8 @@ public class AbstractResourceProviderTest {
 
     public StackLevelConfigurationRequestSetMatcher(String stackName, String stackVersion,
         String propertyName) {
-      this.stackLevelConfigurationRequest = new StackLevelConfigurationRequest(stackName, stackVersion, propertyName);
-      add(this.stackLevelConfigurationRequest);
+      stackLevelConfigurationRequest = new StackLevelConfigurationRequest(stackName, stackVersion, propertyName);
+      add(stackLevelConfigurationRequest);
     }
 
     @Override

+ 35 - 19
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/TaskResourceProviderTest.java

@@ -26,6 +26,7 @@ import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -33,18 +34,25 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.ambari.server.Role;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.RequestStatusResponse;
-import org.apache.ambari.server.controller.TaskStatusResponse;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.junit.Test;
 
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
 /**
  * TaskResourceProvider tests.
  */
@@ -94,24 +102,32 @@ public class TaskResourceProviderTest {
   public void testGetResources() throws Exception {
     Resource.Type type = Resource.Type.Task;
 
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    AmbariManagementController amc = createMock(AmbariManagementController.class);
+    HostRoleCommandDAO hostRoleCommandDAO = createMock(HostRoleCommandDAO.class);
+
+    Injector m_injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    TaskResourceProvider provider = (TaskResourceProvider) AbstractControllerResourceProvider.getResourceProvider(
+        type, PropertyHelper.getPropertyIds(type), PropertyHelper.getKeyPropertyIds(type), amc);
+
+    m_injector.injectMembers(provider);
+    TaskResourceProvider.s_dao = hostRoleCommandDAO;
 
-    Set<TaskStatusResponse> allResponse = new HashSet<TaskStatusResponse>();
-    allResponse.add(new TaskStatusResponse(100L, 100, 100L, "HostName100", "", "", "", 0, "", "", 0L, (short) 0,
-        "commandDetail", "customCommandName", null, null));
+    List<HostRoleCommandEntity> entities = new ArrayList<>();
+    HostRoleCommandEntity hostRoleCommandEntity = new HostRoleCommandEntity();
+    hostRoleCommandEntity.setRequestId(100L);
+    hostRoleCommandEntity.setTaskId(100L);
+    hostRoleCommandEntity.setStageId(100L);
+    hostRoleCommandEntity.setRole(Role.DATANODE);
+    hostRoleCommandEntity.setCustomCommandName("customCommandName");
+    hostRoleCommandEntity.setCommandDetail("commandDetail");
+    entities.add(hostRoleCommandEntity);
 
     // set expectations
-    expect(managementController.getTaskStatus(AbstractResourceProviderTest.Matcher.getTaskRequestSet(100L, 100L))).
-        andReturn(allResponse).once();
+    expect(hostRoleCommandDAO.findAll(EasyMock.anyObject(Request.class),
+        EasyMock.anyObject(Predicate.class))).andReturn(entities).once();
 
     // replay
-    replay(managementController);
-
-    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
+    replay(hostRoleCommandDAO);
 
     Set<String> propertyIds = new HashSet<String>();
 
@@ -135,7 +151,7 @@ public class TaskResourceProviderTest {
     }
 
     // verify
-    verify(managementController);
+    verify(hostRoleCommandDAO);
   }
 
   @Test
@@ -236,7 +252,7 @@ public class TaskResourceProviderTest {
 
     verify(managementController);
   }
-  
+
   @Test
   public void testParseStructuredOutputForHostCheck() {
     Resource.Type type = Resource.Type.Task;
@@ -254,13 +270,13 @@ public class TaskResourceProviderTest {
 
     Assert.assertNotNull(result);
     Map<?,?> host_resolution_check = (Map<?,?>)result.get("host_resolution_check");
-    
+
     assertEquals(host_resolution_check.get("success_count"), 3);
     assertEquals(host_resolution_check.get("failed_count"), 1);
-    
+
     verify(managementController);
   }
-  
+
   @Test
   public void testInvalidStructuredOutput() {
     Resource.Type type = Resource.Type.Task;