浏览代码

AMBARI-2553 - Delay between service tab opening and displaying actual states of Stop/Start buttons

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1499892 13f79535-47bb-0310-9956-ffa450edef68
Tom Beerbower 12 年之前
父节点
当前提交
374d164abf
共有 17 个文件被更改,包括 833 次插入16 次删除
  1. 1 0
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
  2. 4 1
      ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java
  3. 7 0
      ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java
  4. 20 2
      ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java
  5. 45 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
  6. 8 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java
  7. 109 6
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
  8. 71 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PageRequestImpl.java
  9. 61 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PageResponseImpl.java
  10. 26 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ClusterController.java
  11. 76 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/spi/PageRequest.java
  12. 52 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/spi/PageResponse.java
  13. 2 7
      ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
  14. 13 0
      ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java
  15. 188 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterControllerImplTest.java
  16. 74 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PageRequestImplTest.java
  17. 76 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PageResponseImplTest.java

+ 1 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java

@@ -47,6 +47,7 @@ public class ReadHandler implements RequestHandler {
 
     try {
       addFieldsToQuery(request, query);
+      query.setPageRequest(request.getPageRequest());
     } catch (IllegalArgumentException e) {
       return new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
     }

+ 4 - 1
ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java

@@ -168,6 +168,9 @@ public class QueryLexer {
   static {
     // ignore values
     SET_IGNORE.add("fields");
+    SET_IGNORE.add("page_size");
+    SET_IGNORE.add("to");
+    SET_IGNORE.add("from");
     SET_IGNORE.add("_");
   }
 
@@ -501,4 +504,4 @@ public class QueryLexer {
       return "!".equals(token);
     }
   }
-}
+}

+ 7 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java

@@ -85,4 +85,11 @@ public interface Query {
    * @param predicate  the user provided predicate
    */
   public void setUserPredicate(Predicate predicate);
+
+  /**
+   * Set the page request information for this query.
+   *
+   * @param pageRequest  the page request information
+   */
+  public void setPageRequest(PageRequest pageRequest);
 }

+ 20 - 2
ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java

