You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2012/10/16 08:13:45 UTC

svn commit: r1398662 - in /incubator/ambari/branches/AMBARI-666: ./ ambari-agent/src/main/python/ambari_agent/ ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ ambari-server/src/main/java/org/apache/ambari/server/api/query/ ambari-ser...

Author: mahadev
Date: Tue Oct 16 06:13:44 2012
New Revision: 1398662

URL: http://svn.apache.org/viewvc?rev=1398662&view=rev
Log:
AMBARI-852. Improve REST API functionality regarding query and partial response (John Speidel via mahadev)

Added:
    incubator/ambari/branches/AMBARI-666/ambari-agent/src/main/python/ambari_agent/ProcUtil.py
    incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java
Modified:
    incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeletePersistenceManager.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestImpl.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpdatePersistenceManager.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/ArrayPredicate.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/UnaryPredicate.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/DeletePersistenceManagerTest.java
    incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/UpdatePersistenceManagerTest.java

Modified: incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt (original)
+++ incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt Tue Oct 16 06:13:44 2012
@@ -12,6 +12,9 @@ AMBARI-666 branch (unreleased changes)
 
   NEW FEATURES
 
+  AMBARI-852. Improve REST API functionality regarding query and partial
+  response (John Speidel via mahadev)
+
   AMBARI-865. Add unit test for action queue on the agent. (mahadev)
 
   AMBARI-851. Hook up Ganglia property provider. (Tom Beerbower via mahadev)

