Updated Branches: refs/heads/trunk 1ae9d699c -> dd535bcf8
AMBARI-3849 Need ability to filter out href field in requests Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/dd535bcf Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/dd535bcf Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/dd535bcf Branch: refs/heads/trunk Commit: dd535bcf81398132f973faf3a58e71c9aa66e51b Parents: 1ae9d69 Author: tbeerbower <[email protected]> Authored: Wed Nov 27 06:02:13 2013 -0500 Committer: tbeerbower <[email protected]> Committed: Wed Nov 27 06:02:36 2013 -0500 ---------------------------------------------------------------------- .../ambari/server/api/handlers/ReadHandler.java | 7 +- .../ambari/server/api/predicate/QueryLexer.java | 19 ++- .../apache/ambari/server/api/query/Query.java | 11 +- .../ambari/server/api/query/QueryImpl.java | 150 ++++++++++--------- .../ambari/server/api/services/BaseRequest.java | 17 ++- .../ambari/server/api/services/BaseService.java | 9 +- .../ambari/server/api/services/Request.java | 7 + .../services/serializers/JsonSerializer.java | 13 +- .../services/serializers/ResultSerializer.java | 5 +- .../internal/ClusterControllerImpl.java | 62 +++----- .../controller/internal/ResourceImpl.java | 28 +++- .../controller/utilities/PropertyHelper.java | 26 ++++ .../server/api/handlers/ReadHandlerTest.java | 36 +++-- .../ambari/server/api/query/QueryImplTest.java | 6 +- .../server/api/services/BaseServiceTest.java | 30 +++- .../serializers/JsonSerializerTest.java | 58 ++++++- 16 files changed, 325 insertions(+), 159 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java index ffdc1dc..3b4cda1 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java @@ -45,9 +45,11 @@ public class ReadHandler implements RequestHandler { public Result handleRequest(Request request) { Query query = request.getResource().getQuery(); + query.setPageRequest(request.getPageRequest()); + query.setMinimal(request.isMinimal()); + try { addFieldsToQuery(request, query); - query.setPageRequest(request.getPageRequest()); } catch (IllegalArgumentException e) { return new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage())); } @@ -100,8 +102,7 @@ public class ReadHandler implements RequestHandler { for (Map.Entry<String, TemporalInfo> entry : request.getFields().entrySet()) { // Iterate over map and add props/temporalInfo String propertyId = entry.getKey(); - query.addProperty(PropertyHelper.getPropertyCategory(propertyId), - PropertyHelper.getPropertyName(propertyId), entry.getValue()); + query.addProperty(propertyId, entry.getValue()); } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java index 816fef4..5aa04c4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java @@ -33,6 +33,16 @@ import java.util.regex.Pattern; * Second, each string token is converted into a Token with type and value information. */ public class QueryLexer { + + /** + * Query string constants. + */ + public static final String QUERY_FIELDS = "fields"; + public static final String QUERY_PAGE_SIZE = "page_size"; + public static final String QUERY_TO = "to"; + public static final String QUERY_FROM = "from"; + public static final String QUERY_MINIMAL = "minimal_response"; + /** * All valid deliminators. */ @@ -167,10 +177,11 @@ public class QueryLexer { */ static { // ignore values - SET_IGNORE.add("fields"); - SET_IGNORE.add("page_size"); - SET_IGNORE.add("to"); - SET_IGNORE.add("from"); + SET_IGNORE.add(QUERY_FIELDS); + SET_IGNORE.add(QUERY_PAGE_SIZE); + SET_IGNORE.add(QUERY_TO); + SET_IGNORE.add(QUERY_FROM); + SET_IGNORE.add(QUERY_MINIMAL); SET_IGNORE.add("_"); } http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java b/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java index 1ca7142..58c947a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java @@ -33,11 +33,10 @@ public interface Query { * Add a property to the query. * This is the select portion of the query. * - * @param group the group name that contains the property - * @param property the property name + * @param propertyId the property id * @param temporalInfo temporal information for the property */ - public void addProperty(String group, String property, TemporalInfo temporalInfo); + public void addProperty(String propertyId, TemporalInfo temporalInfo); /** * Add a local (not sub-resource) property to the query. @@ -93,4 +92,10 @@ public interface Query { */ public void setPageRequest(PageRequest pageRequest); + /** + * Set a flag to indicate whether or not the response should be minimal. + * + * @param minimal minimal flag; true indicates that the response should be minimal + */ + public void setMinimal(boolean minimal); } http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java index caad1dd..d33eba8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java @@ -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.internal.ResourceImpl; import org.apache.ambari.server.controller.utilities.PropertyHelper; import org.apache.ambari.server.controller.predicate.AndPredicate; import org.apache.ambari.server.controller.predicate.EqualsPredicate; @@ -97,6 +98,11 @@ public class QueryImpl implements Query, ResourceInstance { private PageRequest pageRequest; /** + * Indicates whether or not the response should be minimal. + */ + private boolean minimal; + + /** * The logger. */ private final static Logger LOG = @@ -124,21 +130,17 @@ public class QueryImpl implements Query, ResourceInstance { // ----- Query ------------------------------------------------------------- @Override - public void addProperty(String category, String name, TemporalInfo temporalInfo) { - if (category == null && name.equals("*")) { + public void addProperty(String propertyId, TemporalInfo temporalInfo) { + if (propertyId.equals("*")) { // wildcard addAllProperties(temporalInfo); } else{ - if (addPropertyToSubResource(category, name, temporalInfo)){ - // add pk/fk properties of the resource to this query - Resource.Type resourceType = getResourceDefinition().getType(); - Schema schema = clusterController.getSchema(resourceType); - - for (Resource.Type type : getKeyValueMap().keySet()) { - addLocalProperty(schema.getKeyPropertyId(type)); - } + if (addPropertyToSubResource(propertyId, temporalInfo)){ + addKeyProperties(getResourceDefinition().getType(), !minimal); } else { - String propertyId = PropertyHelper.getPropertyId(category, name.equals("*") ? null : name); + if (propertyId.endsWith("/*")) { + propertyId = propertyId.substring(0, propertyId.length() - 2); + } addLocalProperty(propertyId); if (temporalInfo != null) { temporalInfoMap.put(propertyId, temporalInfo); @@ -183,8 +185,13 @@ public class QueryImpl implements Query, ResourceInstance { this.pageRequest = pageRequest; } + @Override + public void setMinimal(boolean minimal) { + this.minimal = minimal; + } + - // ----- ResourceInstance -------------------------------------------------- +// ----- ResourceInstance -------------------------------------------------- @Override public void setKeyValueMap(Map<Resource.Type, String> keyValueMap) { @@ -263,19 +270,25 @@ public class QueryImpl implements Query, ResourceInstance { getResourceDefinition().getSubResourceDefinitions(); ClusterController controller = clusterController; + for (SubResourceDefinition subResDef : setSubResourceDefs) { Resource.Type type = subResDef.getType(); Map<Resource.Type, String> valueMap = getKeyValueMap(); QueryImpl resource = new QueryImpl(valueMap, ResourceInstanceFactoryImpl.getResourceDefinition(type, valueMap), controller); + resource.setMinimal(minimal); + + Schema schema = controller.getSchema(type); // ensure pk is returned - resource.addLocalProperty(controller.getSchema( - type).getKeyPropertyId(type)); - // add additionally required fk properties - for (Resource.Type fkType : subResDef.getAdditionalForeignKeys()) { - resource.addLocalProperty(controller.getSchema(type).getKeyPropertyId(fkType)); + resource.addLocalProperty(schema.getKeyPropertyId(type)); + + if (!minimal) { + // add additionally required fk properties + for (Resource.Type fkType : subResDef.getAdditionalForeignKeys()) { + resource.addLocalProperty(schema.getKeyPropertyId(fkType)); + } } String subResourceName = subResDef.isCollection() ? @@ -300,18 +313,19 @@ public class QueryImpl implements Query, ResourceInstance { Set<Resource> providerResourceSet = new HashSet<Resource>(); Resource.Type resourceType = getResourceDefinition().getType(); - Request request = createRequest(); + Request request = createRequest(!minimal); + Request qRequest = createRequest(true); Predicate predicate = getPredicate(); Set<Resource> resourceSet = new LinkedHashSet<Resource>(); - for (Resource queryResource : doQuery(resourceType, request, predicate)) { + for (Resource queryResource : doQuery(resourceType, qRequest, predicate)) { providerResourceSet.add(queryResource); resourceSet.add(queryResource); } queryResults.put(null, new QueryResult(request, predicate, getKeyValueMap(), resourceSet)); - clusterController.populateResources(resourceType, providerResourceSet, request, predicate); + clusterController.populateResources(resourceType, providerResourceSet, qRequest, predicate); queryForSubResources(); } @@ -330,7 +344,8 @@ public class QueryImpl implements Query, ResourceInstance { QueryImpl subResource = entry.getValue(); Resource.Type resourceType = subResource.getResourceDefinition().getType(); - Request request = subResource.createRequest(); + Request request = subResource.createRequest(!minimal); + Request qRequest = subResource.createRequest(true); Set<Resource> providerResourceSet = new HashSet<Resource>(); @@ -343,14 +358,14 @@ public class QueryImpl implements Query, ResourceInstance { Set<Resource> resourceSet = new LinkedHashSet<Resource>(); - for (Resource queryResource : subResource.doQuery(resourceType, request, predicate)) { + for (Resource queryResource : subResource.doQuery(resourceType, qRequest, predicate)) { providerResourceSet.add(queryResource); resourceSet.add(queryResource); } subResource.queryResults.put(resource, new QueryResult(request, predicate, map, resourceSet)); } } - clusterController.populateResources(resourceType, providerResourceSet, request, null); + clusterController.populateResources(resourceType, providerResourceSet, qRequest, null); subResource.queryForSubResources(); } } @@ -408,10 +423,16 @@ public class QueryImpl implements Query, ResourceInstance { iterResource = pageResponse.getIterable(); } + Set<String> propertyIds = request.getPropertyIds(); + 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++); + TreeNode<Resource> node = tree.addChild( + minimal ? new ResourceImpl(resource, propertyIds) : resource, + resource.getType() + ":" + count++); + for (Map.Entry<String, QueryImpl> entry : querySubResourceSet.entrySet()) { String subResCategory = entry.getKey(); QueryImpl subResource = entry.getValue(); @@ -426,21 +447,21 @@ public class QueryImpl implements Query, ResourceInstance { return result; } - private void addCollectionProperties(Resource.Type resourceType) { + private void addKeyProperties(Resource.Type resourceType, boolean includeFKs) { Schema schema = clusterController.getSchema(resourceType); - // add pk - String property = schema.getKeyPropertyId(resourceType); - addProperty(PropertyHelper.getPropertyCategory(property), - PropertyHelper.getPropertyName(property), null); - - for (Resource.Type type : getKeyValueMap().keySet()) { - // add fk's - String keyPropertyId = schema.getKeyPropertyId(type); - if (keyPropertyId != null) { - addProperty(PropertyHelper.getPropertyCategory(keyPropertyId), - PropertyHelper.getPropertyName(keyPropertyId), null); + if (includeFKs) { + for (Resource.Type type : Resource.Type.values()) { + // add fk's + String propertyId = schema.getKeyPropertyId(type); + if (propertyId != null) { + addProperty(propertyId, null); + } } + } else { + // add pk only + String propertyId = schema.getKeyPropertyId(resourceType); + addProperty(propertyId, null); } } @@ -458,33 +479,23 @@ public class QueryImpl implements Query, ResourceInstance { } } - 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 - // (path only will presented as above case with property only) - // - path is multi level and prop is non null - - boolean resourceAdded = false; - if (path == null) { - path = property; - property = null; - } + private boolean addPropertyToSubResource(String propertyId, TemporalInfo temporalInfo) { + int index = propertyId.indexOf("/"); + String category = index == -1 ? propertyId : propertyId.substring(0, index); - int i = path.indexOf("/"); - String p = i == -1 ? path : path.substring(0, i); + Map<String, QueryImpl> subResources = ensureSubResources(); - QueryImpl subResource = ensureSubResources().get(p); + QueryImpl subResource = subResources.get(category); if (subResource != null) { - querySubResourceSet.put(p, subResource); + querySubResourceSet.put(category, subResource); - 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, temporalInfo); + //only add if a sub property is set or if a sub category is specified + if (index != -1) { + subResource.addProperty(propertyId.substring(index + 1), temporalInfo); } - resourceAdded = true; + return true; } - return resourceAdded; + return false; } private Predicate createInternalPredicate(Map<Resource.Type, String> mapResourceIds) { @@ -528,7 +539,12 @@ public class QueryImpl implements Query, ResourceInstance { return predicate; } - private Request createRequest() { + private Request createRequest(boolean includeFKs) { + + if (allProperties) { + return PropertyHelper.getReadRequest(Collections.<String>emptySet()); + } + Set<String> setProperties = new HashSet<String>(); Map<String, TemporalInfo> mapTemporalInfo = new HashMap<String, TemporalInfo>(); @@ -536,23 +552,23 @@ public class QueryImpl implements Query, ResourceInstance { Resource.Type resourceType = getResourceDefinition().getType(); if (getKeyValueMap().get(resourceType) == null) { - addCollectionProperties(resourceType); + addKeyProperties(resourceType, includeFKs); } - for (String group : queryPropertySet) { - TemporalInfo temporalInfo = temporalInfoMap.get(group); + setProperties.addAll(queryPropertySet); + + for (String propertyId : setProperties) { + TemporalInfo temporalInfo = temporalInfoMap.get(propertyId); if (temporalInfo != null) { - mapTemporalInfo.put(group, temporalInfo); + mapTemporalInfo.put(propertyId, temporalInfo); } else if (globalTemporalInfo != null) { - mapTemporalInfo.put(group, globalTemporalInfo); + mapTemporalInfo.put(propertyId, globalTemporalInfo); } - setProperties.add(group); } - - return PropertyHelper.getReadRequest(allProperties ? - Collections.<String>emptySet() : setProperties, mapTemporalInfo); + return PropertyHelper.getReadRequest(setProperties, mapTemporalInfo); } + // 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) { http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java index 03dba3e..ed7bc45 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java @@ -21,6 +21,7 @@ package org.apache.ambari.server.api.services; import org.apache.ambari.server.api.handlers.RequestHandler; import org.apache.ambari.server.api.predicate.InvalidQueryException; import org.apache.ambari.server.api.predicate.PredicateCompiler; +import org.apache.ambari.server.api.predicate.QueryLexer; import org.apache.ambari.server.api.resources.*; import org.apache.ambari.server.controller.internal.PageRequestImpl; import org.apache.ambari.server.controller.internal.TemporalInfoImpl; @@ -144,7 +145,7 @@ public abstract class BaseRequest implements Request { @Override public Map<String, TemporalInfo> getFields() { Map<String, TemporalInfo> mapProperties; - String partialResponseFields = m_uriInfo.getQueryParameters().getFirst("fields"); + String partialResponseFields = m_uriInfo.getQueryParameters().getFirst(QueryLexer.QUERY_FIELDS); if (partialResponseFields == null) { mapProperties = Collections.emptyMap(); } else { @@ -192,9 +193,9 @@ public abstract class BaseRequest implements Request { @Override public PageRequest getPageRequest() { - String pageSize = m_uriInfo.getQueryParameters().getFirst("page_size"); - String from = m_uriInfo.getQueryParameters().getFirst("from"); - String to = m_uriInfo.getQueryParameters().getFirst("to"); + String pageSize = m_uriInfo.getQueryParameters().getFirst(QueryLexer.QUERY_PAGE_SIZE); + String from = m_uriInfo.getQueryParameters().getFirst(QueryLexer.QUERY_FROM); + String to = m_uriInfo.getQueryParameters().getFirst(QueryLexer.QUERY_TO); if (pageSize == null && from == null && to == null) { return null; @@ -228,11 +229,16 @@ public abstract class BaseRequest implements Request { } @Override + public boolean isMinimal() { + String minimal = m_uriInfo.getQueryParameters().getFirst(QueryLexer.QUERY_MINIMAL); + return minimal != null && minimal.equalsIgnoreCase("true"); + } + + @Override public RequestBody getBody() { return m_body; } - /** * Obtain the result post processor for the request. * @@ -253,7 +259,6 @@ public abstract class BaseRequest implements Request { return new PredicateCompiler(); } - /** * Parse the query string and compile it into a predicate. * The query string may have already been extracted from the http body. http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java index 566fa43..8bf7836 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java @@ -66,7 +66,9 @@ public abstract class BaseService { protected Response handleRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType, ResourceInstance resource) { - Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK)); + Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK)); + boolean minimal = false; + try { Set<RequestBody> requestBodySet = getBodyParser().parse(body); @@ -77,14 +79,15 @@ public abstract class BaseService { Request request = getRequestFactory().createRequest( headers, requestBody, uriInfo, requestType, resource); - result = request.process(); + minimal = request.isMinimal(); + result = request.process(); } } catch (BodyParseException e) { result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage())); } return Response.status(result.getStatus().getStatusCode()).entity( - getResultSerializer().serialize(result)).build(); + getResultSerializer().serialize(result, minimal)).build(); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java index 7b29ea1..f2de36e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java @@ -114,4 +114,11 @@ public interface Request { * @return the page request */ public PageRequest getPageRequest(); + + /** + * Is the minimal response parameter specified as true. + * + * @return true if the minimal response parameter is specified as true + */ + public boolean isMinimal(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java index 038ac90..15b2f47 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java @@ -53,7 +53,7 @@ public class JsonSerializer implements ResultSerializer { @Override - public Object serialize(Result result) { + public Object serialize(Result result, boolean minimal) { try { ByteArrayOutputStream bytesOut = init(); @@ -61,7 +61,7 @@ public class JsonSerializer implements ResultSerializer { return serializeError(result.getStatus()); } - processNode(result.getResultTree()); + processNode(result.getResultTree(), minimal); m_generator.close(); return bytesOut.toString("UTF-8"); @@ -100,10 +100,13 @@ public class JsonSerializer implements ResultSerializer { return bytesOut; } - private void processNode(TreeNode<Resource> node) throws IOException { + private void processNode(TreeNode<Resource> node, boolean minimal) throws IOException { if (isObject(node)) { m_generator.writeStartObject(); - writeHref(node); + + if (!minimal) { + writeHref(node); + } Resource r = node.getObject(); if (r != null) { @@ -115,7 +118,7 @@ public class JsonSerializer implements ResultSerializer { } for (TreeNode<Resource> child : node.getChildren()) { - processNode(child); + processNode(child, minimal); } if (isArray(node)) { http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java index 8ff8994..22b8c88 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java @@ -29,11 +29,12 @@ public interface ResultSerializer { /** * Serialize the given result to a format expected by client. * - * * @param result internal result + * @param minimal flag to indicate minimal results + * * @return the serialized result */ - Object serialize(Result result); + Object serialize(Result result, boolean minimal); /** * Serialize an error result to the format expected by the client. http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java index 4f1751d..707c66a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java @@ -164,16 +164,16 @@ public class ClusterControllerImpl implements ClusterController { switch (pageRequest.getStartingPoint()) { case Beginning: return getPageFromOffset(pageRequest.getPageSize(), 0, - sortedResources, request, predicate, evaluator); + sortedResources, predicate, evaluator); case End: return getPageToOffset(pageRequest.getPageSize(), -1, - sortedResources, request, predicate, evaluator); + sortedResources, predicate, evaluator); case OffsetStart: return getPageFromOffset(pageRequest.getPageSize(), - pageRequest.getOffset(), sortedResources, request, predicate, evaluator); + pageRequest.getOffset(), sortedResources, predicate, evaluator); case OffsetEnd: return getPageToOffset(pageRequest.getPageSize(), - pageRequest.getOffset(), sortedResources, request, predicate, evaluator); + pageRequest.getOffset(), sortedResources, predicate, evaluator); // TODO : need to support the following cases for pagination // case PredicateStart: // case PredicateEnd: @@ -184,8 +184,9 @@ public class ClusterControllerImpl implements ClusterController { resources = providerResources; } - return new PageResponseImpl(new ResourceIterable(resources, request, predicate, evaluator), - 0, null, null); + return new PageResponseImpl( + new ResourceIterable(resources, predicate, evaluator), + 0, null, null); } @Override @@ -279,23 +280,23 @@ public class ClusterControllerImpl implements ClusterController { * @throws NoSuchResourceException no matching resource(s) found * @throws NoSuchParentResourceException a specified parent resource doesn't exist */ - protected Iterable<Resource> getResourceIterable(Resource.Type type, Request request, Predicate predicate) + protected Iterable<Resource> getResourceIterable(Resource.Type type, Request request, + Predicate predicate) throws UnsupportedPropertyException, SystemException, NoSuchParentResourceException, NoSuchResourceException { - PageResponse resources = getResources(type, request, predicate, null); - return resources.getIterable(); + return getResources(type, request, predicate, null).getIterable(); } /** * Get a page of resources filtered by the given request, predicate objects and * page request. * - * @param type type of resources - * @param request the request - * @param predicate the predicate object which filters which resources are returned - * @param pageRequest the page request for a paginated response + * @param type type of resources + * @param request the request + * @param predicate the predicate object which filters which resources are returned + * @param pageRequest the page request for a paginated response * * @return a page response representing the requested page of resources * @@ -305,7 +306,8 @@ public class ClusterControllerImpl implements ClusterController { * @throws NoSuchResourceException no matching resource(s) found * @throws NoSuchParentResourceException a specified parent resource doesn't exist */ - protected PageResponse getResources(Resource.Type type, Request request, Predicate predicate, PageRequest pageRequest) + protected PageResponse getResources(Resource.Type type, Request request, Predicate predicate, + PageRequest pageRequest) throws UnsupportedPropertyException, SystemException, NoSuchResourceException, @@ -480,14 +482,13 @@ public class ClusterControllerImpl implements ClusterController { * @param pageSize the page size * @param offset the offset * @param resources the set of resources - * @param request the request * @param predicate the predicate * * @return a page response containing a page of resources */ private PageResponse getPageFromOffset(int pageSize, int offset, NavigableSet<Resource> resources, - Request request, Predicate predicate, + Predicate predicate, ResourcePredicateEvaluator evaluator) { int currentOffset = 0; @@ -507,7 +508,7 @@ public class ClusterControllerImpl implements ClusterController { } return new PageResponseImpl(new ResourceIterable(pageResources, - request, predicate, evaluator), + predicate, evaluator), currentOffset, previous, iterator.hasNext() ? iterator.next() : null); @@ -519,14 +520,13 @@ public class ClusterControllerImpl implements ClusterController { * @param pageSize the page size * @param offset the offset; -1 indicates the end of the resource set * @param resources the set of resources - * @param request the request * @param predicate the predicate * * @return a page response containing a page of resources */ private PageResponse getPageToOffset(int pageSize, int offset, NavigableSet<Resource> resources, - Request request, Predicate predicate, + Predicate predicate, ResourcePredicateEvaluator evaluator) { int currentOffset = resources.size() - 1; @@ -549,7 +549,7 @@ public class ClusterControllerImpl implements ClusterController { } return new PageResponseImpl(new ResourceIterable(new - LinkedHashSet<Resource>(pageResources), request, predicate, evaluator), + LinkedHashSet<Resource>(pageResources), predicate, evaluator), currentOffset + 1, iterator.hasNext() ? iterator.next() : null, next); @@ -575,11 +575,6 @@ public class ClusterControllerImpl implements ClusterController { private final Set<Resource> resources; /** - * The associated request. - */ - private final Request request; - - /** * The predicate used to filter the set. */ private final Predicate predicate; @@ -596,14 +591,12 @@ public class ClusterControllerImpl implements ClusterController { * Create a ResourceIterable. * * @param resources the set of resources to iterate over - * @param request the request * @param predicate the predicate used to filter the set of resources * @param evaluator the evaluator used to evaluate with the given predicate */ - private ResourceIterable(Set<Resource> resources, Request request, Predicate predicate, + private ResourceIterable(Set<Resource> resources, Predicate predicate, ResourcePredicateEvaluator evaluator) { this.resources = resources; - this.request = request; this.predicate = predicate; this.evaluator = evaluator; } @@ -612,7 +605,7 @@ public class ClusterControllerImpl implements ClusterController { @Override public Iterator<Resource> iterator() { - return new ResourceIterator(resources, request, predicate, evaluator); + return new ResourceIterator(resources, predicate, evaluator); } } @@ -627,11 +620,6 @@ public class ClusterControllerImpl implements ClusterController { private final Iterator<Resource> iterator; /** - * The associated request. - */ - private final Request request; - - /** * The predicate used to filter the resource being iterated over. */ private final Predicate predicate; @@ -652,14 +640,12 @@ public class ClusterControllerImpl implements ClusterController { * Create a new ResourceIterator. * * @param resources the set of resources to iterate over - * @param request the request * @param predicate the predicate used to filter the set of resources * @param evaluator the evaluator used to evaluate with the given predicate */ - private ResourceIterator(Set<Resource> resources, Request request, Predicate predicate, + private ResourceIterator(Set<Resource> resources, Predicate predicate, ResourcePredicateEvaluator evaluator) { this.iterator = resources.iterator(); - this.request = request; this.predicate = predicate; this.evaluator = evaluator; this.nextResource = getNextResource(); @@ -699,9 +685,7 @@ public class ClusterControllerImpl implements ClusterController { private Resource getNextResource() { while (iterator.hasNext()) { Resource next = iterator.next(); - if (predicate == null || evaluator.evaluate(predicate, next)) { - // TODO : copy the resource and only include the requested properties. return next; } } http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java index 7dbab0c..15fb961 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java @@ -23,6 +23,7 @@ import org.apache.ambari.server.controller.utilities.PropertyHelper; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.TreeMap; /** @@ -57,16 +58,30 @@ public class ResourceImpl implements Resource { * @param resource the resource to copy */ public ResourceImpl(Resource resource) { + this(resource, null); + } + + /** + * Construct a resource from the given resource, setting only the properties + * that are found in the given set of property and category ids. + * + * @param resource the resource to copy + * @param propertyIds the set of requested property and category ids + */ + public ResourceImpl(Resource resource, Set<String> propertyIds) { this.type = resource.getType(); - for (Map.Entry<String, Map<String, Object>> categoryEntry : resource.getPropertiesMap().entrySet()) { + for (Map.Entry<String, Map<String, Object>> categoryEntry : + resource.getPropertiesMap().entrySet()) { String category = categoryEntry.getKey(); Map<String, Object> propertyMap = categoryEntry.getValue(); if (propertyMap != null) { for (Map.Entry<String, Object> propertyEntry : propertyMap.entrySet()) { - String propertyId = PropertyHelper.getPropertyId(category, propertyEntry.getKey()); - Object propertyValue = propertyEntry.getValue(); - setProperty(propertyId, propertyValue); + String propertyId = PropertyHelper.getPropertyId(category, propertyEntry.getKey()); + if (propertyIds == null || propertyIds.isEmpty() || PropertyHelper.containsProperty(propertyIds, propertyId)) { + Object propertyValue = propertyEntry.getValue(); + setProperty(propertyId, propertyValue); + } } } } @@ -143,11 +158,10 @@ public class ResourceImpl implements Resource { @Override public int hashCode() { - int result = 31 * type.hashCode() + (propertiesMap != null ? propertiesMap.hashCode() : 0); - return result; + return 31 * type.hashCode() + (propertiesMap != null ? propertiesMap.hashCode() : 0); } -// ----- utility methods --------------------------------------------------- + // ----- utility methods --------------------------------------------------- private String getCategoryKey(String category) { return category == null ? "" : category; http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java index c5c7b2f..8d2f495 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java @@ -184,6 +184,32 @@ public class PropertyHelper { } /** + * Check if the given property id or one of its parent category ids is contained + * in the given set of property ids. + * + * @param propertyIds the set of property ids + * @param propertyId the property id + * + * @return true if the given property id of one of its parent category ids is + * contained in the given set of property ids + */ + public static boolean containsProperty(Set<String> propertyIds, String propertyId) { + + if (propertyIds.contains(propertyId)){ + return true; + } + + String category = PropertyHelper.getPropertyCategory(propertyId); + while (category != null) { + if ( propertyIds.contains(category)) { + return true; + } + category = PropertyHelper.getPropertyCategory(category); + } + return false; + } + + /** * Check to see if the given property id contains replacement arguments (e.g. $1) * * @param propertyId the property id to check http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java index cd3e79b..f1d2ea6 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java @@ -54,7 +54,9 @@ public class ReadHandlerTest { expect(request.getFields()).andReturn(mapPartialResponseFields); expect(resource.getQuery()).andReturn(query); - query.addProperty("foo", "bar", null); + query.setPageRequest(null); + query.setMinimal(false); + query.addProperty("foo/bar", null); expectLastCall().andThrow(new IllegalArgumentException("testMsg")); replay(request, resource, query); @@ -86,16 +88,18 @@ public class ReadHandlerTest { expect(request.getResource()).andReturn(resource); expect(resource.getQuery()).andReturn(query); - expect(request.getFields()).andReturn(mapPartialResponseFields); expect(request.getPageRequest()).andReturn(null); - query.addProperty(null, "foo", null); - query.addProperty("bar", "c", null); - query.addProperty("bar/d", "e", null); - query.addProperty("category", "", null); + expect(request.isMinimal()).andReturn(false); + expect(request.getFields()).andReturn(mapPartialResponseFields); + query.addProperty("foo", null); + query.addProperty("bar/c", null); + query.addProperty("bar/d/e", null); + query.addProperty("category/", null); expect(request.getQueryPredicate()).andReturn(predicate); query.setUserPredicate(predicate); query.setPageRequest(null); + query.setMinimal(false); expect(query.execute()).andReturn(result); result.setResultStatus(capture(resultStatusCapture)); @@ -118,12 +122,14 @@ public class ReadHandlerTest { expect(request.getResource()).andReturn(resource); expect(resource.getQuery()).andReturn(query); - expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getPageRequest()).andReturn(null); + expect(request.isMinimal()).andReturn(false); + expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getQueryPredicate()).andReturn(predicate); query.setUserPredicate(predicate); query.setPageRequest(null); + query.setMinimal(false); SystemException systemException = new SystemException("testMsg", new RuntimeException()); expect(query.execute()).andThrow(systemException); @@ -148,12 +154,14 @@ public class ReadHandlerTest { expect(request.getResource()).andReturn(resource); expect(resource.getQuery()).andReturn(query); - expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getPageRequest()).andReturn(null); + expect(request.isMinimal()).andReturn(false); + expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getQueryPredicate()).andReturn(predicate); query.setUserPredicate(predicate); query.setPageRequest(null); + query.setMinimal(false); expect(query.execute()).andThrow(exception); @@ -179,12 +187,14 @@ public class ReadHandlerTest { expect(request.getResource()).andReturn(resource); expect(resource.getQuery()).andReturn(query); - expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getPageRequest()).andReturn(null); + expect(request.isMinimal()).andReturn(false); + expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getQueryPredicate()).andReturn(predicate); query.setUserPredicate(predicate); query.setPageRequest(null); + query.setMinimal(false); expect(query.execute()).andThrow(exception); @@ -209,12 +219,14 @@ public class ReadHandlerTest { expect(request.getResource()).andReturn(resource); expect(resource.getQuery()).andReturn(query); - expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getPageRequest()).andReturn(null); + expect(request.isMinimal()).andReturn(false); + expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getQueryPredicate()).andReturn(predicate).anyTimes(); query.setUserPredicate(predicate); query.setPageRequest(null); + query.setMinimal(false); expect(query.execute()).andThrow(exception); @@ -238,12 +250,14 @@ public class ReadHandlerTest { expect(request.getResource()).andReturn(resource); expect(resource.getQuery()).andReturn(query); - expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getPageRequest()).andReturn(null); + expect(request.isMinimal()).andReturn(false); + expect(request.getFields()).andReturn(Collections.<String, TemporalInfo>emptyMap()); expect(request.getQueryPredicate()).andReturn(null).anyTimes(); query.setUserPredicate(null); query.setPageRequest(null); + query.setMinimal(false); expect(query.execute()).andThrow(exception); http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java index 815779b..725ed50 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/query/QueryImplTest.java @@ -160,9 +160,9 @@ public class QueryImplTest { //test QueryImpl instance = new TestQuery(mapIds, resourceDefinition); - instance.addProperty("versions", "*", null); - instance.addProperty("versions/operatingSystems", "*", null); - instance.addProperty("versions/operatingSystems/repositories", "*", null); + instance.addProperty("versions/*", null); + instance.addProperty("versions/operatingSystems/*", null); + instance.addProperty("versions/operatingSystems/repositories/*", null); Result result = instance.execute(); http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseServiceTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseServiceTest.java index 92d2daf..8217b9c 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseServiceTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseServiceTest.java @@ -93,6 +93,7 @@ public abstract class BaseServiceTest { List<ServiceTestInvocation> listTestInvocations = getTestInvocations(); for (ServiceTestInvocation testInvocation : listTestInvocations) { testMethod(testInvocation); + testMethodMinimal(testInvocation); testMethod_bodyParseException(testInvocation); testMethod_resultInErrorState(testInvocation); } @@ -109,7 +110,30 @@ public abstract class BaseServiceTest { expect(request.process()).andReturn(result); expect(result.getStatus()).andReturn(status).atLeastOnce(); expect(status.getStatusCode()).andReturn(testMethod.getStatusCode()).atLeastOnce(); - expect(serializer.serialize(result)).andReturn(serializedResult); + expect(serializer.serialize(result, false)).andReturn(serializedResult); + + replayMocks(); + + Response r = testMethod.invoke(); + + assertEquals(serializedResult, r.getEntity()); + assertEquals(testMethod.getStatusCode(), r.getStatus()); + verifyAndResetMocks(); + } + + private void testMethodMinimal(ServiceTestInvocation testMethod) throws InvocationTargetException, IllegalAccessException { + try { + expect(bodyParser.parse(testMethod.getBody())).andReturn(Collections.singleton(requestBody)); + } catch (BodyParseException e) { + // needed for compiler + } + + expect(requestFactory.createRequest(httpHeaders, requestBody, uriInfo, testMethod.getRequestType(), resourceInstance)).andReturn(request); + expect(request.isMinimal()).andReturn(true); + expect(request.process()).andReturn(result); + expect(result.getStatus()).andReturn(status).atLeastOnce(); + expect(status.getStatusCode()).andReturn(testMethod.getStatusCode()).atLeastOnce(); + expect(serializer.serialize(result, true)).andReturn(serializedResult); replayMocks(); @@ -124,7 +148,7 @@ public abstract class BaseServiceTest { Capture<Result> resultCapture = new Capture<Result>(); BodyParseException e = new BodyParseException("TEST MSG"); expect(bodyParser.parse(testMethod.getBody())).andThrow(e); - expect(serializer.serialize(capture(resultCapture))).andReturn(serializedResult); + expect(serializer.serialize(capture(resultCapture), eq(false))).andReturn(serializedResult); replayMocks(); @@ -146,7 +170,7 @@ public abstract class BaseServiceTest { expect(request.process()).andReturn(result); expect(result.getStatus()).andReturn(status).atLeastOnce(); expect(status.getStatusCode()).andReturn(400).atLeastOnce(); - expect(serializer.serialize(result)).andReturn(serializedResult); + expect(serializer.serialize(result, false)).andReturn(serializedResult); replayMocks(); http://git-wip-us.apache.org/repos/asf/ambari/blob/dd535bcf/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/JsonSerializerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/JsonSerializerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/JsonSerializerTest.java index 816a251..63eb33a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/JsonSerializerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/serializers/JsonSerializerTest.java @@ -47,7 +47,8 @@ public class JsonSerializerTest { result.setResultStatus(new ResultStatus(ResultStatus.STATUS.OK)); TreeNode<Resource> tree = result.getResultTree(); //tree.setName("items"); - tree.addChild(resource, "resource1"); + TreeNode<Resource> child = tree.addChild(resource, "resource1"); + child.setProperty("href", "this is an href"); //child.addChild(resource2, "sub-resource"); // resource properties @@ -71,9 +72,10 @@ public class JsonSerializerTest { replay(uriInfo, resource/*, resource2*/); //execute test - Object o = new JsonSerializer().serialize(result); + Object o = new JsonSerializer().serialize(result, false); String expected = "{\n" + + " \"href\" : \"this is an href\",\n" + " \"prop2\" : \"value2\",\n" + " \"prop1\" : \"value1\",\n" + " \"category\" : {\n" + @@ -87,6 +89,56 @@ public class JsonSerializerTest { verify(uriInfo, resource/*, resource2*/); } + @Test + public void testSerializeMinimal() throws Exception { + UriInfo uriInfo = createMock(UriInfo.class); + Resource resource = createMock(Resource.class); + //Resource resource2 = createMock(Resource.class); + + Result result = new ResultImpl(true); + result.setResultStatus(new ResultStatus(ResultStatus.STATUS.OK)); + TreeNode<Resource> tree = result.getResultTree(); + //tree.setName("items"); + TreeNode<Resource> child = tree.addChild(resource, "resource1"); + child.setProperty("href", "this is an href"); + //child.addChild(resource2, "sub-resource"); + + // resource properties + HashMap<String, Object> mapRootProps = new HashMap<String, Object>(); + mapRootProps.put("prop1", "value1"); + mapRootProps.put("prop2", "value2"); + + HashMap<String, Object> mapCategoryProps = new HashMap<String, Object>(); + mapCategoryProps.put("catProp1", "catValue1"); + mapCategoryProps.put("catProp2", "catValue2"); + + Map<String, Map<String, Object>> propertyMap = new HashMap<String, Map<String, Object>>(); + + propertyMap.put(null, mapRootProps); + propertyMap.put("category", mapCategoryProps); + + //expectations + expect(resource.getPropertiesMap()).andReturn(propertyMap).anyTimes(); + expect(resource.getType()).andReturn(Resource.Type.Cluster).anyTimes(); + + replay(uriInfo, resource/*, resource2*/); + + //execute test + Object o = new JsonSerializer().serialize(result, true); + + String expected = "{\n" + + " \"prop2\" : \"value2\",\n" + + " \"prop1\" : \"value1\",\n" + + " \"category\" : {\n" + + " \"catProp1\" : \"catValue1\",\n" + + " \"catProp2\" : \"catValue2\"\n" + + " }\n" + + "}"; + + assertEquals(expected, o); + + verify(uriInfo, resource/*, resource2*/); + } @Test public void testSerializeResources() throws Exception { @@ -125,7 +177,7 @@ public class JsonSerializerTest { replay(uriInfo, resource); //execute test - Object o = new JsonSerializer().serialize(result); + Object o = new JsonSerializer().serialize(result, false); String expected = "{\n" + " \"resources\" : [\n" +
