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/24 08:05:33 UTC
svn commit: r1401562 [1/2] - in /incubator/ambari/branches/AMBARI-666: ./
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/
ambari-server/src/main/java/org/apache/ambari/server/api/query/
ambari-server/src/main/java/org/apache/ambari/s...
Author: mahadev
Date: Wed Oct 24 06:05:32 2012
New Revision: 1401562
URL: http://svn.apache.org/viewvc?rev=1401562&view=rev
Log:
AMBARI-893. provide api support for temporal queries. (John Speidel via mahadev)
Added:
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TemporalInfoImpl.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/TemporalInfo.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/
incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/JsonSerializerTest.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/resources/HostComponentResourceDefinition.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/ServiceService.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNode.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNodeImpl.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.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/internal/ResourceImpl.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.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/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/RequestImplTest.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/controller/jmx/TestStreamProvider.java
incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/controller/predicate/ResourceImpl.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=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt (original)
+++ incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt Wed Oct 24 06:05:32 2012
@@ -12,6 +12,9 @@ AMBARI-666 branch (unreleased changes)
NEW FEATURES
+ AMBARI-893. provide api support for temporal queries. (John Speidel via
+ mahadev)
+
AMBARI-897. Operations request object and skeleton management methods.
(jitendra)
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -22,6 +22,10 @@ import org.apache.ambari.server.api.serv
import org.apache.ambari.server.api.services.Result;
import org.apache.ambari.server.api.query.Query;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
+
+import java.util.Map;
/**
* Responsible for read requests.
@@ -33,13 +37,10 @@ public class ReadHandler implements Requ
Query query = request.getResourceDefinition().getQuery();
//Partial response
- for (String s : request.getPartialResponseFields()) {
- int i = s.lastIndexOf('/');
- if (i == -1) {
- query.addProperty(null, s);
- } else {
- query.addProperty(s.substring(0, i), s.substring(i + 1));
- }
+ for (Map.Entry<PropertyId, TemporalInfo> entry : request.getFields().entrySet()) {
+ // Iterate over map and add props/temporalInfo
+ PropertyId propertyId = entry.getKey();
+ query.addProperty(propertyId.getCategory(), propertyId.getName(), entry.getValue());
}
query.setUserPredicate(request.getQueryPredicate());
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -22,6 +22,7 @@ import org.apache.ambari.server.api.serv
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
import java.util.Map;
import java.util.Set;
@@ -38,8 +39,9 @@ public interface Query {
*
* @param group the group name that contains the property
* @param property the property name
+ * @param temporalInfo
*/
- public void addProperty(String group, String property);
+ public void addProperty(String group, String property, TemporalInfo temporalInfo);
/**
* Add a property to the query.
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -20,6 +20,7 @@ package org.apache.ambari.server.api.que
import org.apache.ambari.server.api.resources.ResourceDefinition;
import org.apache.ambari.server.api.services.ResultImpl;
+import org.apache.ambari.server.api.util.TreeNodeImpl;
import org.apache.ambari.server.controller.internal.PropertyIdImpl;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
@@ -48,11 +49,23 @@ public class QueryImpl implements Query
private Map<String, Set<String>> m_mapQueryProperties = new HashMap<String, Set<String>>();
/**
+ * Map that associates each property set on the query to temporal data.
+ */
+ private Map<PropertyId, TemporalInfo> m_mapPropertyTemporalInfo = new HashMap<PropertyId, TemporalInfo>();
+
+ private Map<String, TemporalInfo> m_mapCategoryTemporalInfo = new HashMap<String, TemporalInfo>();
+
+ /**
* All properties that are available for the resource.
*/
private Map<String, Set<String>> m_mapAllProperties;
/**
+ * Tree index of m_mapAllProperties. Used to match sub-categories.
+ */
+ TreeNode<Set<String>> m_treeAllProperties = new TreeNodeImpl<Set<String>>(null, new HashSet<String>(), null);
+
+ /**
* Sub-resources of the resource which is being operated on.
*/
private Map<String, ResourceDefinition> m_mapSubResources = new HashMap<String, ResourceDefinition>();
@@ -72,45 +85,40 @@ public class QueryImpl implements Query
m_resourceDefinition = resourceDefinition;
m_mapAllProperties = Collections.unmodifiableMap(getClusterController().
getSchema(resourceDefinition.getType()).getCategories());
+ buildAllPropertiesTree();
}
@Override
- public void addProperty(String path, String property) {
- if (path == null && property.equals("*")) {
+ //todo: consider requiring a path and a property. For categories the property name '*' could be used.
+ public void addProperty(String category, String property, TemporalInfo temporalInfo) {
+ if (category == null && property.equals("*")) {
// wildcard
- addAllProperties();
- } else if (m_mapAllProperties.containsKey(path) && m_mapAllProperties.get(path).contains(property)) {
+ addAllProperties(temporalInfo);
+ } else if (m_mapAllProperties.containsKey(category) && m_mapAllProperties.get(category).contains(property)) {
// local property
- Set<String> setProps = m_mapQueryProperties.get(path);
+ Set<String> setProps = m_mapQueryProperties.get(category);
if (setProps == null) {
setProps = new HashSet<String>();
- m_mapQueryProperties.put(path, setProps);
+ m_mapQueryProperties.put(category, setProps);
}
setProps.add(property);
- } else if (m_mapAllProperties.containsKey(property)) {
- // no path specified because path is provided as property
- //local category
- Set<String> setProps = m_mapQueryProperties.get(property);
- if (setProps == null) {
- setProps = new HashSet<String>();
- m_mapQueryProperties.put(property, setProps);
+ if (temporalInfo != null) {
+ m_mapPropertyTemporalInfo.put(PropertyHelper.getPropertyId(property, category, true), temporalInfo);
}
- // add all props for category
- setProps.addAll(m_mapAllProperties.get(property));
- } else {
+ } else if (! addCategory(category, property, temporalInfo)){
// not a local category/property
- boolean success = addPropertyToSubResource(path, property);
+ boolean success = addPropertyToSubResource(category, property, temporalInfo);
if (!success) {
//TODO
throw new RuntimeException("Attempted to add invalid property to resource. Resource=" +
- m_resourceDefinition.getType() + ", Property: Category=" + path + " Field=" + property);
+ m_resourceDefinition.getType() + ", Property: Category=" + category + " Field=" + property);
}
}
}
@Override
public void addProperty(PropertyId property) {
- addProperty(property.getCategory(), property.getName());
+ addProperty(property.getCategory(), property.getName(), null);
}
@Override
@@ -134,8 +142,10 @@ public class QueryImpl implements Query
m_resourceDefinition.getType(), createRequest(), predicate);
TreeNode<Resource> tree = result.getResultTree();
+ int count = 1;
for (Resource resource : iterResource) {
- TreeNode<Resource> node = tree.addChild(resource, null);
+ // add a child node for the resource and provide a unique name. The name is never used.
+ TreeNode<Resource> node = tree.addChild(resource, resource.getType() + ":" + count++);
for (Map.Entry<String, ResourceDefinition> entry : m_mapSubResources.entrySet()) {
String subResCategory = entry.getKey();
@@ -151,7 +161,6 @@ public class QueryImpl implements Query
node.addChild(childResult);
}
}
-
return result;
}
@@ -170,8 +179,18 @@ public class QueryImpl implements Query
m_userPredicate = predicate;
}
- private void addAllProperties() {
- m_mapQueryProperties.putAll(m_mapAllProperties);
+ private void addAllProperties(TemporalInfo temporalInfo) {
+ if (temporalInfo == null) {
+ m_mapQueryProperties.putAll(m_mapAllProperties);
+ } else {
+ for (Map.Entry<String, Set<String>> entry : m_mapAllProperties.entrySet()) {
+ String path = entry.getKey();
+ Set<String> setProps = entry.getValue();
+ m_mapQueryProperties.put(path, setProps);
+ m_mapCategoryTemporalInfo.put(path, temporalInfo);
+ }
+ }
+
for (Map.Entry<String, ResourceDefinition> entry : m_resourceDefinition.getSubResources().entrySet()) {
String name = entry.getKey();
if (! m_mapSubResources.containsKey(name)) {
@@ -180,7 +199,34 @@ public class QueryImpl implements Query
}
}
- private boolean addPropertyToSubResource(String path, String property) {
+ private boolean addCategory(String category, String name, TemporalInfo temporalInfo) {
+ name = category != null ? category + '/' + name : name;
+ TreeNode<Set<String>> node = m_treeAllProperties.getChild(name);
+ if (node == null) {
+ return false;
+ }
+
+ addCategory(node, name, temporalInfo);
+ return true;
+ }
+
+ private void addCategory(TreeNode<Set<String>> node, String category, TemporalInfo temporalInfo) {
+ if (node != null) {
+ Set<String> setProps = m_mapQueryProperties.get(category);
+ if (setProps == null) {
+ setProps = new HashSet<String>();
+ m_mapQueryProperties.put(category, setProps);
+ }
+ setProps.addAll(node.getObject());
+ m_mapCategoryTemporalInfo.put(category, temporalInfo);
+
+ for (TreeNode<Set<String>> child : node.getChildren()) {
+ addCategory(child, category + '/' + child.getName(), temporalInfo);
+ }
+ }
+ }
+
+ private boolean addPropertyToSubResource(String path, String property, TemporalInfo temporalInfo) {
// cases:
// - path is null, property is path (all sub-resource props will have a path)
// - path is single token and prop in non null
@@ -203,7 +249,7 @@ public class QueryImpl implements Query
if (property != null || !path.equals(p)) {
//only add if a sub property is set or if a sub category is specified
- subResource.getQuery().addProperty(i == -1 ? null : path.substring(i + 1), property);
+ subResource.getQuery().addProperty(i == -1 ? null : path.substring(i + 1), property, temporalInfo);
}
resourceAdded = true;
}
@@ -244,12 +290,35 @@ public class QueryImpl implements Query
predicate = m_userPredicate;
}
} else {
- predicate = (m_userPredicate == null) ? internalPredicate :
- new AndPredicate((BasePredicate) m_userPredicate, internalPredicate);
+ predicate = (m_userPredicate == null ? internalPredicate :
+ new AndPredicate((BasePredicate) m_userPredicate, internalPredicate));
}
return predicate;
}
+ private void buildAllPropertiesTree() {
+ // build index
+ for (String category : m_mapAllProperties.keySet()) {
+ TreeNode<Set<String>> node = m_treeAllProperties.getChild(category);
+ if (node == null) {
+ if (category == null) {
+ node = m_treeAllProperties.addChild(new HashSet<String>(), null);
+ } else {
+ String[] tokens = category.split("/");
+ node = m_treeAllProperties;
+ for (String t : tokens) {
+ TreeNode<Set<String>> child = node.getChild(t);
+ if (child == null) {
+ child = node.addChild(new HashSet<String>(), t);
+ }
+ node = child;
+ }
+ }
+ }
+ node.getObject().addAll(m_mapAllProperties.get(category));
+ }
+ }
+
ClusterController getClusterController() {
return ClusterControllerHelper.getClusterController();
}
@@ -260,14 +329,21 @@ public class QueryImpl implements Query
for (Map.Entry<String, Set<String>> entry : m_mapQueryProperties.entrySet()) {
String group = entry.getKey();
for (String property : entry.getValue()) {
- setProperties.add(new PropertyIdImpl(property, group, false));
+ TemporalInfo temporalInfo = m_mapCategoryTemporalInfo.get(group);
+ if (temporalInfo == null) {
+ temporalInfo = m_mapPropertyTemporalInfo.get(new PropertyIdImpl(property, group, true));
+ }
+ setProperties.add(new PropertyIdImpl(property, group, temporalInfo != null));
}
}
- return PropertyHelper.getReadRequest(setProperties);
+ //todo: need to pass in temporal info
+ Request r = PropertyHelper.getReadRequest(setProperties);
+ r.setTemporalInfo(m_mapPropertyTemporalInfo);
+
+ return r;
}
Result createResult() {
return new ResultImpl();
}
-
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostComponentResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostComponentResourceDefinition.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostComponentResourceDefinition.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostComponentResourceDefinition.java Wed Oct 24 06:05:32 2012
@@ -105,7 +105,7 @@ public class HostComponentResourceDefini
/**
* Host_Component resource processor which is responsible for generating href's for host components.
- * This is called by the {@link org.apache.ambari.server.api.services.ResultPostProcessor} during post processing of a result.
+ * This is called by the ResultPostProcessor during post processing of a result.
*/
private class HostComponentHrefProcessor extends BaseHrefPostProcessor {
@Override
@@ -126,13 +126,12 @@ public class HostComponentResourceDefini
} else {
super.process(request, resultNode, href);
}
-
}
}
/**
* Host_Component resource processor which is responsible for generating a host section for host components.
- * This is called by the {@link org.apache.ambari.server.api.services.ResultPostProcessor} during post processing of a result.
+ * This is called by the ResultPostProcessor during post processing of a result.
*/
private class HostComponentHostProcessor implements PostProcessor {
@Override
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -22,6 +22,7 @@ import org.apache.ambari.server.api.reso
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 org.apache.ambari.server.controller.spi.TemporalInfo;
import java.net.URI;
import java.util.List;
@@ -82,11 +83,12 @@ public interface Request {
public Predicate getQueryPredicate();
/**
- * Obtain the set of partial response fields which were provided in the query string of the request uri.
+ * Obtain the partial response fields and associated temporal information which were provided
+ * in the query string of the request uri.
*
- * @return a set of the provided partial response fields
+ * @return map of partial response propertyId to temporal information
*/
- public Set<String> getPartialResponseFields();
+ public Map<PropertyId, TemporalInfo> getFields();
/**
* Obtain the result serializer for the request. The default serializer is of type JSON.
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -23,9 +23,11 @@ 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.internal.TemporalInfoImpl;
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.spi.TemporalInfo;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import javax.ws.rs.core.HttpHeaders;
@@ -112,7 +114,6 @@ public class RequestImpl implements Requ
String uri = getURI();
int qsBegin = uri.indexOf("?");
- //todo: consider returning an AlwaysPredicate in this case.
if (qsBegin == -1) return null;
Pattern pattern = Pattern.compile("!=|>=|<=|=|>|<");
@@ -141,13 +142,46 @@ public class RequestImpl implements Requ
}
@Override
- public Set<String> getPartialResponseFields() {
+ public Map<PropertyId, TemporalInfo> getFields() {
+ Map<PropertyId, TemporalInfo> mapProperties;
String partialResponseFields = m_uriInfo.getQueryParameters().getFirst("fields");
if (partialResponseFields == null) {
- return Collections.emptySet();
+ mapProperties = Collections.emptyMap();
} else {
- return new HashSet<String>(Arrays.asList(partialResponseFields.split(",")));
+ Set<String> setMatches = new HashSet<String>();
+ // Pattern basically splits a string using ',' as the deliminator unless ',' is between '[' and ']'.
+ // Actually, captures char sequences between ',' and all chars between '[' and ']' including ','.
+ Pattern re = Pattern.compile("[^,\\[]*?\\[[^\\]]*?\\]|[^,]+");
+ Matcher m = re.matcher(partialResponseFields);
+ while (m.find()){
+ for (int groupIdx = 0; groupIdx < m.groupCount() + 1; groupIdx++) {
+ setMatches.add(m.group(groupIdx));
+ }
+ }
+
+ mapProperties = new HashMap<PropertyId, TemporalInfo>(setMatches.size());
+ for (String field : setMatches) {
+ TemporalInfo temporalInfo = null;
+ if (field.contains("[")) {
+ String[] temporalData = field.substring(field.indexOf('[') + 1, field.indexOf(']')).split(",");
+ field = field.substring(0, field.indexOf('['));
+ long start = Long.parseLong(temporalData[0]);
+ long end = -1;
+ long step = -1;
+ if (temporalData.length >= 2) {
+ end = Long.parseLong(temporalData[1]);
+ if (temporalData.length == 3) {
+ step = Long.parseLong(temporalData[2]);
+ }
+ }
+ temporalInfo = new TemporalInfoImpl(start, end, step);
+ }
+ mapProperties.put(PropertyHelper.getPropertyId(
+ field, temporalInfo == null ? false : true), temporalInfo);
+ }
}
+
+ return mapProperties;
}
@Override
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java Wed Oct 24 06:05:32 2012
@@ -57,7 +57,7 @@ public class ServiceService extends Base
public Response getService(@Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("serviceName") String serviceName) {
- return handleRequest(headers, null, ui, org.apache.ambari.server.api.services.Request.Type.GET,
+ return handleRequest(headers, null, ui, Request.Type.GET,
createResourceDefinition(serviceName, m_clusterName));
}
@@ -72,7 +72,7 @@ public class ServiceService extends Base
@GET
@Produces("text/plain")
public Response getServices(@Context HttpHeaders headers, @Context UriInfo ui) {
- return handleRequest(headers, null, ui, org.apache.ambari.server.api.services.Request.Type.GET,
+ return handleRequest(headers, null, ui, Request.Type.GET,
createResourceDefinition(null, m_clusterName));
}
@@ -92,7 +92,8 @@ public class ServiceService extends Base
public Response createService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("serviceName") String serviceName) {
- return handleRequest(headers, body, ui, org.apache.ambari.server.api.services.Request.Type.PUT, createResourceDefinition(serviceName, m_clusterName));
+ return handleRequest(headers, body, ui, Request.Type.PUT,
+ createResourceDefinition(serviceName, m_clusterName));
}
/**
@@ -111,7 +112,7 @@ public class ServiceService extends Base
public Response updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("serviceName") String serviceName) {
- return handleRequest(headers, body, ui, org.apache.ambari.server.api.services.Request.Type.POST, createResourceDefinition(serviceName, m_clusterName));
+ return handleRequest(headers, body, ui, Request.Type.POST, createResourceDefinition(serviceName, m_clusterName));
}
/**
@@ -129,7 +130,7 @@ public class ServiceService extends Base
public Response deleteService(@Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("serviceName") String serviceName) {
- return handleRequest(headers, null, ui, org.apache.ambari.server.api.services.Request.Type.DELETE, createResourceDefinition(serviceName, m_clusterName));
+ return handleRequest(headers, null, ui, Request.Type.DELETE, createResourceDefinition(serviceName, m_clusterName));
}
/**
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java Wed Oct 24 06:05:32 2012
@@ -21,6 +21,7 @@ package org.apache.ambari.server.api.ser
import org.apache.ambari.server.api.services.Result;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.log4j.Category;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.util.DefaultPrettyPrinter;
@@ -82,7 +83,7 @@ public class JsonSerializer implements R
m_generator.writeStartObject();
writeHref(node);
// resource props
- handleResourceProperties(r.getCategories());
+ handleResourceProperties(r.getProperties());
}
for (TreeNode<Resource> child : node.getChildren()) {
@@ -101,22 +102,24 @@ public class JsonSerializer implements R
}
}
- private void handleResourceProperties(Map<String, Map<String, Object>> mapCatProps) throws IOException {
- for (Map.Entry<String, Map<String, Object>> categoryEntry : mapCatProps.entrySet()) {
- String category = categoryEntry.getKey();
- Map<String, Object> mapProps = categoryEntry.getValue();
- if (category != null) {
- m_generator.writeFieldName(category);
- m_generator.writeStartObject();
- }
+ private void handleResourceProperties(TreeNode<Map<String, Object>> node) throws IOException {
+ String category = node.getName();
- for (Map.Entry<String, Object> propEntry : mapProps.entrySet()) {
- m_generator.writeObjectField(propEntry.getKey(), propEntry.getValue());
- }
+ if (category != null) {
+ m_generator.writeFieldName(category);
+ m_generator.writeStartObject();
+ }
- if (category != null) {
- m_generator.writeEndObject();
- }
+ for (Map.Entry<String, Object> entry : node.getObject().entrySet()) {
+ m_generator.writeObjectField(entry.getKey(), entry.getValue());
+ }
+
+ for (TreeNode<Map<String, Object>> n : node.getChildren()) {
+ handleResourceProperties(n);
+ }
+
+ if (category != null) {
+ m_generator.writeEndObject();
}
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNode.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNode.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNode.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNode.java Wed Oct 24 06:05:32 2012
@@ -18,7 +18,7 @@
package org.apache.ambari.server.api.util;
-import java.util.List;
+import java.util.Collection;
/**
* Tree where each node can have a name, properties and an associated object.
@@ -36,7 +36,7 @@ public interface TreeNode<T> {
*
* @return a list of child nodes or an empty list if a leaf node
*/
- public List<TreeNode<T>> getChildren();
+ public Collection<TreeNode<T>> getChildren();
/**
* Obtain the object associated with this node.
@@ -98,4 +98,15 @@ public interface TreeNode<T> {
* @return the requested property value or null
*/
public String getProperty(String name);
+
+ /**
+ * Find a child node by name.
+ * The name may contain '/' to delimit names to find a child more then one level deep.
+ * To find a node named 'bar' that is a child of a child named 'foo', use the name 'foo/bar'.
+ *
+ * @param name the name of the child. May contain the '/' path separator.
+ *
+ * @return the requested node or null if the child was not found
+ */
+ public TreeNode<T> getChild(String name);
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNodeImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNodeImpl.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNodeImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/api/util/TreeNodeImpl.java Wed Oct 24 06:05:32 2012
@@ -18,7 +18,7 @@
package org.apache.ambari.server.api.util;
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -41,7 +41,7 @@ public class TreeNodeImpl<T> implements
/**
* child nodes
*/
- private List<TreeNode<T>> m_listChildren = new ArrayList<TreeNode<T>>();
+ private Map<String, TreeNode<T>> m_mapChildren = new HashMap<String, TreeNode<T>>();
/**
* associated object
@@ -72,8 +72,8 @@ public class TreeNodeImpl<T> implements
}
@Override
- public List<TreeNode<T>> getChildren() {
- return m_listChildren;
+ public Collection<TreeNode<T>> getChildren() {
+ return m_mapChildren.values();
}
@Override
@@ -99,7 +99,7 @@ public class TreeNodeImpl<T> implements
@Override
public TreeNode<T> addChild(T child, String name) {
TreeNodeImpl<T> node = new TreeNodeImpl<T>(this, child, name);
- m_listChildren.add(node);
+ m_mapChildren.put(name, node);
return node;
}
@@ -107,7 +107,7 @@ public class TreeNodeImpl<T> implements
@Override
public TreeNode<T> addChild(TreeNode<T> child) {
child.setParent(this);
- m_listChildren.add(child);
+ m_mapChildren.put(child.getName(), child);
return child;
}
@@ -124,4 +124,16 @@ public class TreeNodeImpl<T> implements
public String getProperty(String name) {
return m_mapNodeProps == null ? null : m_mapNodeProps.get(name);
}
+
+ @Override
+ public TreeNode<T> getChild(String name) {
+ if (name != null && name.contains("/")) {
+ int i = name.indexOf('/');
+ String s = name.substring(0, i);
+ TreeNode<T> node = m_mapChildren.get(s);
+ return node == null ? null : node.getChild(name.substring(i + 1));
+ } else {
+ return m_mapChildren.get(name);
+ }
+ }
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java Wed Oct 24 06:05:32 2012
@@ -19,11 +19,8 @@
package org.apache.ambari.server.controller.ganglia;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.PropertyId;
-import org.apache.ambari.server.controller.spi.PropertyProvider;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.internal.TemporalInfoImpl;
+import org.apache.ambari.server.controller.spi.*;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.controller.utilities.StreamProvider;
import org.codehaus.jackson.map.ObjectMapper;
@@ -133,7 +130,7 @@ public class GangliaPropertyProvider imp
// propertyId.getName();
String property = propertyId.getName();
- Request.TemporalInfo temporalInfo = request.getTemporalInfo(propertyId);
+ TemporalInfo temporalInfo = request.getTemporalInfo(propertyId);
String spec = getSpec(gangliaClusterName, hostName, property,
temporalInfo.getStartTime(), temporalInfo.getEndTime(), temporalInfo.getStep());
@@ -193,9 +190,9 @@ public class GangliaPropertyProvider imp
protected String getSpec(String gangliaCluster,
String host,
String metric,
- Long startTime,
- Long endTime,
- Long step) {
+ long startTime,
+ long endTime,
+ long step) {
StringBuilder sb = new StringBuilder();
@@ -208,13 +205,13 @@ public class GangliaPropertyProvider imp
append("&m=").
append(metric);
- if (startTime != null) {
+ if (startTime != -1) {
sb.append("&cs=").append(startTime);
}
- if (endTime != null) {
+ if (endTime != -1) {
sb.append("&ce=").append(endTime);
}
- if (step != null) {
+ if (step != -1) {
sb.append("&step=").append(step);
}
sb.append("&json=1");
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -20,11 +20,9 @@ package org.apache.ambari.server.control
import org.apache.ambari.server.controller.spi.PropertyId;
import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* Default request implementation.
@@ -43,6 +41,13 @@ public class RequestImpl implements Requ
*/
private final Set<Map<PropertyId, Object>> properties;
+ /**
+ * Map of property to temporal info.
+ */
+ private Map<PropertyId, TemporalInfo> m_mapTemporalInfo = new HashMap<PropertyId, TemporalInfo>();
+
+ private static final TemporalInfo DEFAULT_TEMPORAL_INFO = new TemporalInfoImpl(-1, -1, -1);
+
// ----- Constructors ------------------------------------------------------
@@ -77,25 +82,13 @@ public class RequestImpl implements Requ
@Override
public TemporalInfo getTemporalInfo(PropertyId id) {
- return new TemporalInfoImpl();
+ TemporalInfo info = m_mapTemporalInfo.get(id);
+ return info == null ? DEFAULT_TEMPORAL_INFO : info;
}
-
- public static class TemporalInfoImpl implements TemporalInfo {
- @Override
- public Long getStartTime() {
- return null; //TODO
- }
-
- @Override
- public Long getEndTime() {
- return null; //TODO
- }
-
- @Override
- public Long getStep() {
- return null; //TODO
- }
+ @Override
+ public void setTemporalInfo(Map<PropertyId, TemporalInfo> mapTemporalInfo) {
+ m_mapTemporalInfo = mapTemporalInfo;
}
@Override
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java Wed Oct 24 06:05:32 2012
@@ -18,6 +18,8 @@
package org.apache.ambari.server.controller.internal;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.api.util.TreeNodeImpl;
import org.apache.ambari.server.controller.spi.PropertyId;
import org.apache.ambari.server.controller.spi.Resource;
@@ -35,9 +37,11 @@ public class ResourceImpl implements Res
private final Type type;
/**
- * The map of categories/properties for this resource.
+ * Tree of categories/properties.
+ * Each category is a sub node and each node contains a map of properties(n/v pairs).
*/
- private final Map<String, Map<String, Object>> categories = new HashMap<String, Map<String, Object>>();
+ private final TreeNode<Map<String, Object>> m_treeProperties =
+ new TreeNodeImpl<Map<String, Object>>(null, new HashMap<String, Object>(), null);
// ----- Constructors ------------------------------------------------------
@@ -60,33 +64,48 @@ public class ResourceImpl implements Res
}
@Override
- public Map<String, Map<String, Object>> getCategories() {
- return categories;
+ public TreeNode<Map<String, Object>> getProperties() {
+ return m_treeProperties;
}
@Override
- public void setProperty(PropertyId id, Object value) {
- String category = id.getCategory();
+ public Map<String, Map<String, Object>> getPropertiesMap() {
+ Map<String, Map<String, Object>> mapProps = new HashMap<String, Map<String, Object>>();
+ addNodeToMap(m_treeProperties, mapProps, null);
- Map<String, Object> properties = categories.get(category);
+ return mapProps;
+ }
- if (properties == null) {
- properties = new HashMap<String, Object>();
- categories.put(category, properties);
+ @Override
+ public void setProperty(PropertyId id, Object value) {
+ String category = id.getCategory();
+ TreeNode<Map<String, Object>> node;
+ if (category == null) {
+ node = m_treeProperties;
+ } else {
+ node = m_treeProperties.getChild(category);
+ if (node == null) {
+ String[] tokens = category.split("/");
+ node = m_treeProperties;
+ for (String t : tokens) {
+ TreeNode<Map<String, Object>> child = node.getChild(t);
+ if (child == null) {
+ child = node.addChild(new HashMap<String, Object>(), t);
+ }
+ node = child;
+ }
+ }
}
-
- properties.put(id.getName(), value);
+ node.getObject().put(id.getName(), value);
}
@Override
public Object getPropertyValue(PropertyId id) {
+ String category = id.getCategory();
+ TreeNode<Map<String, Object>> node = (category == null) ? m_treeProperties :
+ m_treeProperties.getChild(category);
- Map<String, Object> properties = categories.get(id.getCategory());
-
- if (properties != null) {
- return properties.get(id.getName());
- }
- return null;
+ return node == null ? null : node.getObject().get(id.getName());
}
@@ -97,11 +116,53 @@ public class ResourceImpl implements Res
StringBuilder sb = new StringBuilder();
sb.append("Resource : ").append(type).append("\n");
- for (Map.Entry<String, Map<String, Object>> catEntry : categories.entrySet()) {
- for (Map.Entry<String, Object> propEntry : catEntry.getValue().entrySet()) {
- sb.append(" ").append(catEntry.getKey()).append(".").append(propEntry.getKey()).append(" : ").append(propEntry.getValue()).append("\n");
- }
- }
+ sb.append("Properties:\n");
+
+ printPropertyNode(m_treeProperties, sb, null, " ");
+
return sb.toString();
}
+
+
+ // ----- class private methods ---------------------------------------------
+
+ /**
+ * Recursively prints the properties for a given node and it's children to a StringBuffer.
+ *
+ * @param node the node to print properties for
+ * @param sb the SringBuffer to print to
+ * @param category the absolute category name
+ * @param indent the indent to be used
+ */
+ private void printPropertyNode(TreeNode<Map<String, Object>> node, StringBuilder sb, String category, String indent) {
+ if (node.getParent() != null) {
+ category = category == null ? node.getName() : category + '/' + node.getName();
+ sb.append(indent).append("Category: ").append(category).append('\n');
+ indent += " ";
+ }
+ for (Map.Entry<String, Object> entry : node.getObject().entrySet()) {
+ sb.append(indent).append(entry.getKey()).append('=').append(entry.getValue()).append('\n');
+ }
+
+ for (TreeNode<Map<String, Object>> n : node.getChildren()) {
+ printPropertyNode(n, sb, category, indent);
+ }
+ }
+
+ /**
+ * Add the node properties to the specified map.
+ * Makes recursive calls for each child node.
+ *
+ * @param node the node whose properties are to be added
+ * @param mapProps the map that the props are to be added to
+ * @param path the current category hierarchy
+ */
+ private void addNodeToMap(TreeNode<Map<String, Object>> node, Map<String, Map<String, Object>> mapProps, String path) {
+ path = path == null ? node.getName() : path + "/" + node.getName();
+ mapProps.put(path, node.getObject());
+
+ for (TreeNode<Map<String, Object>> child : node.getChildren()) {
+ addNodeToMap(child, mapProps, path);
+ }
+ }
}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TemporalInfoImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TemporalInfoImpl.java?rev=1401562&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TemporalInfoImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/TemporalInfoImpl.java Wed Oct 24 06:05:32 2012
@@ -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.TemporalInfo;
+
+/**
+* Temporal query data.
+*/
+public class TemporalInfoImpl implements TemporalInfo {
+ private long m_startTime;
+ private long m_endTime;
+ private long m_step;
+
+ public TemporalInfoImpl(long startTime, long endTime, long step) {
+ m_startTime = startTime;
+ m_endTime = endTime;
+ m_step = step;
+ }
+
+ @Override
+ public Long getStartTime() {
+ return m_startTime;
+ }
+
+ @Override
+ public Long getEndTime() {
+ return m_endTime;
+ }
+
+ @Override
+ public Long getStep() {
+ return m_step;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TemporalInfoImpl that = (TemporalInfoImpl) o;
+ return m_endTime == that.m_endTime &&
+ m_startTime == that.m_startTime &&
+ m_step == that.m_step;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) (m_startTime ^ (m_startTime >>> 32));
+ result = 31 * result + (int) (m_endTime ^ (m_endTime >>> 32));
+ result = 31 * result + (int) (m_step ^ (m_step >>> 32));
+ return result;
+ }
+}
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java Wed Oct 24 06:05:32 2012
@@ -56,33 +56,5 @@ public interface Request {
*/
public TemporalInfo getTemporalInfo(PropertyId id);
- /**
- * Temporal request information describing a range and increment of time.
- */
- public static interface TemporalInfo {
-
- /**
- * Get the start of the requested time range. The time is given in
- * seconds since the Unix epoch.
- *
- * @return the start time in seconds
- */
- public Long getStartTime();
-
- /**
- * Get the end of the requested time range. The time is given in
- * seconds since the Unix epoch.
- *
- * @return the end time in seconds
- */
- public Long getEndTime();
-
- /**
- * Get the requested time between each data point of the temporal
- * data. The time is given in seconds.
- *
- * @return the step time in seconds
- */
- public Long getStep();
- }
+ public void setTemporalInfo(Map<PropertyId, TemporalInfo> mapTemporalInfo);
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java?rev=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java Wed Oct 24 06:05:32 2012
@@ -17,6 +17,8 @@
*/
package org.apache.ambari.server.controller.spi;
+import org.apache.ambari.server.api.util.TreeNode;
+
import java.util.Map;
/**
@@ -32,13 +34,22 @@ public interface Resource {
public Type getType();
/**
- * Get the map of categories contained by this resource. The map
- * is keyed by the category name and contains maps of properties
- * for each category.
+ * Get the properties contained by this resource.
+ * Each category is contained in a sub-node.
+ *
+ * @return resource properties tree
+ */
+ public TreeNode<Map<String, Object>> getProperties();
+
+ /**
+ * Obtain the properties contained by this group in a map structure.
+ * The category/property hierarchy is flattened into a map where
+ * each key is the absolute category name and the corresponding
+ * value is a map of properties(name/value pairs) for that category.
*
- * @return the map of categories
+ * @return resource properties map
*/
- public Map<String, Map<String, Object>> getCategories();
+ public Map<String, Map<String, Object>> getPropertiesMap();
/**
* Set a property value for the given property id on this resource.
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/TemporalInfo.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/TemporalInfo.java?rev=1401562&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/TemporalInfo.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/TemporalInfo.java Wed Oct 24 06:05:32 2012
@@ -0,0 +1,48 @@
+/**
+ * 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;
+
+/**
+ * Temporal query data.
+ */
+public interface TemporalInfo {
+ /**
+ * Get the start of the requested time range. The time is given in
+ * seconds since the Unix epoch.
+ *
+ * @return the start time in seconds
+ */
+ Long getStartTime();
+
+ /**
+ * Get the end of the requested time range. The time is given in
+ * seconds since the Unix epoch.
+ *
+ * @return the end time in seconds
+ */
+ Long getEndTime();
+
+ /**
+ * Get the requested time between each data point of the temporal
+ * data. The time is given in seconds.
+ *
+ * @return the step time in seconds
+ */
+ Long getStep();
+}
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -82,6 +82,37 @@ public class PropertyHelper {
return getPropertyId(name, category);
}
+ /**
+ * 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
+ * @param temporal whether the property is temporal
+ *
+ * @return a new PropertyId for the provided property string
+ * with the temporal flag set to the provided value
+ */
+ public static PropertyId getPropertyId(String absProperty, boolean temporal) {
+ 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, temporal);
+ }
+
public static Set<PropertyId> getPropertyIds(Resource.Type resourceType, String providerKey) {
Map<String, Set<PropertyId>> propertyIds = PROPERTY_IDS.get(resourceType);
@@ -105,7 +136,7 @@ public class PropertyHelper {
public static Map<PropertyId, Object> getProperties(Resource resource) {
Map<PropertyId, Object> properties = new HashMap<PropertyId, Object>();
- Map<String, Map<String, Object>> categories = resource.getCategories();
+ Map<String, Map<String, Object>> categories = resource.getPropertiesMap();
for (Map.Entry<String, Map<String, Object>> categoryEntry : categories.entrySet()) {
for (Map.Entry<String, Object> propertyEntry : categoryEntry.getValue().entrySet()) {
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -23,10 +23,15 @@ import org.apache.ambari.server.api.reso
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.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.junit.Test;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import static org.easymock.EasyMock.*;
@@ -45,19 +50,23 @@ public class ReadHandlerTest {
Predicate predicate = createMock(Predicate.class);
Result result = createStrictMock(Result.class);
- Set<String> setPartialResponseFields = new HashSet<String>();
- setPartialResponseFields.add("foo");
- setPartialResponseFields.add("bar/c");
- setPartialResponseFields.add("bar/d/e");
+ Map<PropertyId, TemporalInfo> mapPartialResponseFields = new HashMap<PropertyId, TemporalInfo>();
+ mapPartialResponseFields.put(PropertyHelper.getPropertyId("foo"), null);
+ mapPartialResponseFields.put(PropertyHelper.getPropertyId("bar/c"), null);
+ mapPartialResponseFields.put(PropertyHelper.getPropertyId("bar/d/e"), null);
+ //Set<String> setPartialResponseFields = new HashSet<String>();
+// setPartialResponseFields.add("foo");
+// setPartialResponseFields.add("bar/c");
+// setPartialResponseFields.add("bar/d/e");
//expectations
expect(request.getResourceDefinition()).andReturn(resourceDefinition);
expect(resourceDefinition.getQuery()).andReturn(query);
- expect(request.getPartialResponseFields()).andReturn(setPartialResponseFields);
- query.addProperty(null, "foo");
- query.addProperty("bar", "c");
- query.addProperty("bar/d", "e");
+ expect(request.getFields()).andReturn(mapPartialResponseFields);
+ query.addProperty(null, "foo", null);
+ query.addProperty("bar", "c", null);
+ query.addProperty("bar/d", "e", null);
expect(request.getQueryPredicate()).andReturn(predicate);
query.setUserPredicate(predicate);
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=1401562&r1=1401561&r2=1401562&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 Wed Oct 24 06:05:32 2012
@@ -1,6 +1,7 @@
package org.apache.ambari.server.api.query;
import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.api.util.TreeNodeImpl;
import org.apache.ambari.server.controller.internal.PropertyIdImpl;
import org.apache.ambari.server.controller.predicate.AndPredicate;
import org.apache.ambari.server.controller.predicate.BasePredicate;
@@ -29,8 +30,6 @@ public class QueryImplTest {
@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);
@@ -38,8 +37,9 @@ public class QueryImplTest {
PropertyId componentPropertyId = PropertyHelper.getPropertyId("componentId", "");
Query hostComponentQuery = createStrictMock(Query.class);
Result hostComponentQueryResult = createStrictMock(Result.class);
- TreeNode<Resource> hostComponentResultTree = createMock(TreeNode.class);
+ TreeNode<Resource> tree = new TreeNodeImpl<Resource>(null, null, null);
+ TreeNode<Resource> hostComponentResultNode = new TreeNodeImpl<Resource>(null, null, null);
List<Resource> listResources = Collections.singletonList(componentResource);
Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
@@ -55,8 +55,8 @@ public class QueryImplTest {
property("serviceId", "").equals("serviceName").and().
property("componentId", "").equals("componentName").toPredicate();
-
// expectations
+ expect(componentResource.getType()).andReturn(Resource.Type.Component).anyTimes();
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());
@@ -71,31 +71,34 @@ public class QueryImplTest {
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");
+ expect(hostComponentQueryResult.getResultTree()).andReturn(hostComponentResultNode);
+
- replay(m_controller, result, tree, componentNode, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
- hostComponentQuery, hostComponentQueryResult, hostComponentResultTree);
+ replay(m_controller, result, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
+ hostComponentQuery, hostComponentQueryResult);
QueryImpl query = new TestQuery(componentResourceDef, result);
query.execute();
- verify(m_controller, result, tree, componentNode, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
- hostComponentQuery, hostComponentQueryResult, hostComponentResultTree);
+ verify(m_controller, result, componentResourceDef, hostComponentResourceDef, componentSchema, componentResource,
+ hostComponentQuery, hostComponentQueryResult);
+
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> componentNode = tree.getChild("Component:1");
+ assertEquals("Component:1", componentNode.getName());
+ assertEquals(componentResource, componentNode.getObject());
+ assertEquals(1, componentNode.getChildren().size());
+ assertSame(hostComponentResultNode, componentNode.getChild("host_components"));
+ assertEquals("false", hostComponentResultNode.getProperty("isCollection"));
}
@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);
Schema componentSchema = createMock(Schema.class);
Resource componentResource = createStrictMock(Resource.class);
@@ -104,6 +107,7 @@ public class QueryImplTest {
Map<String, Set<String>> mapProperties = new HashMap<String, Set<String>>();
mapProperties.put("", Collections.singleton("componentId"));
+ TreeNode<Resource> tree = new TreeNodeImpl<Resource>(null, null, null);
List<Resource> listResources = Collections.singletonList(componentResource);
Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
@@ -117,13 +121,13 @@ public class QueryImplTest {
property("componentId", "").equals("componentName").toPredicate();
// expectations
+ expect(componentResource.getType()).andReturn(Resource.Type.Component).anyTimes();
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);
@@ -134,43 +138,44 @@ public class QueryImplTest {
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, componentSchema, componentResource);
+ replay(m_controller, result,componentResourceDef, componentSchema, componentResource);
QueryImpl query = new TestQuery(componentResourceDef, result);
query.execute();
- verify(m_controller, result, tree, componentNode, componentResourceDef, componentSchema, componentResource);
+ verify(m_controller, result, componentResourceDef, componentSchema, componentResource);
+
+ assertEquals("true", tree.getProperty("isCollection"));
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> componentNode = tree.getChild("Component:1");
+ assertSame(componentResource, componentNode.getObject());
+ assertEquals(0, componentNode.getChildren().size());
}
@Test
public void testExecute__collection_nullInternalPredicate_nullUserPredicate() throws Exception {
Result result = createStrictMock(Result.class);
- TreeNode<Resource> tree = createStrictMock(TreeNode.class);
- TreeNode<Resource> clusterNode = createStrictMock(TreeNode.class);
ResourceDefinition clusterResourceDef = createMock(ResourceDefinition.class);
Schema clusterSchema = createMock(Schema.class);
Resource clusterResource = createStrictMock(Resource.class);
PropertyId clusterPropertyId = PropertyHelper.getPropertyId("clusterId", "");
-
Map<String, Set<String>> mapProperties = new HashMap<String, Set<String>>();
mapProperties.put("", Collections.singleton("clusterId"));
+ TreeNode<Resource> tree = new TreeNodeImpl<Resource>(null, null, null);
List<Resource> listResources = Collections.singletonList(clusterResource);
Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
// expectations
+ expect(clusterResource.getType()).andReturn(Resource.Type.Cluster).anyTimes();
expect(clusterResourceDef.getId()).andReturn(null).atLeastOnce();
expect(m_controller.getSchema(Resource.Type.Component)).andReturn(clusterSchema).atLeastOnce();
expect(clusterSchema.getCategories()).andReturn(mapProperties);
expect(clusterSchema.getKeyPropertyId(Resource.Type.Component)).andReturn(clusterPropertyId).atLeastOnce();
expect(result.getResultTree()).andReturn(tree).atLeastOnce();
- tree.setProperty("isCollection", "true");
expect(clusterResourceDef.getType()).andReturn(Resource.Type.Component).atLeastOnce();
expect(clusterResourceDef.getResourceIds()).andReturn(mapResourceIds);
@@ -179,43 +184,46 @@ public class QueryImplTest {
(Predicate) isNull())).andReturn(listResources);
- expect(tree.addChild(clusterResource, null)).andReturn(clusterNode);
-
- replay(m_controller, result, tree, clusterNode, clusterResourceDef, clusterSchema, clusterResource);
+ replay(m_controller, result, clusterResourceDef, clusterSchema, clusterResource);
QueryImpl query = new TestQuery(clusterResourceDef, result);
query.execute();
- verify(m_controller, result, tree, clusterNode, clusterResourceDef, clusterSchema, clusterResource);
+ verify(m_controller, result, clusterResourceDef, clusterSchema, clusterResource);
+
+ assertEquals("true", tree.getProperty("isCollection"));
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> clusterNode = tree.getChild("Cluster:1");
+ assertSame(clusterResource, clusterNode.getObject());
+ assertEquals(0, clusterNode.getChildren().size());
+
}
@Test
public void testExecute__collection_nullInternalPredicate_nonNullUserPredicate() throws Exception {
Result result = createStrictMock(Result.class);
- TreeNode<Resource> tree = createStrictMock(TreeNode.class);
- TreeNode<Resource> clusterNode = createStrictMock(TreeNode.class);
ResourceDefinition clusterResourceDef = createMock(ResourceDefinition.class);
Schema clusterSchema = createMock(Schema.class);
Resource clusterResource = createStrictMock(Resource.class);
PropertyId clusterPropertyId = PropertyHelper.getPropertyId("clusterId", "");
Predicate userPredicate = createMock(Predicate.class);
-
Map<String, Set<String>> mapProperties = new HashMap<String, Set<String>>();
mapProperties.put("", Collections.singleton("clusterId"));
+ TreeNode<Resource> tree = new TreeNodeImpl<Resource>(null, null, null);
List<Resource> listResources = Collections.singletonList(clusterResource);
Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
// expectations
+ expect(clusterResource.getType()).andReturn(Resource.Type.Cluster).anyTimes();
expect(clusterResourceDef.getId()).andReturn(null).atLeastOnce();
expect(m_controller.getSchema(Resource.Type.Component)).andReturn(clusterSchema).atLeastOnce();
expect(clusterSchema.getCategories()).andReturn(mapProperties);
expect(clusterSchema.getKeyPropertyId(Resource.Type.Component)).andReturn(clusterPropertyId).atLeastOnce();
expect(result.getResultTree()).andReturn(tree).atLeastOnce();
- tree.setProperty("isCollection", "true");
expect(clusterResourceDef.getType()).andReturn(Resource.Type.Component).atLeastOnce();
expect(clusterResourceDef.getResourceIds()).andReturn(mapResourceIds);
@@ -223,23 +231,24 @@ public class QueryImplTest {
expect(m_controller.getResources(eq(Resource.Type.Component), eq(PropertyHelper.getReadRequest(Collections.singleton(clusterPropertyId))),
eq(userPredicate))).andReturn(listResources);
-
- expect(tree.addChild(clusterResource, null)).andReturn(clusterNode);
-
- replay(m_controller, result, tree, clusterNode, clusterResourceDef, clusterSchema, clusterResource, userPredicate);
+ replay(m_controller, result,clusterResourceDef, clusterSchema, clusterResource, userPredicate);
QueryImpl query = new TestQuery(clusterResourceDef, result);
query.setUserPredicate(userPredicate);
query.execute();
- verify(m_controller, result, tree, clusterNode, clusterResourceDef, clusterSchema, clusterResource, userPredicate);
+ verify(m_controller, result, clusterResourceDef, clusterSchema, clusterResource, userPredicate);
+
+ assertEquals("true", tree.getProperty("isCollection"));
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> clusterNode = tree.getChild("Cluster:1");
+ assertSame(clusterResource, clusterNode.getObject());
+ assertEquals(0, clusterNode.getChildren().size());
}
@Test
public void testExecute__collection_nonNullInternalPredicate_nonNullUserPredicate() throws Exception {
Result result = createStrictMock(Result.class);
- TreeNode<Resource> tree = createStrictMock(TreeNode.class);
- TreeNode<Resource> componentNode = createStrictMock(TreeNode.class);
ResourceDefinition componentResourceDef = createMock(ResourceDefinition.class);
Schema componentSchema = createMock(Schema.class);
Resource componentResource = createStrictMock(Resource.class);
@@ -248,6 +257,7 @@ public class QueryImplTest {
Map<String, Set<String>> mapProperties = new HashMap<String, Set<String>>();
mapProperties.put("", Collections.singleton("componentId"));
+ TreeNode<Resource> tree = new TreeNodeImpl<Resource>(null, null, null);
List<Resource> listResources = Collections.singletonList(componentResource);
Map<Resource.Type, String> mapResourceIds = new HashMap<Resource.Type, String>();
@@ -267,13 +277,13 @@ public class QueryImplTest {
Predicate predicate = new AndPredicate((BasePredicate) internalPredicate, (BasePredicate) userPredicate);
// expectations
+ expect(componentResource.getType()).andReturn(Resource.Type.Component).anyTimes();
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);
@@ -284,16 +294,19 @@ public class QueryImplTest {
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, componentSchema, componentResource);
+ replay(m_controller, result, componentResourceDef, componentSchema, componentResource);
QueryImpl query = new TestQuery(componentResourceDef, result);
query.setUserPredicate(userPredicate);
query.execute();
- verify(m_controller, result, tree, componentNode, componentResourceDef, componentSchema, componentResource);
+ verify(m_controller, result, componentResourceDef, componentSchema, componentResource);
+
+ assertEquals("true", tree.getProperty("isCollection"));
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> componentNode = tree.getChild("Component:1");
+ assertSame(componentResource, componentNode.getObject());
+ assertEquals(0, componentNode.getChildren().size());
}
@Test
@@ -313,12 +326,12 @@ public class QueryImplTest {
replay(m_controller, resource, schema);
Query query = new TestQuery(resource, null);
- query.addProperty("category", "property");
+ query.addProperty("category", "property", null);
assertEquals(1, query.getProperties().size());
assertEquals(Collections.singleton("property"), query.getProperties().get("category"));
- query.addProperty(null, "property2");
+ query.addProperty(null, "property2", null);
assertEquals(2, query.getProperties().size());
assertEquals(Collections.singleton("property2"), query.getProperties().get(null));
@@ -336,7 +349,11 @@ public class QueryImplTest {
setProps.add("property");
setProps.add("property2");
mapSchemaProps.put("category", setProps);
- mapSchemaProps.put(null, Collections.singleton("property3"));
+ Set<String> setInnerProps = new HashSet<String>();
+ setInnerProps.add("property3");
+ setInnerProps.add("property4");
+ mapSchemaProps.put("category/nestedCategory", setInnerProps);
+ mapSchemaProps.put(null, Collections.singleton("property5"));
//expectations
expect(resource.getType()).andReturn(Resource.Type.Service).atLeastOnce();
@@ -346,14 +363,91 @@ public class QueryImplTest {
replay(m_controller, resource, schema);
Query query = new TestQuery(resource, null);
- query.addProperty(null, "category");
+ query.addProperty(null, "category", null);
- assertEquals(1, query.getProperties().size());
- Set<String> setResultProps = query.getProperties().get("category");
+ Map<String, Set<String>> mapProperties = query.getProperties();
+ assertEquals(2, mapProperties.size());
+ Set<String> setResultProps = mapProperties.get("category");
assertEquals(2, setResultProps.size());
assertTrue(setResultProps.contains("property"));
assertTrue(setResultProps.contains("property2"));
+ setResultProps = mapProperties.get("category/nestedCategory");
+ assertEquals(2, setResultProps.size());
+ assertTrue(setResultProps.contains("property3"));
+ assertTrue(setResultProps.contains("property4"));
+
+ verify(m_controller, resource, schema);
+ }
+
+ @Test
+ public void testAddProperty__localSubCategory() {
+ 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);
+ Set<String> setInnerProps = new HashSet<String>();
+ setInnerProps.add("property3");
+ setInnerProps.add("property4");
+ mapSchemaProps.put("category/nestedCategory", setInnerProps);
+ mapSchemaProps.put(null, Collections.singleton("property5"));
+
+ //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", "nestedCategory", null);
+
+ Map<String, Set<String>> mapProperties = query.getProperties();
+ assertEquals(1, mapProperties.size());
+ Set<String >setResultProps = mapProperties.get("category/nestedCategory");
+ assertEquals(2, setResultProps.size());
+ assertTrue(setResultProps.contains("property3"));
+ assertTrue(setResultProps.contains("property4"));
+
+ verify(m_controller, resource, schema);
+ }
+
+ @Test
+ public void testAddProperty__localCategorySubPropsOnly() {
+ ResourceDefinition resource = createMock(ResourceDefinition.class);
+ Schema schema = createMock(Schema.class);
+
+ Map<String, Set<String>> mapSchemaProps = new HashMap<String, Set<String>>();
+ Set<String> setInnerProps = new HashSet<String>();
+ setInnerProps.add("property3");
+ setInnerProps.add("property4");
+ mapSchemaProps.put("category/nestedCategory", setInnerProps);
+ mapSchemaProps.put(null, Collections.singleton("property5"));
+
+ //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", null);
+
+ Map<String, Set<String>> mapProperties = query.getProperties();
+ assertEquals(2, mapProperties.size());
+
+ assertTrue(mapProperties.get("category").isEmpty());
+
+ Set<String> setResultProps = mapProperties.get("category/nestedCategory");
+ assertEquals(2, setResultProps.size());
+ assertTrue(setResultProps.contains("property3"));
+ assertTrue(setResultProps.contains("property4"));
+
verify(m_controller, resource, schema);
}
@@ -379,7 +473,7 @@ public class QueryImplTest {
replay(m_controller, resource, subResource, schema);
Query query = new TestQuery(resource, null);
- query.addProperty(null, "components");
+ query.addProperty(null, "components", null);
verify(m_controller, resource, subResource, schema);
}
Modified: 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=1401562&r1=1401561&r2=1401562&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestImplTest.java Wed Oct 24 06:05:32 2012
@@ -1,18 +1,24 @@
package org.apache.ambari.server.api.services;
import org.apache.ambari.server.api.resources.ResourceDefinition;
+import org.apache.ambari.server.controller.internal.TemporalInfoImpl;
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.spi.TemporalInfo;
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 static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
/**
@@ -42,6 +48,55 @@ public class RequestImplTest {
assertEquals(expectedPredicate, predicate);
}
+ @Test
+ public void testGetFields() {
+ UriInfo uriInfo = createMock(UriInfo.class);
+ MultivaluedMap<String, String> mapQueryParams = createMock(MultivaluedMap.class);
+ String fields = "prop,category/prop1,category2/category3/prop2[1,2,3],prop3[4,5,6],category4[7,8,9],sub-resource/*[10,11,12],finalProp";
+
+ expect(uriInfo.getQueryParameters()).andReturn(mapQueryParams);
+ expect(mapQueryParams.getFirst("fields")).andReturn(fields);
+
+ replay(uriInfo, mapQueryParams);
+
+ Request request = new TestRequest(null, null, uriInfo, Request.Type.GET, null);
+ Map<PropertyId, TemporalInfo> mapFields = request.getFields();
+
+ assertEquals(7, mapFields.size());
+
+ PropertyId prop = PropertyHelper.getPropertyId("prop", null, false);
+ assertTrue(mapFields.containsKey(prop));
+ assertNull(mapFields.get(prop));
+
+ PropertyId prop1 = PropertyHelper.getPropertyId("prop1", "category", false);
+ assertTrue(mapFields.containsKey(prop1));
+ assertNull(mapFields.get(prop1));
+
+ PropertyId prop2 = PropertyHelper.getPropertyId("prop2", "category2/category3", true);
+ assertTrue(mapFields.containsKey(prop2));
+ assertEquals(new TemporalInfoImpl(1, 2, 3), mapFields.get(prop2));
+
+ PropertyId prop3 = PropertyHelper.getPropertyId("prop3", null, true);
+ assertTrue(mapFields.containsKey(prop3));
+ assertEquals(new TemporalInfoImpl(4, 5, 6), mapFields.get(prop3));
+
+ PropertyId category4 = PropertyHelper.getPropertyId("category4", null, true);
+ assertTrue(mapFields.containsKey(category4));
+ assertEquals(new TemporalInfoImpl(7, 8, 9), mapFields.get(category4));
+
+ PropertyId subResource = PropertyHelper.getPropertyId("*", "sub-resource", true);
+ assertTrue(mapFields.containsKey(subResource));
+ assertEquals(new TemporalInfoImpl(10, 11, 12), mapFields.get(subResource));
+
+ PropertyId finalProp = PropertyHelper.getPropertyId("finalProp", null, false);
+ assertTrue(mapFields.containsKey(finalProp));
+ assertNull(mapFields.get(finalProp));
+
+
+ verify(uriInfo, mapQueryParams);
+ }
+
+
private class TestRequest extends RequestImpl {
private TestRequest(HttpHeaders headers, String body, UriInfo uriInfo, Type requestType, ResourceDefinition resourceDefinition) {
super(headers, body, uriInfo, requestType, resourceDefinition);