Added: incubator/ambari/branches/AMBARI-666/ambari-agent/src/main/python/ambari_agent/ProcUtil.py
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-agent/src/main/python/ambari_agent/ProcUtil.py?rev=1398662&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-agent/src/main/python/ambari_agent/ProcUtil.py (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-agent/src/main/python/ambari_agent/ProcUtil.py Tue Oct 16 06:13:44 2012
@@ -0,0 +1,38 @@
+#!/usr/bin/env python2.6
+
+'''
+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.
+'''
+
+import sys
+import os
+
+def get_proc_status(pid):
+  pid = int(pid)
+  path = ("/proc/%d/status" % pid)
+  if not os.path.exists(path):
+    return None
+  status_file = open(path)
+  lines = status_file.readlines()
+  for line in lines:
+    if line.startswith("State:"):
+      return line.split(":",1)[1].strip().split(' ')[0].split(" ",1)[0]
+  return None
+    
+if __name__ == '__main__':
+  state = get_proc_status(sys.argv[1])
+  print state

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java Tue Oct 16 06:13:44 2012
@@ -33,7 +33,6 @@ public class ReadHandler implements Requ
     Query query = request.getResourceDefinition().getQuery();
 
     //Partial response
-    //todo: could be encapsulated in request/query
     for (String s : request.getPartialResponseFields()) {
       int i = s.lastIndexOf('/');
       if (i == -1) {
@@ -43,6 +42,8 @@ public class ReadHandler implements Requ
       }
     }
 
+   query.setUserPredicate(request.getQueryPredicate());
+
     try {
       return query.execute();
     } catch (AmbariException e) {

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java Tue Oct 16 06:13:44 2012
@@ -23,6 +23,9 @@ import org.apache.ambari.server.AmbariEx
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.PropertyId;
 
+import java.util.Map;
+import java.util.Set;
+
 
 /**
  * Responsible for querying the back end for read requests
@@ -48,6 +51,15 @@ public interface Query {
   public void addProperty(PropertyId property);
 
   /**
+   * Obtain the properties of the query.
+   * These are the properties that make up the select portion of the query for which
+   * values are to be retrieved.
+   *
+   * @return the query properties
+   */
+  public Map<String, Set<String>> getProperties();
+
+  /**
    * Execute the query.
    *
    * @return the result of the query.
@@ -60,5 +72,13 @@ public interface Query {
    *
    * @return the predicate used to identify the associated resource
    */
-  public Predicate getPredicate();
+  public Predicate getInternalPredicate();
+
+  /**
+   * Set the user provided predicated on this query.
+   * This predicate will be "AND'd" with the internal query to produce the final predicate.
+   *
+   * @param predicate  the user provided predicate
+   */
+  public void setUserPredicate(Predicate predicate);
 }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java Tue Oct 16 06:13:44 2012
@@ -40,10 +40,10 @@ public class QueryImpl implements Query 
   /**
    * Resource definition of resource being operated on.
    */
-  ResourceDefinition m_resourceDefinition;
+  private ResourceDefinition m_resourceDefinition;
 
   /**
-   * PropertyHelper of the query which make up the select portion of the query.
+   * Properties of the query which make up the select portion of the query.
    */
   private Map<String, Set<String>> m_mapQueryProperties = new HashMap<String, Set<String>>();
 
@@ -57,6 +57,11 @@ public class QueryImpl implements Query 
    */
   private Map<String, ResourceDefinition> m_mapSubResources = new HashMap<String, ResourceDefinition>();
 
+  /**
+   * The user supplied predicate.
+   */
+  private Predicate m_userPredicate;
+
 
   /**
    * Constructor.
@@ -71,7 +76,10 @@ public class QueryImpl implements Query 
 
   @Override
   public void addProperty(String path, String property) {
-    if (m_mapAllProperties.containsKey(path) && m_mapAllProperties.get(path).contains(property)) {
+    if (path == null && property.equals("*")) {
+      // wildcard
+      addAllProperties();
+    } else if (m_mapAllProperties.containsKey(path) && m_mapAllProperties.get(path).contains(property)) {
       // local property
       Set<String> setProps = m_mapQueryProperties.get(path);
       if (setProps == null) {
@@ -125,8 +133,9 @@ public class QueryImpl implements Query 
     Iterable<Resource> iterResource = getClusterController().getResources(
         m_resourceDefinition.getType(), createRequest(), predicate);
 
+    TreeNode<Resource> tree = result.getResultTree();
     for (Resource resource : iterResource) {
-      TreeNode<Resource> node = result.getResultTree().addChild(resource, null);
+      TreeNode<Resource> node = tree.addChild(resource, null);
 
       for (Map.Entry<String, ResourceDefinition> entry : m_mapSubResources.entrySet()) {
         String subResCategory = entry.getKey();
@@ -147,18 +156,38 @@ public class QueryImpl implements Query 
   }
 
   @Override
-  public Predicate getPredicate() {
-    return createPredicate(m_resourceDefinition);
+  public Predicate getInternalPredicate() {
+    return createInternalPredicate(m_resourceDefinition);
   }
 
-  private boolean addPropertyToSubResource(String path, String property) {
-    boolean resourceAdded = false;
+  @Override
+  public Map<String, Set<String>> getProperties() {
+    return Collections.unmodifiableMap(m_mapQueryProperties);
+  }
+
+  @Override
+  public void setUserPredicate(Predicate predicate) {
+    m_userPredicate = predicate;
+  }
 
+  private void addAllProperties() {
+    m_mapQueryProperties.putAll(m_mapAllProperties);
+    for (Map.Entry<String, ResourceDefinition> entry : m_resourceDefinition.getSubResources().entrySet()) {
+      String name = entry.getKey();
+      if (! m_mapSubResources.containsKey(name)) {
+        m_mapSubResources.put(name, entry.getValue());
+      }
+    }
+  }
+
+  private boolean addPropertyToSubResource(String path, String property) {
     // cases:
-    // path is null, property is path
-    // path is single token and prop in non null
-    // path is multi level and prop is non null
+    // - path is null, property is path (all sub-resource props will have a path)
+    // - path is single token and prop in non null
+    //      (path only will presented as above case with property only)
+    // - path is multi level and prop is non null
 
+    boolean resourceAdded = false;
     if (path == null) {
       path = property;
       property = null;
@@ -170,8 +199,7 @@ public class QueryImpl implements Query 
     ResourceDefinition subResource = m_resourceDefinition.getSubResources().get(p);
     if (subResource != null) {
       m_mapSubResources.put(p, subResource);
-      //todo: handle case of trailing /
-      //todo: for example fields=subResource/
+      //todo: handle case of trailing '/' (for example fields=subResource/)
 
       if (property != null || !path.equals(p)) {
         //only add if a sub property is set or if a sub category is specified
@@ -182,13 +210,13 @@ public class QueryImpl implements Query 
     return resourceAdded;
   }
 
-  private Predicate createPredicate(ResourceDefinition resourceDefinition) {
+  private BasePredicate createInternalPredicate(ResourceDefinition resourceDefinition) {
     //todo: account for user predicates
     Resource.Type resourceType = resourceDefinition.getType();
     Map<Resource.Type, String> mapResourceIds = resourceDefinition.getResourceIds();
     Schema schema = getClusterController().getSchema(resourceType);
 
-    Set<Predicate> setPredicates = new HashSet<Predicate>();
+    Set<BasePredicate> setPredicates = new HashSet<BasePredicate>();
     for (Map.Entry<Resource.Type, String> entry : mapResourceIds.entrySet()) {
       //todo: null check is a hack for host_component and component queries where serviceId is not available for
       //todo: host_component queries and host is not available for component queries.
@@ -207,6 +235,13 @@ public class QueryImpl implements Query 
     }
   }
 
+  private Predicate createPredicate(ResourceDefinition resourceDefinition) {
+    BasePredicate internalPredicate = createInternalPredicate(resourceDefinition);
+    //todo: remove cast when predicate hierarchy is fixed
+    return m_userPredicate == null ? internalPredicate :
+        new AndPredicate((BasePredicate) m_userPredicate, internalPredicate);
+  }
+
   ClusterController getClusterController() {
     return ClusterControllerHelper.getClusterController();
   }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeletePersistenceManager.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeletePersistenceManager.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeletePersistenceManager.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeletePersistenceManager.java Tue Oct 16 06:13:44 2012
@@ -29,7 +29,7 @@ public class DeletePersistenceManager ex
   public void persist(ResourceDefinition resource) {
     try {
       getClusterController().deleteResources(resource.getType(),
-          resource.getQuery().getPredicate());
+          resource.getQuery().getInternalPredicate());
     } catch (AmbariException e) {
       //todo: handle exception
       throw new RuntimeException("Delete of resource failed: " + e, e);

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java Tue Oct 16 06:13:44 2012
@@ -20,6 +20,7 @@ package org.apache.ambari.server.api.ser
 
 import org.apache.ambari.server.api.resources.ResourceDefinition;
 import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.PropertyId;
 
 import java.net.URI;
@@ -55,7 +56,7 @@ public interface Request {
    *
    * @return the request uri
    */
-  public URI getURI();
+  public String getURI();
 
   /**
    * Obtain the http request type.  Type is one of {@link Type}.
@@ -72,11 +73,13 @@ public interface Request {
   public int getAPIVersion();
 
   /**
-   * Obtain the query predicates that were provided in the URL query string.
+   * Obtain the query predicate that was built from the user provided predicate fields in the query string.
+   * If multiple predicates are supplied, then they will be combined using the appropriate grouping predicate
+   * such as 'AND'.
    *
-   * @return a map of request predicates
+   * @return the user defined predicate
    */
-  public Map<String, String> getQueryPredicates();
+  public Predicate getQueryPredicate();
 
   /**
    * Obtain the set of partial response fields which were provided in the query string of the request uri.

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestImpl.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestImpl.java Tue Oct 16 06:13:44 2012
@@ -23,12 +23,17 @@ import org.apache.ambari.server.api.serv
 import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
 import org.apache.ambari.server.api.services.serializers.JsonSerializer;
 import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+import org.apache.ambari.server.controller.predicate.*;
+import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.UriInfo;
-import java.net.URI;
+import java.net.URLDecoder;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Request implementation.
@@ -86,8 +91,8 @@ public class RequestImpl implements Requ
   }
 
   @Override
-  public URI getURI() {
-    return m_uriInfo.getRequestUri();
+  public String getURI() {
+    return URLDecoder.decode(m_uriInfo.getRequestUri().toString());
   }
 
   @Override
@@ -101,8 +106,38 @@ public class RequestImpl implements Requ
   }
 
   @Override
-  public Map<String, String> getQueryPredicates() {
-    return null;
+  public Predicate getQueryPredicate() {
+    //todo: parse during init
+    //not using getQueryParameters because it assumes '=' operator
+    String uri = getURI();
+    int qsBegin = uri.indexOf("?");
+
+    //todo: consider returning an AlwaysPredicate in this case.
+    if (qsBegin == -1) return null;
+
+    Pattern pattern = Pattern.compile("!=|>=|<=|=|>|<");
+    String qs = uri.substring(qsBegin + 1);
+    String[] tokens = qs.split("&");
+
+    Set<Predicate> setPredicates = new HashSet<Predicate>();
+    for (String outerToken : tokens) {
+      Matcher m = pattern.matcher(outerToken);
+      m.find();
+      String field = outerToken.substring(0, m.start());
+      if (! field.equals("fields")) {
+        int tokEnd = m.end();
+        String value = outerToken.substring(tokEnd);
+        setPredicates.add(createPredicate(field, m.group(), value));
+      }
+    }
+
+    if (setPredicates.size() == 1) {
+      return setPredicates.iterator().next();
+    } else if (setPredicates.size() > 1) {
+      return new AndPredicate(setPredicates.toArray(new BasePredicate[setPredicates.size()]));
+    } else {
+      return null;
+    }
   }
 
   @Override
@@ -156,6 +191,26 @@ public class RequestImpl implements Requ
     }
   }
 
+  private Predicate createPredicate(String field, String operator, String value) {
+    PropertyId propertyId = PropertyHelper.getPropertyId(field);
+
+    if (operator.equals("=")) {
+      return new EqualsPredicate(propertyId, value);
+    } else if (operator.equals("!=")) {
+      return new NotPredicate(new EqualsPredicate(propertyId, value));
+    } else if (operator.equals("<")) {
+      return new LessPredicate(propertyId, value);
+    } else if (operator.equals(">"))  {
+      return new GreaterPredicate(propertyId, value);
+    } else if (operator.equals("<=")) {
+      return new LessEqualsPredicate(propertyId, value);
+    } else if (operator.equals(">=")) {
+      return new GreaterEqualsPredicate(propertyId, value);
+    } else {
+      throw new RuntimeException("Unknown operator provided in predicate: " + operator);
+    }
+  }
+
   private  RequestBodyParser getHttpBodyParser() {
     return new JsonPropertyParser();
   }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java Tue Oct 16 06:13:44 2012
@@ -57,7 +57,7 @@ public class ResultPostProcessorImpl imp
 
   @Override
   public void process(Result result) {
-    processNode(result.getResultTree(), m_request.getURI().toString());
+    processNode(result.getResultTree(), m_request.getURI());
   }
 
   /**

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpdatePersistenceManager.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpdatePersistenceManager.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpdatePersistenceManager.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/UpdatePersistenceManager.java Tue Oct 16 06:13:44 2012
@@ -31,7 +31,7 @@ public class UpdatePersistenceManager ex
   public void persist(ResourceDefinition resource) {
     try {
       getClusterController().updateResources(resource.getType(), createControllerRequest(resource.getProperties()),
-          resource.getQuery().getPredicate());
+          resource.getQuery().getInternalPredicate());
     } catch (AmbariException e) {
       //todo: handle exception
       throw new RuntimeException("Update of resource failed: " + e, e);

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java Tue Oct 16 06:13:44 2012
@@ -97,4 +97,24 @@ public class RequestImpl implements Requ
       return null;  //TODO
     }
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    RequestImpl request = (RequestImpl) o;
+
+    if (properties == null ? request.properties != null : !properties.equals(request.properties)) return false;
+    if (propertyIds == null ? request.propertyIds != null : !propertyIds.equals(request.propertyIds)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = propertyIds != null ? propertyIds.hashCode() : 0;
+    result = 31 * result + (properties != null ? properties.hashCode() : 0);
+    return result;
+  }
 }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/ArrayPredicate.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/ArrayPredicate.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/ArrayPredicate.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/ArrayPredicate.java Tue Oct 16 06:13:44 2012
@@ -58,13 +58,9 @@ public abstract class ArrayPredicate imp
     if (propertyIds != null ? !propertyIds.equals(that.propertyIds) : that.propertyIds != null) return false;
 
     // don't care about array order
-    List<BasePredicate> listPredicates = Arrays.asList(predicates);
-    if (listPredicates.size() != that.predicates.length) return false;
-    for (BasePredicate predicate : predicates) {
-      if (!listPredicates.contains(predicate)) return false;
-    }
-
-    return true;
+    Set<BasePredicate> setThisPredicates = new HashSet<BasePredicate>(Arrays.asList(predicates));
+    Set<BasePredicate> setThatPredicates = new HashSet<BasePredicate>(Arrays.asList(that.predicates));
+    return setThisPredicates.equals(setThatPredicates);
   }
 
   @Override

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/UnaryPredicate.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/UnaryPredicate.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/UnaryPredicate.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/predicate/UnaryPredicate.java Tue Oct 16 06:13:44 2012
@@ -28,6 +28,7 @@ public abstract class UnaryPredicate imp
   private final BasePredicate predicate;
 
   public UnaryPredicate(BasePredicate predicate) {
+    assert(predicate != null);
     this.predicate = predicate;
   }
 
@@ -45,5 +46,20 @@ public abstract class UnaryPredicate imp
     visitor.acceptUnaryPredicate(this);
   }
 
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof UnaryPredicate)) return false;
+
+    UnaryPredicate that = (UnaryPredicate) o;
+
+    return predicate.equals(that.predicate);
+  }
+
+  @Override
+  public int hashCode() {
+    return predicate.hashCode();
+  }
+
   public abstract String getOperator();
 }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java Tue Oct 16 06:13:44 2012
@@ -41,6 +41,7 @@ public class PropertyHelper {
 
   private static final String PROPERTIES_FILE = "properties.json";
   private static final String KEY_PROPERTIES_FILE = "key_properties.json";
+  private static final char EXTERNAL_PATH_SEP = '/';
 
   private static final Map<Resource.Type, Map<String, Set<PropertyId>>> PROPERTY_IDS = readPropertyIds(PROPERTIES_FILE);
   private static final Map<Resource.Type, Map<Resource.Type, PropertyId>> KEY_PROPERTY_IDS = readKeyPropertyIds(KEY_PROPERTIES_FILE);
@@ -53,6 +54,35 @@ public class PropertyHelper {
     return new PropertyIdImpl(name, category, temporal);
   }
 
+  /**
+   * Helper to create a PropertyId from an string.
+   * The provided string must not be null and should be the fully qualified property name.
+   * The fully qualified property name may or may not have a category name.
+   * if the fully qualified property name contains a path separator char, then the
+   * path up to the last pth separator is considered the path and the token after the last
+   * path separator char is the property name.  If no path separator is present, the category
+   * is null and the property name is the provided string.
+   *
+   * @param absProperty  the fully qualified property
+   *
+   * @return a new PropertyId for the provided property string
+   */
+  public static PropertyId getPropertyId(String absProperty) {
+    String category;
+    String name;
+
+    int lastPathSep = absProperty.lastIndexOf(EXTERNAL_PATH_SEP);
+    if (lastPathSep == -1) {
+      category = null;
+      name     = absProperty;
+    } else {
+      category = absProperty.substring(0, lastPathSep);
+      name     = absProperty.substring(lastPathSep + 1);
+    }
+
+    return getPropertyId(name, category);
+  }
+
   public static Set<PropertyId> getPropertyIds(Resource.Type resourceType, String providerKey) {
 
     Map<String, Set<PropertyId>> propertyIds = PROPERTY_IDS.get(resourceType);

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java Tue Oct 16 06:13:44 2012
@@ -5,6 +5,7 @@ package org.apache.ambari.server.api;
  */
 
 import org.apache.ambari.server.api.handlers.*;
+import org.apache.ambari.server.api.query.QueryImplTest;
 import org.apache.ambari.server.api.services.*;
 import org.apache.ambari.server.api.services.parsers.JsonPropertyParserTest;
 import org.junit.runner.RunWith;
@@ -13,8 +14,8 @@ import org.junit.runners.Suite;
 @RunWith(Suite.class)
 @Suite.SuiteClasses({ClusterServiceTest.class, HostServiceTest.class, ServiceServiceTest.class,
     ComponentServiceTest.class, HostComponentServiceTest.class, DelegatingRequestHandlerTest.class,
-    ReadHandlerTest.class, /*QueryImplTest.class*/ JsonPropertyParserTest.class, CreateHandlerTest.class,
+    ReadHandlerTest.class, QueryImplTest.class, JsonPropertyParserTest.class, CreateHandlerTest.class,
     UpdateHandlerTest.class, DeleteHandlerTest.class, CreatePersistenceManagerTest.class,
-    UpdatePersistenceManagerTest.class})
+    UpdatePersistenceManagerTest.class, RequestImplTest.class})
 public class TestSuite {
 }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java Tue Oct 16 06:13:44 2012
