|
@@ -23,6 +23,7 @@ import org.apache.ambari.server.api.resources.ResourceInstance;
|
|
|
import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
|
|
|
import org.apache.ambari.server.api.resources.SubResourceDefinition;
|
|
|
import org.apache.ambari.server.api.services.ResultImpl;
|
|
|
+import org.apache.ambari.server.controller.predicate.OrPredicate;
|
|
|
import org.apache.ambari.server.controller.utilities.PropertyHelper;
|
|
|
import org.apache.ambari.server.controller.predicate.AndPredicate;
|
|
|
import org.apache.ambari.server.controller.predicate.EqualsPredicate;
|
|
@@ -66,9 +67,9 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
private final Map<Resource.Type, String> keyValueMap = new HashMap<Resource.Type, String>();
|
|
|
|
|
|
/**
|
|
|
- * Set of query results.
|
|
|
+ * Set of maps of primary and foreign key values.
|
|
|
*/
|
|
|
- Set<QueryResult> queryResults = new LinkedHashSet<QueryResult>();
|
|
|
+ Set<Map<Resource.Type, String>> keyValueMaps = new HashSet<Map<Resource.Type, String>>();
|
|
|
|
|
|
/**
|
|
|
* Sub-resources of the resource which is being operated on.
|
|
@@ -96,6 +97,11 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
*/
|
|
|
private PageRequest pageRequest;
|
|
|
|
|
|
+ /**
|
|
|
+ * Query resources.
|
|
|
+ */
|
|
|
+ private Set<Resource> providerResourceSet;
|
|
|
+
|
|
|
/**
|
|
|
* The logger.
|
|
|
*/
|
|
@@ -297,21 +303,14 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
NoSuchResourceException,
|
|
|
NoSuchParentResourceException {
|
|
|
|
|
|
- Set<Resource> providerResourceSet = new LinkedHashSet<Resource>();
|
|
|
-
|
|
|
- Resource.Type resourceType = getResourceDefinition().getType();
|
|
|
- Request request = createRequest();
|
|
|
- Predicate predicate = getPredicate();
|
|
|
-
|
|
|
- Set<Resource> resourceSet = new LinkedHashSet<Resource>();
|
|
|
+ providerResourceSet = new LinkedHashSet<Resource>();
|
|
|
|
|
|
- for (Resource queryResource : doQuery(resourceType, request, predicate)) {
|
|
|
- providerResourceSet.add(queryResource);
|
|
|
- resourceSet.add(queryResource);
|
|
|
+ // save the top level resources
|
|
|
+ for (Resource resource : doQuery(getPredicate())) {
|
|
|
+ providerResourceSet.add(resource);
|
|
|
}
|
|
|
- queryResults.add(new QueryResult(request, predicate, getKeyValueMap(), resourceSet));
|
|
|
+ keyValueMaps.add(getKeyValueMap());
|
|
|
|
|
|
- clusterController.populateResources(resourceType, providerResourceSet, request, predicate);
|
|
|
queryForSubResources();
|
|
|
}
|
|
|
|
|
@@ -326,31 +325,17 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
NoSuchResourceException,
|
|
|
NoSuchParentResourceException {
|
|
|
|
|
|
- for (Map.Entry<String, QueryImpl> entry : querySubResourceSet.entrySet()) {
|
|
|
-
|
|
|
- QueryImpl subResource = entry.getValue();
|
|
|
- Resource.Type resourceType = subResource.getResourceDefinition().getType();
|
|
|
- Request request = subResource.createRequest();
|
|
|
-
|
|
|
- Set<Resource> providerResourceSet = new LinkedHashSet<Resource>();
|
|
|
-
|
|
|
- for (QueryResult queryResult : queryResults) {
|
|
|
- for (Resource resource : queryResult.getProviderResourceSet()) {
|
|
|
+ // get predicates for all of the sub resource types
|
|
|
+ Map<String, Predicate> predicateMap = getSubResourcePredicates(providerResourceSet);
|
|
|
|
|
|
- Map<Resource.Type, String> map = getKeyValueMap(resource, queryResult.getKeyValueMap());
|
|
|
-
|
|
|
- Predicate predicate = subResource.createPredicate(map);
|
|
|
+ for (Map.Entry<String, QueryImpl> entry : querySubResourceSet.entrySet()) {
|
|
|
+ QueryImpl subResource = entry.getValue();
|
|
|
|
|
|
- Set<Resource> resourceSet = new LinkedHashSet<Resource>();
|
|
|
+ subResource.providerResourceSet = new LinkedHashSet<Resource>();
|
|
|
|
|
|
- for (Resource queryResource : subResource.doQuery(resourceType, request, predicate)) {
|
|
|
- providerResourceSet.add(queryResource);
|
|
|
- resourceSet.add(queryResource);
|
|
|
- }
|
|
|
- subResource.queryResults.add(new QueryResult(request, predicate, map, resourceSet));
|
|
|
- }
|
|
|
+ for (Resource resource : subResource.doQuery(predicateMap.get(entry.getKey()))) {
|
|
|
+ subResource.providerResourceSet.add(resource);
|
|
|
}
|
|
|
- clusterController.populateResources(resourceType, providerResourceSet, request, null);
|
|
|
subResource.queryForSubResources();
|
|
|
}
|
|
|
}
|
|
@@ -358,24 +343,59 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
/**
|
|
|
* Query the cluster controller for the resources.
|
|
|
*/
|
|
|
- private Set<Resource> doQuery(Resource.Type type, Request request, Predicate predicate)
|
|
|
+ private Set<Resource> doQuery(Predicate predicate)
|
|
|
throws UnsupportedPropertyException,
|
|
|
SystemException,
|
|
|
NoSuchResourceException,
|
|
|
NoSuchParentResourceException {
|
|
|
|
|
|
- if (getKeyValueMap().get(type) == null) {
|
|
|
- addCollectionProperties(type);
|
|
|
+ Resource.Type resourceType1 = getResourceDefinition().getType();
|
|
|
+
|
|
|
+ if (getKeyValueMap().get(resourceType1) == null) {
|
|
|
+ addCollectionProperties(resourceType1);
|
|
|
}
|
|
|
if (queryPropertySet.isEmpty() && querySubResourceSet.isEmpty()) {
|
|
|
//Add sub resource properties for default case where no fields are specified.
|
|
|
querySubResourceSet.putAll(ensureSubResources());
|
|
|
}
|
|
|
|
|
|
+ Resource.Type resourceType = getResourceDefinition().getType();
|
|
|
+ Request request = createRequest();
|
|
|
+
|
|
|
if (LOG.isDebugEnabled()) {
|
|
|
LOG.debug("Executing resource query: " + request + " where " + predicate);
|
|
|
}
|
|
|
- return clusterController.getResources(type, request, predicate);
|
|
|
+ return clusterController.getResources(resourceType, request, predicate);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get a map of predicates for the given resource's sub-resources keyed
|
|
|
+ * by resource type. Each predicate is a combined predicate of all
|
|
|
+ * the sub resource predicates for a given type OR'd together. This
|
|
|
+ * allows for all of the sub-resources of a given type to be
|
|
|
+ * acquired in a single query.
|
|
|
+ */
|
|
|
+ private Map<String, Predicate> getSubResourcePredicates(Set<Resource> resources) {
|
|
|
+ Map<String, Predicate> predicateMap = new HashMap<String, Predicate>();
|
|
|
+
|
|
|
+ for (Resource resource : resources) {
|
|
|
+ for (Map.Entry<String, QueryImpl> entry : querySubResourceSet.entrySet()) {
|
|
|
+ QueryImpl subResourceInstance = entry.getValue();
|
|
|
+ String subResCategory = entry.getKey();
|
|
|
+
|
|
|
+ Set<Map<Resource.Type, String>> resourceKeyValueMaps = getKeyValueMaps(resource, keyValueMaps);
|
|
|
+
|
|
|
+ for( Map<Resource.Type, String> map : resourceKeyValueMaps) {
|
|
|
+ Predicate predicate = predicateMap.get(subResCategory);
|
|
|
+
|
|
|
+ predicateMap.put(subResCategory, predicate == null ?
|
|
|
+ subResourceInstance.createPredicate(map) :
|
|
|
+ new OrPredicate(predicate, subResourceInstance.createPredicate(map)));
|
|
|
+ }
|
|
|
+ subResourceInstance.keyValueMaps.addAll(resourceKeyValueMaps);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return predicateMap;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -386,44 +406,40 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
|
|
|
Result result = new ResultImpl(true);
|
|
|
Resource.Type resourceType = getResourceDefinition().getType();
|
|
|
- TreeNode<Resource> tree = result.getResultTree();
|
|
|
-
|
|
|
- if (isCollectionResource()) {
|
|
|
- tree.setProperty("isCollection", "true");
|
|
|
+ if (getKeyValueMap().get(resourceType) == null) {
|
|
|
+ result.getResultTree().setProperty("isCollection", "true");
|
|
|
}
|
|
|
|
|
|
- for (QueryResult queryResult : queryResults) {
|
|
|
- Predicate predicate = queryResult.getPredicate();
|
|
|
- Request request = queryResult.getRequest();
|
|
|
+ Predicate predicate = createPredicate();
|
|
|
+ Request request = createRequest();
|
|
|
|
|
|
- Iterable<Resource> iterResource;
|
|
|
+ Iterable<Resource> iterResource;
|
|
|
|
|
|
- Set<Resource> providerResourceSet = queryResult.getProviderResourceSet();
|
|
|
+ if (pageRequest == null) {
|
|
|
+ iterResource = clusterController.getIterable(
|
|
|
+ resourceType, providerResourceSet, request, predicate);
|
|
|
+ } else {
|
|
|
+ PageResponse pageResponse = clusterController.getPage(
|
|
|
+ resourceType, providerResourceSet, request, predicate, pageRequest);
|
|
|
+ iterResource = pageResponse.getIterable();
|
|
|
+ }
|
|
|
|
|
|
- if (pageRequest == null) {
|
|
|
- iterResource = clusterController.getIterable(
|
|
|
- resourceType, providerResourceSet, request, predicate);
|
|
|
- } else {
|
|
|
- PageResponse pageResponse = clusterController.getPage(
|
|
|
- resourceType, providerResourceSet, request, predicate, pageRequest);
|
|
|
- iterResource = pageResponse.getIterable();
|
|
|
- }
|
|
|
+ TreeNode<Resource> tree = result.getResultTree();
|
|
|
|
|
|
- int count = 1;
|
|
|
- for (Resource resource : iterResource) {
|
|
|
- // 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, QueryImpl> entry : querySubResourceSet.entrySet()) {
|
|
|
- String subResCategory = entry.getKey();
|
|
|
- QueryImpl subResource = entry.getValue();
|
|
|
+ int count = 1;
|
|
|
+ for (Resource resource : iterResource) {
|
|
|
+ // 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, QueryImpl> entry : querySubResourceSet.entrySet()) {
|
|
|
+ String subResCategory = entry.getKey();
|
|
|
+ QueryImpl subResource = entry.getValue();
|
|
|
|
|
|
- subResource.setKeyValueMap(getKeyValueMap(resource, getKeyValueMap()));
|
|
|
+ subResource.setKeyValueMap(getKeyValueMap(resource, getKeyValueMap()));
|
|
|
|
|
|
- TreeNode<Resource> childResult = subResource.getResult().getResultTree();
|
|
|
- childResult.setName(subResCategory);
|
|
|
- childResult.setProperty("isCollection", "false");
|
|
|
- node.addChild(childResult);
|
|
|
- }
|
|
|
+ TreeNode<Resource> childResult = subResource.getResult().getResultTree();
|
|
|
+ childResult.setName(subResCategory);
|
|
|
+ childResult.setProperty("isCollection", "false");
|
|
|
+ node.addChild(childResult);
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
@@ -551,6 +567,18 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
Collections.<String>emptySet() : setProperties, mapTemporalInfo);
|
|
|
}
|
|
|
|
|
|
+ // Get a set of key value maps based on the given resource and an existing set of key value maps
|
|
|
+ private Set<Map<Resource.Type, String>> getKeyValueMaps(Resource resource,
|
|
|
+ Set<Map<Resource.Type, String>> keyValueMaps) {
|
|
|
+ Set<Map<Resource.Type, String>> resourceKeyValueMaps = new HashSet<Map<Resource.Type, String>>();
|
|
|
+
|
|
|
+ for(Map<Resource.Type, String> keyValueMap : keyValueMaps) {
|
|
|
+ Map<Resource.Type, String> resourceKeyValueMap = getKeyValueMap(resource, keyValueMap);
|
|
|
+ resourceKeyValueMaps.add(resourceKeyValueMap);
|
|
|
+ }
|
|
|
+ return resourceKeyValueMaps;
|
|
|
+ }
|
|
|
+
|
|
|
// Get a key value map based on the given resource and an existing key value map
|
|
|
private Map<Resource.Type, String> getKeyValueMap(Resource resource,
|
|
|
Map<Resource.Type, String> keyValueMap) {
|
|
@@ -573,45 +601,4 @@ public class QueryImpl implements Query, ResourceInstance {
|
|
|
resourceKeyValueMap.put(resource.getType(), resource.getPropertyValue(resourceKeyProp).toString());
|
|
|
return resourceKeyValueMap;
|
|
|
}
|
|
|
-
|
|
|
- // ----- inner class : QueryResult -----------------------------------------
|
|
|
-
|
|
|
- /**
|
|
|
- * Maintain information about an individual query and its result.
|
|
|
- */
|
|
|
- private static class QueryResult {
|
|
|
- private final Request request;
|
|
|
- private final Predicate predicate;
|
|
|
- private final Map<Resource.Type, String> keyValueMap;
|
|
|
- private final Set<Resource> providerResourceSet;
|
|
|
-
|
|
|
- // ----- Constructor -----------------------------------------------------
|
|
|
-
|
|
|
- private QueryResult(Request request, Predicate predicate,
|
|
|
- Map<Resource.Type, String> keyValueMap,
|
|
|
- Set<Resource> providerResourceSet) {
|
|
|
- this.request = request;
|
|
|
- this.predicate = predicate;
|
|
|
- this.keyValueMap = keyValueMap;
|
|
|
- this.providerResourceSet = providerResourceSet;
|
|
|
- }
|
|
|
-
|
|
|
- // ----- accessors -------------------------------------------------------
|
|
|
-
|
|
|
- public Request getRequest() {
|
|
|
- return request;
|
|
|
- }
|
|
|
-
|
|
|
- public Predicate getPredicate() {
|
|
|
- return predicate;
|
|
|
- }
|
|
|
-
|
|
|
- public Map<Resource.Type, String> getKeyValueMap() {
|
|
|
- return keyValueMap;
|
|
|
- }
|
|
|
-
|
|
|
- public Set<Resource> getProviderResourceSet() {
|
|
|
- return providerResourceSet;
|
|
|
- }
|
|
|
- }
|
|
|
}
|