@@ -72,6 +72,11 @@ public class QueryImpl implements Query {
    */
   private Predicate m_userPredicate;
 
+  /**
+   * The user supplied page request information.
+   */
+  private PageRequest m_pageRequest;
+
   /**
    * The logger.
    */
@@ -138,8 +143,16 @@ public class QueryImpl implements Query {
     }
 
     Predicate predicate = createPredicate(m_resource);
-    Iterable<Resource> iterResource = getClusterController().getResources(
-        resourceType, createRequest(), predicate);
+    Iterable<Resource> iterResource;
+
+    if (m_pageRequest == null) {
+      iterResource = getClusterController().getResources(
+          resourceType, createRequest(), predicate);
+    } else {
+      PageResponse pageResponse = getClusterController().getResources(
+          resourceType, createRequest(), predicate, m_pageRequest);
+      iterResource = pageResponse.getIterable();
+    }
 
     TreeNode<Resource> tree = result.getResultTree();
     int count = 1;
@@ -178,6 +191,11 @@ public class QueryImpl implements Query {
     m_userPredicate = predicate;
   }
 
+  @Override
+  public void setPageRequest(PageRequest pageRequest) {
+    m_pageRequest = pageRequest;
+  }
+
   ClusterController getClusterController() {
     return ClusterControllerHelper.getClusterController();
   }

+ 45 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java

@@ -22,7 +22,9 @@ import org.apache.ambari.server.api.handlers.RequestHandler;
 import org.apache.ambari.server.api.predicate.InvalidQueryException;
 import org.apache.ambari.server.api.predicate.PredicateCompiler;
 import org.apache.ambari.server.api.resources.*;
+import org.apache.ambari.server.controller.internal.PageRequestImpl;
 import org.apache.ambari.server.controller.internal.TemporalInfoImpl;
+import org.apache.ambari.server.controller.spi.PageRequest;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.TemporalInfo;
 import org.slf4j.Logger;
@@ -66,6 +68,11 @@ public abstract class BaseRequest implements Request {
    */
   private ResourceInstance m_resource;
 
+  /**
+   * Default page size for pagination request.
+   */
+  private static final int DEFAULT_PAGE_SIZE = 20;
+
   /**
    *  Logger instance.
    */
@@ -182,6 +189,44 @@ public abstract class BaseRequest implements Request {
     return m_headers.getRequestHeaders();
   }
 
+  @Override
+  public PageRequest getPageRequest() {
+
+    String pageSize = m_uriInfo.getQueryParameters().getFirst("page_size");
+    String from     = m_uriInfo.getQueryParameters().getFirst("from");
+    String to       = m_uriInfo.getQueryParameters().getFirst("to");
+
+    if (pageSize == null && from == null && to == null) {
+      return null;
+    }
+
+    int offset = 0;
+    PageRequest.StartingPoint startingPoint;
+
+    // TODO : support other starting points
+    if (from != null) {
+      if(from.equals("start")) {
+        startingPoint = PageRequest.StartingPoint.Beginning;
+      } else {
+        offset = Integer.valueOf(from);
+        startingPoint = PageRequest.StartingPoint.OffsetStart;
+      }
+    } else if (to != null ) {
+      if (to.equals("end")) {
+        startingPoint = PageRequest.StartingPoint.End;
+      } else {
+        offset = Integer.valueOf(to);
+        startingPoint = PageRequest.StartingPoint.OffsetEnd;
+      }
+    } else {
+      startingPoint = PageRequest.StartingPoint.Beginning;
+    }
+
+    // TODO : support predicate and comparator
+    return new PageRequestImpl(startingPoint,
+        pageSize == null ? DEFAULT_PAGE_SIZE : Integer.valueOf(pageSize), offset, null, null);
+  }
+
   @Override
   public RequestBody getBody() {
     return m_body;

+ 8 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java

@@ -20,6 +20,7 @@ package org.apache.ambari.server.api.services;
 
 import org.apache.ambari.server.api.resources.ResourceDefinition;
 import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.PageRequest;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.TemporalInfo;
 
@@ -106,4 +107,11 @@ public interface Request {
    * @return the http headers
    */
   public Map<String, List<String>> getHttpHeaders();
+
+  /**
+   * Obtain the pagination request information.
+   *
+   * @return the page request
+   */
+  public PageRequest getPageRequest();
 }

+ 109 - 6
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java

@@ -31,8 +31,11 @@ import java.util.Comparator;
 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.NavigableSet;
 import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.TreeSet;
@@ -88,7 +91,16 @@ public class ClusterControllerImpl implements ClusterController {
              SystemException,
              NoSuchParentResourceException,
              NoSuchResourceException {
+    PageResponse response = getResources(type, request, predicate, null);
+    return response.getIterable();
+  }
 
+  @Override
+  public PageResponse getResources(Resource.Type type, Request request, Predicate predicate, PageRequest pageRequest)
+      throws UnsupportedPropertyException,
+             SystemException,
+             NoSuchResourceException,
+             NoSuchParentResourceException {
     ResourceProvider provider = ensureResourceProvider(type);
     ensurePropertyProviders(type);
     Set<Resource> resources;
@@ -99,19 +111,39 @@ public class ClusterControllerImpl implements ClusterController {
 
       if (LOG.isDebugEnabled()) {
         LOG.debug("Using resource provider "
-          + provider.getClass().getName()
-          + " for request type " + type.toString());
+            + provider.getClass().getName()
+            + " for request type " + type.toString());
       }
       checkProperties(type, request, predicate);
 
       Set<Resource> providerResources = provider.getResources(request, predicate);
       providerResources               = populateResources(type, providerResources, request, predicate);
 
-      resources = new TreeSet<Resource>(comparator);
-      resources.addAll(providerResources);
+      Comparator<Resource> resourceComparator = pageRequest == null || pageRequest.getComparator() == null ?
+          comparator : pageRequest.getComparator();
+
+      TreeSet<Resource> sortedResources = new TreeSet<Resource>(resourceComparator);
+      sortedResources.addAll(providerResources);
+
+      if (pageRequest != null) {
+        switch (pageRequest.getStartingPoint()) {
+          case Beginning:
+            return getPageFromOffset(pageRequest.getPageSize(), 0, sortedResources, predicate);
+          case End:
+            return getPageToOffset(pageRequest.getPageSize(), -1, sortedResources, predicate);
+          case OffsetStart:
+            return getPageFromOffset(pageRequest.getPageSize(), pageRequest.getOffset(), sortedResources, predicate);
+          case OffsetEnd:
+            return getPageToOffset(pageRequest.getPageSize(), pageRequest.getOffset(), sortedResources, predicate);
+          // TODO : need to support the following cases for pagination
+//          case PredicateStart:
+//          case PredicateEnd:
+        }
+      }
+      resources = sortedResources;
     }
-    
-    return new ResourceIterable(resources, predicate);
+
+    return new PageResponseImpl(new ResourceIterable(resources, predicate), 0, null, null);
   }
 
   @Override
@@ -375,6 +407,77 @@ public class ClusterControllerImpl implements ClusterController {
     return propertyProviders.get(type);
   }
 
+  /**
+   * Get one page of resources from the given set of resources starting at the given offset.
+   *
+   * @param pageSize   the page size
+   * @param offset     the offset
+   * @param resources  the set of resources
+   * @param predicate  the predicate
+   *
+   * @return a page response containing a page of resources
+   */
+  private PageResponse getPageFromOffset(int pageSize, int offset, NavigableSet<Resource> resources, Predicate predicate) {
+
+    int                currentOffset = 0;
+    Resource           previous      = null;
+    Set<Resource>      pageResources = new LinkedHashSet<Resource>();
+    Iterator<Resource> iterator      = resources.iterator();
+
+    // skip till offset
+    while (currentOffset < offset && iterator.hasNext()) {
+      previous = iterator.next();
+      ++currentOffset;
+    }
+
+    // get a page worth of resources
+    for (int i = 0; i < pageSize && iterator.hasNext(); ++i) {
+      pageResources.add(iterator.next());
+    }
+
+    return new PageResponseImpl(new ResourceIterable(pageResources, predicate),
+        currentOffset,
+        previous,
+        iterator.hasNext() ? iterator.next() : null);
+  }
+
+  /**
+   * Get one page of resources from the given set of resources ending at the given offset.
+   *
+   * @param pageSize   the page size
+   * @param offset     the offset; -1 indicates the end of the resource set
+   * @param resources  the set of resources
+   * @param predicate  the predicate
+   *
+   * @return a page response containing a page of resources
+   */
+  private PageResponse getPageToOffset(int pageSize, int offset, NavigableSet<Resource> resources, Predicate predicate) {
+
+    int                currentOffset = resources.size() - 1;
+    Resource           next          = null;
+    List<Resource>     pageResources = new LinkedList<Resource>();
+    Iterator<Resource> iterator      = resources.descendingIterator();
+
+    if (offset != -1) {
+      // skip till offset
+      while (currentOffset > offset && iterator.hasNext()) {
+        next = iterator.next();
+        --currentOffset;
+      }
+    }
+
+    // get a page worth of resources
+    for (int i = 0; i < pageSize && iterator.hasNext(); ++i) {
+      pageResources.add(0, iterator.next());
+      --currentOffset;
+    }
+
+    return new PageResponseImpl(new ResourceIterable(new LinkedHashSet<Resource>(pageResources), predicate),
+        currentOffset + 1,
+        iterator.hasNext() ? iterator.next() : null,
+        next);
+  }
+
   /**
    * Get the associated resource comparator.
    *

+ 71 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PageRequestImpl.java

@@ -0,0 +1,71 @@
+/**
+ * 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.internal;
+
+import org.apache.ambari.server.controller.spi.PageRequest;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import java.util.Comparator;
+
+/**
+ * Basic page request implementation.
+ */
+public class PageRequestImpl implements PageRequest{
+
+  private final StartingPoint startingPoint;
+  private final int pageSize;
+  private final int offset;
+  private final Predicate predicate;
+  private final Comparator<Resource> comparator;
+
+  public PageRequestImpl(StartingPoint startingPoint, int pageSize, int offset, Predicate predicate,
+                         Comparator<Resource> comparator) {
+    this.startingPoint = startingPoint;
+    this.pageSize = pageSize;
+    this.offset = offset;
+    this.predicate = predicate;
+    this.comparator = comparator;
+  }
+
+  @Override
+  public StartingPoint getStartingPoint() {
+    return startingPoint;
+  }
+
+  @Override
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  @Override
+  public int getOffset() {
+    return offset;
+  }
+
+  @Override
+  public Predicate getPredicate() {
+    return predicate;
+  }
+
+  @Override
+  public Comparator<Resource> getComparator() {
+    return comparator;
+  }
+}

+ 61 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PageResponseImpl.java

@@ -0,0 +1,61 @@
+/**
+ * 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.internal;
+
+import org.apache.ambari.server.controller.spi.PageResponse;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Basic page response implementation.
+ */
+public class PageResponseImpl implements PageResponse{
+
+
+  private final Iterable<Resource> iterable;
+  private final int offset;
+  private final Resource previousResource;
+  private final Resource nextResource;
+
+  public PageResponseImpl(Iterable<Resource> iterable, int offset, Resource previousResource, Resource nextResource) {
+    this.iterable = iterable;
+    this.offset = offset;
+    this.previousResource = previousResource;
+    this.nextResource = nextResource;
+  }
+
+  @Override
+  public Iterable<Resource> getIterable() {
+    return iterable;
+  }
+
+  @Override
+  public int getOffset() {
+    return offset;
+  }
+
+  @Override
+  public Resource getPreviousResource() {
+    return previousResource;
+  }
+
+  @Override
+  public Resource getNextResource() {
+    return nextResource;
+  }
+}

+ 26 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ClusterController.java

@@ -51,6 +51,32 @@ public interface ClusterController {
              NoSuchResourceException,
              NoSuchParentResourceException;
 
+  /**
+   * Get a page of resources of the given type filtered by the given request,
+   * predicate objects and page request.
+   *
+   * @param type        the type of the requested resources
+   * @param request     the request object which defines the desired set of properties
+   * @param predicate   the predicate object which filters which resources are returned
+   * @param pageRequest the page request for a paginated response
+   *
+   * @return a page response representing the requested page of resources
+   *
+   * @throws UnsupportedPropertyException thrown if the request or predicate contain
+   *                                      unsupported property ids
+   * @throws SystemException an internal exception occurred
+   * @throws NoSuchResourceException no matching resource(s) found
+   * @throws NoSuchParentResourceException a specified parent resource doesn't exist
+   */
+  public PageResponse getResources(Resource.Type type,
+                                         Request request,
+                                         Predicate predicate,
+                                         PageRequest pageRequest)
+      throws UnsupportedPropertyException,
+      SystemException,
+      NoSuchResourceException,
+      NoSuchParentResourceException;
+
   /**
    * Get the {@link Schema schema} for the given resource type.  The schema
    * for a given resource type describes the properties and categories provided

+ 76 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/spi/PageRequest.java

@@ -0,0 +1,76 @@
+/**
+ * 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.spi;
+
+import java.util.Comparator;
+
+/**
+ * Holder for page request information used when pagination is requested.
+ */
+public interface PageRequest {
+
+  /**
+   * Get the starting point for the page being requested.
+   *
+   * @return the starting point
+   */
+  public StartingPoint getStartingPoint();
+
+  /**
+   * Get the desired page size.
+   *
+   * @return the page size; -1 means from the starting point to the end of the resource set
+   */
+  public int getPageSize();
+
+  /**
+   * Get the offset (zero based) of the resource that should be used as the start or end
+   * of the page.
+   *
+   * @return the offset
+   */
+  public int getOffset();
+
+  /**
+   * Return the predicate that identifies the single resource to be used
+   * as the start or end of the page.
+   *
+   * @return the associated predicate
+   */
+  public Predicate getPredicate();
+
+  /**
+   * Get the comparator used to order the page request.
+   *
+   * @return the comparator
+   */
+  public Comparator<Resource> getComparator();
+
+  /**
+   * The desired starting point of the page being requested.
+   */
+  public enum StartingPoint {
+    Beginning,      // start the page from the beginning of the resource set
+    End,            // end the page at the end of the resource set
+    OffsetStart,    // start the page from the associated offset point
+    OffsetEnd,      // end the page at the associated offset point
+    PredicateStart, // start the page from the resource identified by the associated predicate
+    PredicateEnd    // end the page at the resource identified by the associated predicate
+    }
+}

+ 52 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/spi/PageResponse.java

@@ -0,0 +1,52 @@
+/**
+ * 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.spi;
+
+/**
+ * A response for a single page of resources when pagination is used.
+ */
+public interface PageResponse {
+  /**
+   * Get the iterable set of resources for the page.
+   *
+   * @return the iterable set of resources
+   */
+  public Iterable<Resource> getIterable();
+
+  /**
+   * Get the offset of the first resource of the page.
+   *
+   * @return the offset
+   */
+  public int getOffset();
+
+  /**
+   * Get the last resource before this page.
+   *
+   * @return the last resource before this page; null if this is the first page
+   */
+  public Resource getPreviousResource();
+
+  /**
+   * Get the next resource after this page.
+   *
+   * @return the next resource after this page; null if this is the last page
+   */
+  public Resource getNextResource();
+}

+ 2 - 7
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java

@@ -153,7 +153,7 @@ public class HostRoleCommandDAO {
       Collection<HostRoleStatus> statuses, boolean match, boolean checkAllTasks) {
     List<Long> results = null;
     StringBuilder queryStr = new StringBuilder();
-    Integer resultsLimit = null;
+
     queryStr.append("SELECT DISTINCT command.requestId ").append(
         "FROM HostRoleCommandEntity command ");
     if (statuses != null && !statuses.isEmpty()) {
@@ -175,17 +175,12 @@ public class HostRoleCommandDAO {
         }
         queryStr.append("IN ?1 ");
       }
-      resultsLimit = REQUESTS_RESULT_LIMIT_WITH_FILTER;
-    } else {
-      resultsLimit = REQUESTS_RESULT_LIMIT;
     }
 
     queryStr.append("ORDER BY command.requestId DESC");
     TypedQuery<Long> query = entityManagerProvider.get().createQuery(queryStr.toString(),
         Long.class);
-    if (resultsLimit != null) {
-      query.setMaxResults(resultsLimit);
-    }
+
     if (statuses != null && !statuses.isEmpty()) {
       results = daoUtils.selectList(query, statuses);
     } else {

+ 13 - 0
ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java

@@ -87,6 +87,7 @@ public class ReadHandlerTest {
     expect(resource.getQuery()).andReturn(query);
 
     expect(request.getFields()).andReturn(mapPartialResponseFields);
+    expect(request.getPageRequest()).andReturn(null);
     query.addProperty(null, "foo", null);
     query.addProperty("bar", "c", null);
     query.addProperty("bar/d", "e", null);
@@ -94,6 +95,7 @@ public class ReadHandlerTest {
 
     expect(request.getQueryPredicate()).andReturn(predicate);
     query.setUserPredicate(predicate);
+    query.setPageRequest(null);
     expect(query.execute()).andReturn(result);
     result.setResultStatus(capture(resultStatusCapture));
 
@@ -117,9 +119,11 @@ public class ReadHandlerTest {
     expect(resource.getQuery()).andReturn(query);
 
     expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap());
+    expect(request.getPageRequest()).andReturn(null);
 
     expect(request.getQueryPredicate()).andReturn(predicate);
     query.setUserPredicate(predicate);
+    query.setPageRequest(null);
     SystemException systemException = new SystemException("testMsg", new RuntimeException());
     expect(query.execute()).andThrow(systemException);
 
@@ -145,9 +149,11 @@ public class ReadHandlerTest {
     expect(resource.getQuery()).andReturn(query);
 
     expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap());
+    expect(request.getPageRequest()).andReturn(null);
 
     expect(request.getQueryPredicate()).andReturn(predicate);
     query.setUserPredicate(predicate);
+    query.setPageRequest(null);
 
     expect(query.execute()).andThrow(exception);
 
@@ -174,9 +180,11 @@ public class ReadHandlerTest {
     expect(resource.getQuery()).andReturn(query);
 
     expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap());
+    expect(request.getPageRequest()).andReturn(null);
 
     expect(request.getQueryPredicate()).andReturn(predicate);
     query.setUserPredicate(predicate);
+    query.setPageRequest(null);
 
     expect(query.execute()).andThrow(exception);
 
@@ -202,9 +210,11 @@ public class ReadHandlerTest {
     expect(resource.getQuery()).andReturn(query);
 
     expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap());
+    expect(request.getPageRequest()).andReturn(null);
 
     expect(request.getQueryPredicate()).andReturn(predicate).anyTimes();
     query.setUserPredicate(predicate);
+    query.setPageRequest(null);
 
     expect(query.execute()).andThrow(exception);
 
@@ -229,9 +239,11 @@ public class ReadHandlerTest {
     expect(resource.getQuery()).andReturn(query);
 
     expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap());
+    expect(request.getPageRequest()).andReturn(null);
 
     expect(request.getQueryPredicate()).andReturn(null).anyTimes();
     query.setUserPredicate(null);
+    query.setPageRequest(null);
 
     expect(query.execute()).andThrow(exception);
 
@@ -257,6 +269,7 @@ public class ReadHandlerTest {
 //    expect(request.getResource()).andReturn(resource);
 //    expect(resource.getQuery()).andReturn(query);
 //
+//    expect(request.getPageRequest()).andReturn(null);
 //    expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap());
 //
 //    expect(request.getQueryPredicate()).andReturn(null).anyTimes();

+ 188 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterControllerImplTest.java

@@ -122,6 +122,194 @@ public class ClusterControllerImplTest {
     Assert.assertEquals(4, cnt);
   }
 
+  @Test
+  public void testGetResourcesPageFromStart() throws Exception{
+    ClusterController controller = new ClusterControllerImpl(new TestProviderModule());
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+
+    // get the first two
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 2, 0, null, null);
+    PageResponse pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    Iterable<Resource> iterable = pageResponse.getIterable();
+    List<Resource> list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(2, list.size());
+    Assert.assertEquals("host:1", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:2", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+
+    // get the first three
+    pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 3, 0, null, null);
+    pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    iterable = pageResponse.getIterable();
+    list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(3, list.size());
+    Assert.assertEquals("host:1", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:2", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+    Assert.assertEquals("host:3", (String) list.get(2).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(2).getType());
+  }
+
+  @Test
+  public void testGetResourcesPageFromOffset() throws Exception{
+    ClusterController controller = new ClusterControllerImpl(new TestProviderModule());
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+
+    // get the middle two (1 - 2)
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.OffsetStart, 2, 1, null, null);
+    PageResponse pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    Assert.assertEquals(1, pageResponse.getOffset());
+    Assert.assertEquals("host:1", pageResponse.getPreviousResource().getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals("host:4", pageResponse.getNextResource().getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+
+    Iterable<Resource> iterable = pageResponse.getIterable();
+    List<Resource> list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(2, list.size());
+    Assert.assertEquals("host:2", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:3", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+
+    // get the last three (0 - 2)
+    pageRequest = new PageRequestImpl(PageRequest.StartingPoint.OffsetStart, 3, 0, null, null);
+    pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    Assert.assertEquals(0, pageResponse.getOffset());
+    Assert.assertNull(pageResponse.getPreviousResource());
+    Assert.assertEquals("host:4", pageResponse.getNextResource().getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+
+    iterable = pageResponse.getIterable();
+    list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(3, list.size());
+    Assert.assertEquals("host:1", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:2", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+    Assert.assertEquals("host:3", (String) list.get(2).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(2).getType());
+  }
+
+  @Test
+  public void testGetResourcesPageToEnd() throws Exception{
+    ClusterController controller = new ClusterControllerImpl(new TestProviderModule());
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+
+    // get the last two
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.End, 2, 0, null, null);
+    PageResponse pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    Iterable<Resource> iterable = pageResponse.getIterable();
+    List<Resource> list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(2, list.size());
+    Assert.assertEquals("host:3", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:4", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+
+    // get the last three
+    pageRequest = new PageRequestImpl(PageRequest.StartingPoint.End, 3, 0, null, null);
+    pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    iterable = pageResponse.getIterable();
+    list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(3, list.size());
+    Assert.assertEquals("host:2", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:3", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+    Assert.assertEquals("host:4", (String) list.get(2).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(2).getType());
+  }
+
+  @Test
+  public void testGetResourcesPageToOffset() throws Exception{
+    ClusterController controller = new ClusterControllerImpl(new TestProviderModule());
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+
+    // get the middle two (1 - 2)
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.OffsetEnd, 2, 2, null, null);
+    PageResponse pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    Assert.assertEquals(1, pageResponse.getOffset());
+    Assert.assertEquals("host:1", pageResponse.getPreviousResource().getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals("host:4", pageResponse.getNextResource().getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+
+    Iterable<Resource> iterable = pageResponse.getIterable();
+    List<Resource> list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(2, list.size());
+    Assert.assertEquals("host:2", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:3", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+
+    // get the last three (0 - 2)
+    pageRequest = new PageRequestImpl(PageRequest.StartingPoint.OffsetEnd, 3, 2, null, null);
+    pageResponse = controller.getResources(Resource.Type.Host, request, null, pageRequest);
+
+    Assert.assertEquals(0, pageResponse.getOffset());
+    Assert.assertNull(pageResponse.getPreviousResource());
+    Assert.assertEquals("host:4", pageResponse.getNextResource().getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+
+    iterable = pageResponse.getIterable();
+    list = new LinkedList<Resource>();
+
+    for (Resource resource : iterable) {
+      list.add(resource);
+    }
+    Assert.assertEquals(3, list.size());
+    Assert.assertEquals("host:1", (String) list.get(0).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(0).getType());
+    Assert.assertEquals("host:2", (String) list.get(1).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(1).getType());
+    Assert.assertEquals("host:3", (String) list.get(2).getPropertyValue(PropertyHelper.getPropertyId("Hosts", "host_name")));
+    Assert.assertEquals(Resource.Type.Host, list.get(2).getType());
+  }
+
   @Test
   public void testGetResourcesEmptyRequest() throws Exception{
     ClusterController controller = new ClusterControllerImpl(new TestProviderModule());

+ 74 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PageRequestImplTest.java

@@ -0,0 +1,74 @@
+/**
+ * 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.internal;
+
+import org.apache.ambari.server.controller.spi.PageRequest;
+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.junit.Assert;
+import org.junit.Test;
+
+import java.util.Comparator;
+
+/**
+ * PageRequestImpl tests.
+ */
+public class PageRequestImplTest {
+  @Test
+  public void testGetStartingPoint() throws Exception {
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 20, 99, null, null);
+    Assert.assertEquals(PageRequest.StartingPoint.Beginning, pageRequest.getStartingPoint());
+  }
+
+  @Test
+  public void testGetPageSize() throws Exception {
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 20, 99, null, null);
+    Assert.assertEquals(20, pageRequest.getPageSize());
+  }
+
+  @Test
+  public void testGetOffset() throws Exception {
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 20, 99, null, null);
+    Assert.assertEquals(99, pageRequest.getOffset());
+  }
+
+  @Test
+  public void testGetPredicate() throws Exception {
+    PredicateBuilder pb = new PredicateBuilder();
+    Predicate predicate = pb.property("id").equals(20).toPredicate();
+
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 20, 99, predicate, null);
+    Assert.assertEquals(predicate, pageRequest.getPredicate());
+  }
+
+  @Test
+  public void testGetComparator() throws Exception {
+
+    Comparator<Resource> comparator = new Comparator<Resource>() {
+      @Override
+      public int compare(Resource resource, Resource resource1) {
+        return 0;
+      }
+    };
+
+    PageRequest pageRequest = new PageRequestImpl(PageRequest.StartingPoint.Beginning, 20, 99, null, comparator);
+    Assert.assertEquals(comparator, pageRequest.getComparator());
+  }
+}

+ 76 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/PageResponseImplTest.java

@@ -0,0 +1,76 @@
+/**
+ * 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.internal;
+
+import junit.framework.Assert;
+import org.apache.ambari.server.controller.spi.PageResponse;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.junit.Test;
+
+import java.util.HashSet;
+
+/**
+ * PageResponseImpl tests.
+ */
+public class PageResponseImplTest {
+
+  @Test
+  public void testGetIterable() throws Exception {
+    Iterable<Resource> iterable = new HashSet<Resource>();
+    Resource prev = new ResourceImpl(Resource.Type.Cluster);
+    Resource next = new ResourceImpl(Resource.Type.Cluster);
+
+    PageResponse response = new PageResponseImpl(iterable, 99, prev, next);
+
+    Assert.assertEquals(iterable, response.getIterable());
+  }
+
+  @Test
+  public void testGetOffset() throws Exception {
+    Iterable<Resource> iterable = new HashSet<Resource>();
+    Resource prev = new ResourceImpl(Resource.Type.Cluster);
+    Resource next = new ResourceImpl(Resource.Type.Cluster);
+
+    PageResponse response = new PageResponseImpl(iterable, 99, prev, next);
+
+    Assert.assertEquals(99, response.getOffset());
+  }
+
+  @Test
+  public void testGetPreviousResource() throws Exception {
+    Iterable<Resource> iterable = new HashSet<Resource>();
+    Resource prev = new ResourceImpl(Resource.Type.Cluster);
+    Resource next = new ResourceImpl(Resource.Type.Cluster);
+
+    PageResponse response = new PageResponseImpl(iterable, 99, prev, next);
+
+    Assert.assertEquals(prev, response.getPreviousResource());
+  }
+
+  @Test
+  public void testGetNextResource() throws Exception {
+    Iterable<Resource> iterable = new HashSet<Resource>();
+    Resource prev = new ResourceImpl(Resource.Type.Cluster);
+    Resource next = new ResourceImpl(Resource.Type.Cluster);
+
+    PageResponse response = new PageResponseImpl(iterable, 99, prev, next);
+
+    Assert.assertEquals(next, response.getNextResource());
+  }
+}