@@ -22,6 +22,7 @@ import org.apache.ambari.server.api.quer
 import org.apache.ambari.server.api.resources.ResourceDefinition;
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.controller.spi.Predicate;
 import org.junit.Test;
 
 
@@ -41,6 +42,7 @@ public class ReadHandlerTest {
     Request request = createStrictMock(Request.class);
     ResourceDefinition resourceDefinition = createStrictMock(ResourceDefinition.class);
     Query query = createMock(Query.class);
+    Predicate predicate = createMock(Predicate.class);
     Result result = createStrictMock(Result.class);
 
     Set<String> setPartialResponseFields = new HashSet<String>();
@@ -56,15 +58,18 @@ public class ReadHandlerTest {
     query.addProperty(null, "foo");
     query.addProperty("bar", "c");
     query.addProperty("bar/d", "e");
+
+    expect(request.getQueryPredicate()).andReturn(predicate);
+    query.setUserPredicate(predicate);
     expect(query.execute()).andReturn(result);
 
-    replay(request, resourceDefinition, query, result);
+    replay(request, resourceDefinition, query, predicate, result);
 
     //test
     ReadHandler handler = new ReadHandler();
     assertSame(result, handler.handleRequest(request));
 
-    verify(request, resourceDefinition, query, result);
+    verify(request, resourceDefinition, query, predicate, result);
 
   }
 }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java Tue Oct 16 06:13:44 2012
@@ -1,264 +1,271 @@
 package org.apache.ambari.server.api.query;
 
-//import org.apache.ambari.server.controller.internal.PropertyIdImpl;
-//import org.apache.ambari.server.controller.utilities.PredicateBuilder;
-//import org.apache.ambari.server.api.resources.ResourceDefinition;
-//import org.apache.ambari.server.api.services.Request;
-//import org.apache.ambari.server.api.services.Result;
-//import org.apache.ambari.server.controller.spi.ClusterController;
-//import org.apache.ambari.server.controller.spi.Predicate;
-//import org.apache.ambari.server.controller.spi.Resource;
-//import org.apache.ambari.server.controller.spi.Schema;
-//import org.junit.Test;
-//
-//import java.util.*;
-//
-//
-//import static org.easymock.EasyMock.*;
-//
-//import static org.junit.Assert.assertEquals;
-//import static org.junit.Assert.assertSame;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.api.resources.ResourceDefinition;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.After;
+import org.junit.Test;
 
+import java.util.*;
+
+import static org.easymock.EasyMock.*;
+
+import static org.easymock.EasyMock.eq;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
 
 public class QueryImplTest {
 
-//    ClusterController m_controller = createStrictMock(ClusterController.class);
-//    @Test
-//    public void testExecute__Component_Instance() throws Exception {
-//        ResourceDefinition componentResourceDef = createMock(ResourceDefinition.class);
-//        ResourceDefinition hostComponentResourceDef = createStrictMock(ResourceDefinition.class);
-//        Request request = createStrictMock(Request.class);
-//        Result result = createStrictMock(Result.class);
-//
-//        Schema componentSchema = createMock(Schema.class);
-//        Resource componentResource = createStrictMock(Resource.class);
-//        Query hostComponentQuery = createStrictMock(Query.class);
-//        Result hostComponentQueryResult  = createStrictMock(Result.class);
-//        Resource hostComponentResource = createStrictMock(Resource.class);
-//
-//        List<Resource> listResources = new ArrayList<Resource>();
-//        listResources.add(componentResource);
-//
-//        Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
-//        mapResourceIds.put(Resource.Type.Cluster, "clusterName");
-//        mapResourceIds.put(Resource.Type.Service, "serviceName");
-//        mapResourceIds.put(Resource.Type.Component, "componentName");
-//
-//        Set<ResourceDefinition> setChildren = new HashSet<ResourceDefinition>();
-//        Set<ResourceDefinition> setForeign = new HashSet<ResourceDefinition>();
-//        setForeign.add(hostComponentResourceDef);
-//
-//        Map<String, List<Resource>> mapHostComponentResources = new HashMap<String, List<Resource>>();
-//        mapHostComponentResources.put("/", Collections.singletonList(hostComponentResource));
-//
-//        // expectations
-//        expect(componentResourceDef.getType()).andReturn(Resource.Type.Component).atLeastOnce();
-//        expect(componentResourceDef.getResourceIds()).andReturn(mapResourceIds);
-//        expect(m_controller.getSchema(Resource.Type.Component)).andReturn(componentSchema).atLeastOnce();
-//        expect(componentSchema.getKeyPropertyId(Resource.Type.Cluster)).andReturn(new PropertyIdImpl("clusterId", "", false));
-//        expect(componentSchema.getKeyPropertyId(Resource.Type.Service)).andReturn(new PropertyIdImpl("serviceId", "", false));
-//        expect(componentSchema.getKeyPropertyId(Resource.Type.Component)).andReturn(new PropertyIdImpl("componentId", "", false));
-//
-//        expect(componentResourceDef.getId()).andReturn("componentName").atLeastOnce();
-//        //expect(componentResourceDef.getChildren()).andReturn(setChildren);
-//        //expect(componentResourceDef.getRelations()).andReturn(setForeign);
-//        expect(hostComponentResourceDef.getQuery()).andReturn(hostComponentQuery);
-//
-//        PredicateBuilder pb = new PredicateBuilder();
-//        Predicate predicate = pb.property("clusterId", "").equals("clusterName").and().
-//                property("serviceId", "").equals("serviceName").and().
-//                property("componentId", "").equals("componentName").toPredicate();
-//
-//        expect(m_controller.getResources(eq(Resource.Type.Component), eq(request), eq(predicate))).
-//                andReturn(listResources);
-//
-//        result.addResources("/", listResources);
-//
-//        expect(hostComponentQuery.execute()).andReturn(hostComponentQueryResult);
-//        expect(hostComponentQueryResult.getResources()).andReturn(mapHostComponentResources);
-//        expect(hostComponentResourceDef.getId()).andReturn("hostComponentName");
-//        expect(hostComponentResourceDef.getSingularName()).andReturn("host_component");
-//        result.addResources("host_component", Collections.singletonList(hostComponentResource));
-//
-//        replay(componentResourceDef, request, result, m_controller, componentSchema, componentResource,
-//                hostComponentResourceDef, hostComponentQuery, hostComponentQueryResult, hostComponentResource);
-//
-//        QueryImpl query = new TestQuery(componentResourceDef, result, request);
-//        Result testResult = query.execute();
-//        // todo: assert return value.  This is currently a mock.
-//
-//        verify(componentResourceDef, request, result, m_controller, componentSchema, componentResource,
-//                hostComponentResourceDef, hostComponentQuery, hostComponentQueryResult, hostComponentResource);
-//    }
-//
-//    @Test
-//    public void testExecute__Component_Collection() {
-//        ResourceDefinition componentResourceDef = createMock(ResourceDefinition.class);
-//        Request request = createStrictMock(Request.class);
-//        Result result = createStrictMock(Result.class);
-//
-//        Schema componentSchema = createMock(Schema.class);
-//        Resource componentResource1 = createStrictMock(Resource.class);
-//        Resource componentResource2 = createStrictMock(Resource.class);
-//
-//        List<Resource> listResources = new ArrayList<Resource>();
-//        listResources.add(componentResource1);
-//        listResources.add(componentResource2);
-//
-//        Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
-//        mapResourceIds.put(Resource.Type.Cluster, "clusterName");
-//        mapResourceIds.put(Resource.Type.Service, "serviceName");
-//
-//        // expectations
-//        expect(componentResourceDef.getType()).andReturn(Resource.Type.Component).atLeastOnce();
-//        expect(componentResourceDef.getResourceIds()).andReturn(mapResourceIds);
-//        expect(m_controller.getSchema(Resource.Type.Component)).andReturn(componentSchema).atLeastOnce();
-//        expect(componentSchema.getKeyPropertyId(Resource.Type.Cluster)).andReturn(new PropertyIdImpl("clusterId", "", false));
-//        expect(componentSchema.getKeyPropertyId(Resource.Type.Service)).andReturn(new PropertyIdImpl("serviceId", "", false));
-//
-//        expect(componentResourceDef.getId()).andReturn(null).atLeastOnce();
-//
-//        PredicateBuilder pb = new PredicateBuilder();
-//        Predicate predicate = pb.property("clusterId", "").equals("clusterName").and().
-//                property("serviceId", "").equals("serviceName").toPredicate();
-//
-//        expect(m_controller.getResources(eq(Resource.Type.Component), eq(request), eq(predicate))).
-//                andReturn(listResources);
-//
-//        result.addResources("/", listResources);
-//
-//        replay(componentResourceDef, request, result, m_controller, componentSchema, componentResource1, componentResource2);
-//
-//        QueryImpl query = new TestQuery(componentResourceDef, result, request);
-//        Result testResult = query.execute();
-//        // todo: assert return value.  This is currently a mock.
-//
-//        verify(componentResourceDef, request, result, m_controller, componentSchema, componentResource1, componentResource2);
-//    }
-//
-//    @Test
-//    public void testExecute__Cluster_Instance() {
-//        ResourceDefinition clusterResourceDef = createMock(ResourceDefinition.class);
-//        ResourceDefinition serviceResourceDef = createMock(ResourceDefinition.class);
-//        ResourceDefinition hostResourceDef = createMock(ResourceDefinition.class);
-//        Request request = createStrictMock(Request.class);
-//        Result result = createMock(Result.class);
-//
-//        Schema clusterSchema = createMock(Schema.class);
-//        Resource clusterResource = createStrictMock(Resource.class);
-//        Query serviceQuery = createStrictMock(Query.class);
-//        Result serviceQueryResult  = createStrictMock(Result.class);
-//        Resource serviceResource = createStrictMock(Resource.class);
-//        Resource serviceResource2 = createStrictMock(Resource.class);
-//        Query hostQuery = createStrictMock(Query.class);
-//        Result hostQueryResult  = createStrictMock(Result.class);
-//        Resource hostResource = createStrictMock(Resource.class);
-//
-//        List<Resource> listResources = new ArrayList<Resource>();
-//        listResources.add(clusterResource);
-//
-//        Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
-//        mapResourceIds.put(Resource.Type.Cluster, "clusterName");
-//
-//        Set<ResourceDefinition> setChildren = new HashSet<ResourceDefinition>();
-//        setChildren.add(serviceResourceDef);
-//        setChildren.add(hostResourceDef);
-//        Set<ResourceDefinition> setForeign = new HashSet<ResourceDefinition>();
-//
-//        Map<String, List<Resource>> mapServiceResources = new HashMap<String, List<Resource>>();
-//        List<Resource> listServiceResources = new ArrayList<Resource>();
-//        listServiceResources.add(serviceResource);
-//        listServiceResources.add(serviceResource2);
-//        mapServiceResources.put("/", listServiceResources);
-//
-//        Map<String, List<Resource>> mapHostResources = new HashMap<String, List<Resource>>();
-//        mapHostResources.put("/", Collections.singletonList(hostResource));
-//
-//        Map<String, Set<String>> mapPropertiesAll = new HashMap<String, Set<String>>();
-//        Set<String> setRootProps = new HashSet<String>();
-//        Set<String> setCategoryProps = new HashSet<String>();
-//        mapPropertiesAll.put(null,setRootProps);
-//        mapPropertiesAll.put("category", setCategoryProps);
-//
-//
-//        // expectations
-//        expect(clusterResourceDef.getType()).andReturn(Resource.Type.Cluster).atLeastOnce();
-//        expect(m_controller.getSchema(Resource.Type.Cluster)).andReturn(clusterSchema).atLeastOnce();
-//        expect(clusterSchema.getCategories()).andReturn(mapPropertiesAll);
-//
-//        expect(clusterResourceDef.getResourceIds()).andReturn(mapResourceIds);
-//        expect(clusterSchema.getKeyPropertyId(Resource.Type.Cluster)).andReturn(new PropertyIdImpl("clusterId", "", false));
-//        expect(clusterResourceDef.getId()).andReturn("clusterName").atLeastOnce();
-//
-//
-//        //expect(clusterResourceDef.getChildren()).andReturn(setChildren);
-//        expect(serviceResourceDef.getQuery()).andReturn(serviceQuery);
-//        expect(hostResourceDef.getQuery()).andReturn(hostQuery);
-//        //expect(clusterResourceDef.getRelations()).andReturn(setForeign);
-//
-//        Predicate clusterEqualsPredicate = new EqualsPredicate(new PropertyIdImpl("clusterId", "", false), "clusterName");
-//
-//        expect(m_controller.getResources(eq(Resource.Type.Cluster), eq(request), eq(clusterEqualsPredicate))).
-//                andReturn(listResources);
-//
-//        result.addResources("/", listResources);
-//
-//        expect(serviceQuery.execute()).andReturn(serviceQueryResult);
-//        expect(serviceQueryResult.getResources()).andReturn(mapServiceResources);
-//        expect(serviceResourceDef.getId()).andReturn(null);
-//        expect(serviceResourceDef.getPluralName()).andReturn("services");
-//        result.addResources("services",listServiceResources);
-//
-//        expect(hostQuery.execute()).andReturn(hostQueryResult);
-//        expect(hostQueryResult.getResources()).andReturn(mapHostResources);
-//        expect(hostResourceDef.getId()).andReturn(null);
-//        expect(hostResourceDef.getPluralName()).andReturn("hosts");
-//        result.addResources("hosts", Collections.singletonList(hostResource));
-//
-//        replay(clusterResourceDef, request, result, m_controller, clusterSchema, clusterResource,
-//                serviceResourceDef, serviceQuery, serviceQueryResult, serviceResource, serviceResource2,
-//                hostResourceDef, hostQuery, hostQueryResult, hostResource);
-//
-//        // test
-//        QueryImpl query = new TestQuery(clusterResourceDef, result, request);
-//        Result testResult = query.execute();
-//        // todo: assert return value.  This is currently a mock.
-//
-//        verify(clusterResourceDef, request, result, m_controller, clusterSchema, clusterResource,
-//                serviceResourceDef, serviceQuery, serviceQueryResult, serviceResource, serviceResource2,
-//                hostResourceDef, hostQuery, hostQueryResult, hostResource);
-//    }
-//
-//    private class TestQuery extends QueryImpl {
-//
-//        private Result m_result;
-//        private Request m_request;
-//
-//        public TestQuery(ResourceDefinition resourceDefinition, Result result, Request request) {
-//            super(resourceDefinition);
-//            m_result = result;
-//            m_request = request;
-//        }
-//
-//        @Override
-//        Result createResult() {
-//            return m_result;
-//        }
-//
-//        @Override
-//        Request createRequest() {
-//            return m_request;
-//        }
-//
-//        @Override
-//        ClusterController getClusterController() {
-//            return m_controller;
-//        }
-//    }
-//
-//    @After
-//    public void resetGlobalMocks() {
-//        reset(m_controller);
-//    }
+  ClusterController m_controller = createMock(ClusterController.class);
+
+  @Test
+  public void testExecute__Component_instance_noSpecifiedProps() throws Exception {
+    Result result = createStrictMock(Result.class);
+    TreeNode<Resource> tree = createStrictMock(TreeNode.class);
+    TreeNode<Resource> componentNode = createStrictMock(TreeNode.class);
+    ResourceDefinition componentResourceDef = createMock(ResourceDefinition.class);
+    ResourceDefinition hostComponentResourceDef = createStrictMock(ResourceDefinition.class);
+    Schema componentSchema = createMock(Schema.class);
+    Resource componentResource = createStrictMock(Resource.class);
+    PropertyId componentPropertyId = PropertyHelper.getPropertyId("componentId", "");
+    Query hostComponentQuery = createStrictMock(Query.class);
+    Result hostComponentQueryResult = createStrictMock(Result.class);
+    TreeNode<Resource> hostComponentResultTree = createMock(TreeNode.class);
+
+    List<Resource> listResources = Collections.singletonList(componentResource);
+
+    Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
+    mapResourceIds.put(Resource.Type.Cluster, "clusterName");
+    mapResourceIds.put(Resource.Type.Service, "serviceName");
+    mapResourceIds.put(Resource.Type.Component, "componentName");
+
+    Map<String, ResourceDefinition> mapChildren = new HashMap<String, ResourceDefinition>();
+    mapChildren.put("host_components", hostComponentResourceDef);
+
+    PredicateBuilder pb = new PredicateBuilder();
+    Predicate predicate = pb.property("clusterId", "").equals("clusterName").and().
+        property("serviceId", "").equals("serviceName").and().
+        property("componentId", "").equals("componentName").toPredicate();
+
+
+    // expectations
+    expect(componentResourceDef.getId()).andReturn("componentName").atLeastOnce();
+    expect(m_controller.getSchema(Resource.Type.Component)).andReturn(componentSchema).atLeastOnce();
+    expect(componentSchema.getCategories()).andReturn(Collections.<String, Set<String>>emptyMap());
+    expect(componentResourceDef.getSubResources()).andReturn(mapChildren);
+    expect(componentResourceDef.getType()).andReturn(Resource.Type.Component).atLeastOnce();
+    expect(componentResourceDef.getResourceIds()).andReturn(mapResourceIds);
+    expect(componentSchema.getKeyPropertyId(Resource.Type.Cluster)).andReturn(new PropertyIdImpl("clusterId", "", false));
+    expect(componentSchema.getKeyPropertyId(Resource.Type.Service)).andReturn(new PropertyIdImpl("serviceId", "", false));
+    expect(componentSchema.getKeyPropertyId(Resource.Type.Component)).andReturn(componentPropertyId).atLeastOnce();
+
+    expect(m_controller.getResources(eq(Resource.Type.Component), eq(PropertyHelper.getReadRequest(Collections.<PropertyId>emptySet())),
+        eq(predicate))).andReturn(listResources);
+
+    expect(result.getResultTree()).andReturn(tree);
+    expect(tree.addChild(componentResource, null)).andReturn(componentNode);
+    expect(componentNode.addChild(hostComponentResultTree)).andReturn(hostComponentResultTree);
+    expect(componentResource.getPropertyValue(componentPropertyId)).andReturn("componentName");
+    hostComponentResourceDef.setParentId(Resource.Type.Component, "componentName");
+    expect(hostComponentResourceDef.getQuery()).andReturn(hostComponentQuery);
+    expect(hostComponentQuery.execute()).andReturn(hostComponentQueryResult);
+    expect(hostComponentQueryResult.getResultTree()).andReturn(hostComponentResultTree);
+    hostComponentResultTree.setName("host_components");
+    hostComponentResultTree.setProperty("isCollection", "false");
+
+    replay(m_controller, result, tree, componentNode, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
+        hostComponentQuery, hostComponentQueryResult, hostComponentResultTree);
+
+    QueryImpl query = new TestQuery(componentResourceDef, result);
+    query.execute();
+
+    verify(m_controller, result, tree, componentNode, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
+        hostComponentQuery, hostComponentQueryResult, hostComponentResultTree);
+  }
+
+  @Test
+  public void testExecute__Component_collection_noSpecifiedProps() throws Exception {
+    Result result = createStrictMock(Result.class);
+    TreeNode<Resource> tree = createStrictMock(TreeNode.class);
+    TreeNode<Resource> componentNode = createStrictMock(TreeNode.class);
+    ResourceDefinition componentResourceDef = createMock(ResourceDefinition.class);
+    ResourceDefinition hostComponentResourceDef = createStrictMock(ResourceDefinition.class);
+    Schema componentSchema = createMock(Schema.class);
+    Resource componentResource = createStrictMock(Resource.class);
+    PropertyId componentPropertyId = PropertyHelper.getPropertyId("componentId", "");
+    Query hostComponentQuery = createStrictMock(Query.class);
+    Result hostComponentQueryResult = createStrictMock(Result.class);
+    TreeNode<Resource> hostComponentResultTree = createMock(TreeNode.class);
+
+    Map<String, Set<String>> mapProperties = new HashMap<String, Set<String>>();
+    mapProperties.put("", Collections.singleton("componentId"));
+
+    List<Resource> listResources = Collections.singletonList(componentResource);
+
+    Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
+    mapResourceIds.put(Resource.Type.Cluster, "clusterName");
+    mapResourceIds.put(Resource.Type.Service, "serviceName");
+    mapResourceIds.put(Resource.Type.Component, "componentName");
+
+    PredicateBuilder pb = new PredicateBuilder();
+    Predicate predicate = pb.property("clusterId", "").equals("clusterName").and().
+        property("serviceId", "").equals("serviceName").and().
+        property("componentId", "").equals("componentName").toPredicate();
+
+    // expectations
+    expect(componentResourceDef.getId()).andReturn(null).atLeastOnce();
+    expect(m_controller.getSchema(Resource.Type.Component)).andReturn(componentSchema).atLeastOnce();
+    expect(componentSchema.getCategories()).andReturn(mapProperties);
+
+    expect(componentSchema.getKeyPropertyId(Resource.Type.Component)).andReturn(componentPropertyId).atLeastOnce();
+    expect(result.getResultTree()).andReturn(tree).atLeastOnce();
+    tree.setProperty("isCollection", "true");
+
+    expect(componentResourceDef.getType()).andReturn(Resource.Type.Component).atLeastOnce();
+    expect(componentResourceDef.getResourceIds()).andReturn(mapResourceIds);
+    expect(componentSchema.getKeyPropertyId(Resource.Type.Cluster)).andReturn(new PropertyIdImpl("clusterId", "", false));
+    expect(componentSchema.getKeyPropertyId(Resource.Type.Service)).andReturn(new PropertyIdImpl("serviceId", "", false));
+
+
+    expect(m_controller.getResources(eq(Resource.Type.Component), eq(PropertyHelper.getReadRequest(Collections.singleton(componentPropertyId))),
+        eq(predicate))).andReturn(listResources);
+
+
+    expect(tree.addChild(componentResource, null)).andReturn(componentNode);
+
+    replay(m_controller, result, tree, componentNode, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
+        hostComponentQuery, hostComponentQueryResult, hostComponentResultTree);
+
+    QueryImpl query = new TestQuery(componentResourceDef, result);
+    query.execute();
+
+    verify(m_controller, result, tree, componentNode, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
+        hostComponentQuery, hostComponentQueryResult, hostComponentResultTree);
+  }
+
+  @Test
+  public void testAddProperty__localProperty() {
+    ResourceDefinition resource = createMock(ResourceDefinition.class);
+    Schema schema = createMock(Schema.class);
+
+    Map<String, Set<String>> mapSchemaProps = new HashMap<String, Set<String>>();
+    mapSchemaProps.put("category", Collections.singleton("property"));
+    mapSchemaProps.put(null, Collections.singleton("property2"));
+
+    //expectations
+    expect(resource.getType()).andReturn(Resource.Type.Service).atLeastOnce();
+    expect(m_controller.getSchema(Resource.Type.Service)).andReturn(schema);
+    expect(schema.getCategories()).andReturn(mapSchemaProps);
+
+    replay(m_controller, resource, schema);
+
+    Query query = new TestQuery(resource, null);
+    query.addProperty("category", "property");
+
+    assertEquals(1, query.getProperties().size());
+    assertEquals(Collections.singleton("property"), query.getProperties().get("category"));
+
+    query.addProperty(null, "property2");
+
+    assertEquals(2, query.getProperties().size());
+    assertEquals(Collections.singleton("property2"), query.getProperties().get(null));
+
+    verify(m_controller, resource, schema);
+  }
+
+  @Test
+  public void testAddProperty__localCategory() {
+    ResourceDefinition resource = createMock(ResourceDefinition.class);
+    Schema schema = createMock(Schema.class);
+
+    Map<String, Set<String>> mapSchemaProps = new HashMap<String, Set<String>>();
+    Set<String> setProps = new HashSet<String>();
+    setProps.add("property");
+    setProps.add("property2");
+    mapSchemaProps.put("category", setProps);
+    mapSchemaProps.put(null, Collections.singleton("property3"));
+
+    //expectations
+    expect(resource.getType()).andReturn(Resource.Type.Service).atLeastOnce();
+    expect(m_controller.getSchema(Resource.Type.Service)).andReturn(schema);
+    expect(schema.getCategories()).andReturn(mapSchemaProps);
+
+    replay(m_controller, resource, schema);
+
+    Query query = new TestQuery(resource, null);
+    query.addProperty(null, "category");
+
+    assertEquals(1, query.getProperties().size());
+    Set<String> setResultProps = query.getProperties().get("category");
+    assertEquals(2, setResultProps.size());
+    assertTrue(setResultProps.contains("property"));
+    assertTrue(setResultProps.contains("property2"));
+
+    verify(m_controller, resource, schema);
+  }
+
+  @Test
+  public void testAddProperty__subProperty() {
+    ResourceDefinition resource = createMock(ResourceDefinition.class);
+    ResourceDefinition subResource = createMock(ResourceDefinition.class);
+    Schema schema = createMock(Schema.class);
+
+    Map<String, Set<String>> mapSchemaProps = new HashMap<String, Set<String>>();
+    mapSchemaProps.put("category", Collections.singleton("property"));
+    mapSchemaProps.put(null, Collections.singleton("property2"));
+
+    //expectations
+    expect(resource.getType()).andReturn(Resource.Type.Service).atLeastOnce();
+    expect(m_controller.getSchema(Resource.Type.Service)).andReturn(schema);
+    expect(schema.getCategories()).andReturn(mapSchemaProps);
+
+    expect(resource.getSubResources()).andReturn(Collections.singletonMap("components", subResource));
+
+    //todo: ensure that sub-resource was added.
+
+    replay(m_controller, resource, subResource, schema);
+
+    Query query = new TestQuery(resource, null);
+    query.addProperty(null, "components");
+
+    verify(m_controller, resource, subResource, schema);
+  }
+
+  //todo: sub-resource with property and with sub-path
+
+  @Test
+  public void testAddProperty__invalidProperty() {
+
+  }
+
+  private class TestQuery extends QueryImpl {
+
+    private Result m_result;
+
+    public TestQuery(ResourceDefinition resourceDefinition, Result result) {
+      super(resourceDefinition);
+      m_result = result;
+    }
+
+    @Override
+    ClusterController getClusterController() {
+      return m_controller;
+    }
+
+    @Override
+    Result createResult() {
+      return m_result;
+    }
+  }
+
+  @After
+  public void resetGlobalMocks() {
+    reset(m_controller);
+  }
 }

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/DeletePersistenceManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/DeletePersistenceManagerTest.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/DeletePersistenceManagerTest.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/DeletePersistenceManagerTest.java Tue Oct 16 06:13:44 2012
@@ -42,7 +42,7 @@ public class DeletePersistenceManagerTes
     //expectations
     expect(resource.getType()).andReturn(Resource.Type.Component);
     expect(resource.getQuery()).andReturn(query);
-    expect(query.getPredicate()).andReturn(predicate);
+    expect(query.getInternalPredicate()).andReturn(predicate);
 
     controller.deleteResources(Resource.Type.Component, predicate);
 

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java?rev=1398662&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java Tue Oct 16 06:13:44 2012
@@ -0,0 +1,55 @@
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceDefinition;
+import org.apache.ambari.server.controller.predicate.*;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: john
+ * Date: 10/12/12
+ * Time: 11:30 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class RequestImplTest {
+
+  @Test
+  public void testGetQueryPredicate() {
+
+    Request request = new TestRequest(null, null, null, Request.Type.GET, null);
+    Predicate predicate = request.getQueryPredicate();
+
+    Set<Predicate> setPredicates = new HashSet<Predicate>();
+    setPredicates.add(new EqualsPredicate(PropertyHelper.getPropertyId("foo"), "bar"));
+    setPredicates.add(new NotPredicate(new EqualsPredicate(PropertyHelper.getPropertyId("prop"), "5")));
+    setPredicates.add(new GreaterPredicate(PropertyHelper.getPropertyId("prop2"), "10"));
+    setPredicates.add(new GreaterEqualsPredicate(PropertyHelper.getPropertyId("prop3"), "20"));
+    setPredicates.add(new LessPredicate(PropertyHelper.getPropertyId("prop4"), "500"));
+    setPredicates.add(new LessEqualsPredicate(PropertyHelper.getPropertyId("prop5"), "1"));
+    Predicate expectedPredicate = new AndPredicate(setPredicates.toArray(new BasePredicate[6]));
+
+    assertEquals(expectedPredicate, predicate);
+  }
+
+  private class TestRequest extends RequestImpl {
+    private TestRequest(HttpHeaders headers, String body, UriInfo uriInfo, Type requestType, ResourceDefinition resourceDefinition) {
+      super(headers, body, uriInfo, requestType, resourceDefinition);
+    }
+
+    @Override
+    public String getURI() {
+      return ("http://foo.bar.com/api/v1/clusters?foo=bar&prop!=5&prop2>10&prop3>=20&prop4<500&prop5<=1&fields=field1,category/field2");
+    }
+  }
+}

Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/UpdatePersistenceManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/UpdatePersistenceManagerTest.java?rev=1398662&r1=1398661&r2=1398662&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/UpdatePersistenceManagerTest.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/UpdatePersistenceManagerTest.java Tue Oct 16 06:13:44 2012
@@ -54,7 +54,7 @@ public class UpdatePersistenceManagerTes
     expect(resource.getType()).andReturn(Resource.Type.Component);
     expect(resource.getProperties()).andReturn(mapProperties);
     expect(resource.getQuery()).andReturn(query);
-    expect(query.getPredicate()).andReturn(predicate);
+    expect(query.getInternalPredicate()).andReturn(predicate);
 
     controller.updateResources(Resource.Type.Component, serverRequest, predicate);