You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2013/03/11 20:26:50 UTC
svn commit: r1455293 [1/4] - in /incubator/ambari/trunk: ./
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/
ambari-server/src/main/java/org/apache/ambari/server/api/services/
ambari-server/src/main/java/org/apache/ambari/server/api/s...
Author: jspeidel
Date: Mon Mar 11 19:26:49 2013
New Revision: 1455293
URL: http://svn.apache.org/r1455293
Log:
AMBARI-1406. Provide API support for including query string in http message body
Added:
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/NamedPropertySet.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/BodyParseException.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/NamedPropertySetTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/QueryPostRequestTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestBodyTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/BodyParseExceptionTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParserTest.java
Removed:
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/RequestHandlerFactory.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonPropertyParser.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonPropertyParserTest.java
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/RequestBodyParser.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/CreateHandlerTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/DeleteHandlerTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/QueryCreateHandlerTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/ReadHandlerTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/UpdateHandlerTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/ActionServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/ClusterServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/ComponentServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/ConfigurationServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/DeleteRequestTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/GetRequestTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/HostComponentServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/HostServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/PostRequestTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/PutRequestTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/ServiceServiceTest.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/StacksServiceTest.java
Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Mon Mar 11 19:26:49 2013
@@ -15,6 +15,8 @@ Trunk (unreleased changes):
AMBARI-1602. Edit User - drop the requirement to specify the old
password. (swagle)
+ AMBARI-1406. Provide API support for including query string in http message body. (jspeidel)
+
AMBARI-1592. Change how configurations are propagated (ncole)
AMBARI-1593. Change host override JSON to include version tag (ncole)
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java Mon Mar 11 19:26:49 2013
@@ -18,12 +18,11 @@
package org.apache.ambari.server.api.handlers;
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.NamedPropertySet;
import org.apache.ambari.server.api.services.Request;
import org.apache.ambari.server.api.services.Result;
import org.apache.ambari.server.api.services.ResultImpl;
-import org.apache.ambari.server.api.services.ResultStatus;
import org.apache.ambari.server.api.services.persistence.PersistenceManager;
import org.apache.ambari.server.api.services.persistence.PersistenceManagerImpl;
import org.apache.ambari.server.api.util.TreeNode;
@@ -35,6 +34,7 @@ import org.apache.ambari.server.controll
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -54,29 +54,32 @@ public abstract class BaseManagementHand
*/
PersistenceManager m_pm = new PersistenceManagerImpl(getClusterController());
+ /**
+ * Constructor.
+ */
protected BaseManagementHandler() {
}
+
+ @Override
public Result handleRequest(Request request) {
- ResourceInstance resource = request.getResource();
- Predicate queryPredicate;
- try {
- queryPredicate = request.getQueryPredicate();
- } catch (InvalidQueryException e) {
- return new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
- "Invalid Request: " + e.getMessage()));
- }
+ ResourceInstance resource = request.getResource();
+ Predicate queryPredicate = request.getQueryPredicate();
+
if (queryPredicate != null) {
resource.getQuery().setUserPredicate(queryPredicate);
}
- return handleRequest(resource, request.getHttpBodyProperties());
- }
-
- protected Result handleRequest(ResourceInstance resource, Set<Map<String, Object>> setProperties) {
- return persist(resource, setProperties);
+ return persist(resource, getHttpBodyProperties(request));
}
+ /**
+ * Create a result from a request status.
+ *
+ * @param requestStatus the request stats to build the result from.
+ *
+ * @return a Result instance for the provided request status
+ */
protected Result createResult(RequestStatus requestStatus) {
boolean isSynchronous = requestStatus.getStatus() == RequestStatus.Status.Complete;
@@ -98,18 +101,55 @@ public abstract class BaseManagementHand
resourcesNode.addChild(resource, resource.getType() + ":" + count++);
}
}
-
return result;
}
- //todo: controller should be injected
+ /**
+ * Obtain a set of property maps from the request.
+ * Convenience method that converts a Set<NamedPropertySet> from the request to a Set<Map<String, Object>>.
+ *
+ * @param request the current request
+ *
+ * @return a set of property maps for the request
+ */
+ protected Set<Map<String, Object>> getHttpBodyProperties(Request request) {
+ Set<NamedPropertySet> setNamedProps = request.getHttpBodyProperties();
+ Set<Map<String, Object>> setProps = new HashSet<Map<String, Object>>(setNamedProps.size());
+
+ for (NamedPropertySet namedProps : setNamedProps) {
+ setProps.add(namedProps.getProperties());
+ }
+
+ return setProps;
+ }
+
+ //todo: inject ClusterController, PersistenceManager
+
+ /**
+ * Get the cluster controller instance.
+ *
+ * @return cluster controller
+ */
protected ClusterController getClusterController() {
return ClusterControllerHelper.getClusterController();
}
+ /**
+ * Get the persistence manager instance.
+ *
+ * @return persistence manager
+ */
protected PersistenceManager getPersistenceManager() {
return m_pm;
}
- protected abstract Result persist(ResourceInstance r, Set<Map<String, Object>> properties);
+ /**
+ * Persist the operation to the back end.
+ *
+ * @param request the requests resource instance
+ * @param setProperties request properties
+ *
+ * @return the result of the persist operation
+ */
+ protected abstract Result persist(ResourceInstance request, Set<Map<String, Object>> setProperties);
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java Mon Mar 11 19:26:49 2013
@@ -33,10 +33,10 @@ import java.util.Set;
public class CreateHandler extends BaseManagementHandler {
@Override
- protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+ protected Result persist(ResourceInstance request, Set<Map<String, Object>> setProperties) {
Result result;
try {
- RequestStatus status = getPersistenceManager().create(r, properties);
+ RequestStatus status = getPersistenceManager().create(request, setProperties);
result = createResult(status);
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java Mon Mar 11 19:26:49 2013
@@ -33,10 +33,10 @@ import java.util.Set;
public class DeleteHandler extends BaseManagementHandler implements RequestHandler {
@Override
- protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+ protected Result persist(ResourceInstance request, Set<Map<String, Object>> setProperties) {
Result result;
try {
- RequestStatus status = getPersistenceManager().delete(r, properties);
+ RequestStatus status = getPersistenceManager().delete(request, setProperties);
result = createResult(status);
if (result.isSynchronous()) {
@@ -49,7 +49,7 @@ public class DeleteHandler extends BaseM
} catch (NoSuchParentResourceException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
} catch (NoSuchResourceException e) {
- if (r.isCollectionResource()) {
+ if (request.isCollectionResource()) {
//todo: The query didn't match any resource so no resources were updated.
//todo: 200 may be ok but we need to return a collection
//todo: of resources that were updated.
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java Mon Mar 11 19:26:49 2013
@@ -22,10 +22,8 @@ package org.apache.ambari.server.api.han
import org.apache.ambari.server.api.resources.ResourceInstance;
import org.apache.ambari.server.api.resources.ResourceInstanceFactory;
import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
+import org.apache.ambari.server.api.services.*;
import org.apache.ambari.server.api.services.Request;
-import org.apache.ambari.server.api.services.ResultStatus;
-import org.apache.ambari.server.api.services.Result;
-import org.apache.ambari.server.api.services.ResultImpl;
import org.apache.ambari.server.api.util.TreeNode;
import org.apache.ambari.server.controller.spi.*;
@@ -44,30 +42,55 @@ public class QueryCreateHandler extends
if (queryResult.getStatus().isErrorState() ||
queryResult.getResultTree().getChildren().isEmpty()) {
- //return the query result if result has error state or contains no resources
- //todo: For case where no resources are returned, will return 200 ok.
- //todo: What is the appropriate status code?
+ //if query result has error state or contains no resources return it
+ // currently returns 200 for case where query returns no rows
return queryResult;
}
- ResourceInstance resource = request.getResource();
- Resource.Type createType = getCreateType(request.getHttpBody(), resource);
- Set<Map<String, Object>> setProperties = buildCreateSet(request, queryResult, createType);
+ Map<Resource.Type, Set<Map<String, Object>>> mapProperties;
+ try {
+ mapProperties = buildCreateSet(request, queryResult);
+ } catch (IllegalArgumentException e) {
+ return createInvalidRequestResult(e.getMessage());
+ }
+
+ if (mapProperties.size() != 1) {
+ return createInvalidRequestResult(mapProperties.size() == 0 ?
+ "A minimum of one sub-resource must be specified for creation." :
+ "Multiple sub-resource types may not be created in the same request.");
+ }
+
+ Map.Entry<Resource.Type, Set<Map<String, Object>>> entry = mapProperties.entrySet().iterator().next();
ResourceInstance createResource = getResourceFactory().createResource(
- createType, request.getResource().getIds());
+ entry.getKey(), request.getResource().getIds());
- return super.handleRequest(createResource, setProperties);
+ return persist(createResource, entry.getValue());
}
- private Set<Map<String, Object>> buildCreateSet(Request request, Result queryResult, Resource.Type createType) {
- Set<Map<String, Object>> setRequestProps = request.getHttpBodyProperties();
- Set<Map<String, Object>> setCreateProps = new HashSet<Map<String, Object>>(setRequestProps.size());
+ /**
+ * Build the property set for all sub-resource to be created.
+ * This includes determining the sub-resource type and creating a property set for each matching parent.
+ *
+ * @param request the current request
+ * @param queryResult the result of the query for matching parents
+ *
+ * @return a map of sub-resource types to be created and their associated properties
+ *
+ * @throws IllegalArgumentException if no sub-resource type was specified or it is not a valid
+ * sub-resource of the parent.
+ */
+ private Map<Resource.Type, Set<Map<String, Object>>> buildCreateSet(Request request, Result queryResult)
+ throws IllegalArgumentException {
+
+ Set<NamedPropertySet> setRequestProps = request.getHttpBodyProperties();
+
+ HashMap<Resource.Type, Set<Map<String, Object>>> mapProps =
+ new HashMap<Resource.Type, Set<Map<String, Object>>>();
ResourceInstance resource = request.getResource();
Resource.Type type = resource.getResourceDefinition().getType();
ClusterController controller = getClusterController();
String resourceKeyProperty = controller.getSchema(type).getKeyPropertyId(type);
- String createKeyProperty = controller.getSchema(createType).getKeyPropertyId(type);
TreeNode<Resource> tree = queryResult.getResultTree();
Collection<TreeNode<Resource>> treeChildren = tree.getChildren();
@@ -75,29 +98,61 @@ public class QueryCreateHandler extends
Resource r = node.getObject();
Object keyVal = r.getPropertyValue(resourceKeyProperty);
- for (Map<String, Object> mapProps : setRequestProps) {
- Map<String, Object> mapResourceProps = new HashMap<String, Object>(mapProps);
- mapResourceProps.put(createKeyProperty, keyVal);
+ for (NamedPropertySet namedProps : setRequestProps) {
+ Map<String, Object> mapResourceProps = new HashMap<String, Object>(namedProps.getProperties());
+ Resource.Type createType = getCreateType(resource, namedProps.getName());
+ mapResourceProps.put(controller.getSchema(createType).
+ getKeyPropertyId(resource.getResourceDefinition().getType()), keyVal);
+ Set<Map<String, Object>> setCreateProps = mapProps.get(createType);
+ if (setCreateProps == null) {
+ setCreateProps = new HashSet<Map<String, Object>>();
+ mapProps.put(createType, setCreateProps);
+ }
setCreateProps.add(mapResourceProps);
}
}
- return setCreateProps;
+ return mapProps;
}
- private Resource.Type getCreateType(String requestBody, ResourceInstance resource) {
- int startIdx = requestBody.indexOf("\"") + 1;
- int endIdx = requestBody.indexOf("\"", startIdx + 1);
+ /**
+ * Determine the sub-resurce type(s) to be created.
+ *
+ * @param resource the requests resource instance
+ * @param subResourceName the name of the sub-resource to be created
+ * @return the resource type
+ *
+ * @throws IllegalArgumentException if the specified sub-resource name is empty or it is not a valid
+ * sub-resource of the parent.
+ */
+ private Resource.Type getCreateType(ResourceInstance resource, String subResourceName) throws IllegalArgumentException{
+ if (subResourceName == null || subResourceName.equals("")) {
+ throw new IllegalArgumentException("A sub-resource name must be supplied.");
+ }
+ ResourceInstance res = resource.getSubResources().get(subResourceName);
+
+ if (res == null) {
+ throw new IllegalArgumentException("The specified sub-resource name is not valid: '" + subResourceName + "'.");
+ }
- ResourceInstance res = resource.getSubResources().get(requestBody.substring(startIdx, endIdx));
- return res == null ? null : res.getResourceDefinition().getType();
+ return res.getResourceDefinition().getType();
+ }
+
+ /**
+ * Convenience method to create a result for invalid requests.
+ *
+ * @param msg message indicating why the request is invalid
+ *
+ * @return a request with a 400 status and msg set
+ */
+ private Result createInvalidRequestResult(String msg) {
+ return new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, "Invalid Request: " + msg));
}
@Override
- protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+ protected Result persist(ResourceInstance request, Set<Map<String, Object>> setProperties) {
Result result;
try {
- RequestStatus status = getPersistenceManager().create(r, properties);
-
+ RequestStatus status = getPersistenceManager().create(request, setProperties);
result = createResult(status);
if (result.isSynchronous()) {
@@ -105,7 +160,6 @@ public class QueryCreateHandler extends
} else {
result.setResultStatus(new ResultStatus(ResultStatus.STATUS.ACCEPTED));
}
-
} catch (UnsupportedPropertyException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
} catch (ResourceAlreadyExistsException e) {
@@ -119,10 +173,20 @@ public class QueryCreateHandler extends
return result;
}
+ /**
+ * Get the resource factory instance.
+ * @return a factory for creating resource instances
+ */
protected ResourceInstanceFactory getResourceFactory() {
+ //todo: inject
return new ResourceInstanceFactoryImpl();
}
+ /**
+ * Read handler instance. Used for obtaining matching parents which match the query.
+ *
+ * @return read handler instance
+ */
protected RequestHandler getReadHandler() {
return m_readHandler;
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java Mon Mar 11 19:26:49 2013
@@ -18,7 +18,6 @@
package org.apache.ambari.server.api.handlers;
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
import org.apache.ambari.server.api.services.Request;
import org.apache.ambari.server.api.services.ResultImpl;
import org.apache.ambari.server.api.services.ResultStatus;
@@ -78,10 +77,7 @@ public class ReadHandler implements Requ
} catch (IllegalArgumentException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
"Invalid Request: " + e.getMessage()));
- } catch (InvalidQueryException e) {
- result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
- "Invalid Request: " + e.getMessage()));
- } catch (RuntimeException e) {
+ } catch (RuntimeException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Caught a runtime exception executing a query", e);
}
@@ -91,7 +87,13 @@ public class ReadHandler implements Requ
return result;
}
- private void addFieldsToQuery(Request request, Query query) throws IllegalArgumentException {
+ /**
+ * Add partial response fields to the provided query.
+ *
+ * @param request the current request
+ * @param query the associated query *
+ */
+ private void addFieldsToQuery(Request request, Query query) {
//Partial response
for (Map.Entry<String, TemporalInfo> entry : request.getFields().entrySet()) {
// Iterate over map and add props/temporalInfo
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java Mon Mar 11 19:26:49 2013
@@ -32,10 +32,10 @@ import java.util.Set;
public class UpdateHandler extends BaseManagementHandler {
@Override
- protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+ protected Result persist(ResourceInstance request, Set<Map<String, Object>> setProperties) {
Result result;
try {
- RequestStatus status = getPersistenceManager().update(r, properties);
+ RequestStatus status = getPersistenceManager().update(request, setProperties);
result = createResult(status);
if (result.isSynchronous()) {
@@ -49,7 +49,7 @@ public class UpdateHandler extends BaseM
} catch (NoSuchParentResourceException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
} catch (NoSuchResourceException e) {
- if (r.isCollectionResource()) {
+ if (request.isCollectionResource()) {
//todo: what is the correct status code here. The query didn't match any resource
//todo: so no resource were updated. 200 may be ok but we would need to return a collection
//todo: of resources that were updated.
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java Mon Mar 11 19:26:49 2013
@@ -18,16 +18,15 @@
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.resources.*;
-import org.apache.ambari.server.api.services.parsers.JsonPropertyParser;
-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.spi.Predicate;
import org.apache.ambari.server.controller.spi.TemporalInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriInfo;
@@ -55,29 +54,58 @@ public abstract class BaseRequest implem
/**
* Http Body
*/
- private String m_body;
+ private RequestBody m_body;
+ /**
+ * Query Predicate
+ */
+ private Predicate m_predicate;
/**
* Associated resource definition
*/
private ResourceInstance m_resource;
+ /**
+ * Logger instance.
+ */
+ private final static Logger LOG = LoggerFactory.getLogger(Request.class);
+
/**
* Constructor.
*
- * @param headers http headers
- * @param body http body
- * @param uriInfo uri information
- * @param resource associated resource definition
- */
- public BaseRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
-
- m_headers = headers;
- m_body = body;
- m_uriInfo = uriInfo;
- m_resource = resource;
+ * @param headers http headers
+ * @param body http body
+ * @param uriInfo uri information
+ * @param resource associated resource definition
+ *
+ */
+ public BaseRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
+ m_headers = headers;
+ m_uriInfo = uriInfo;
+ m_resource = resource;
+ m_body = body;
+ }
+
+ @Override
+ public Result process() {
+ LOG.info("Handling API Request: '" + getURI() + "'");
+
+ Result result;
+ try {
+ parseQueryPredicate();
+ result = getRequestHandler().handleRequest(this);
+ } catch (InvalidQueryException e) {
+ result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
+ "Unable to compile query predicate: " + e.getMessage()));
+ }
+
+ if (! result.getStatus().isErrorState()) {
+ getResultPostProcessor().process(result);
+ }
+
+ return result;
}
@Override
@@ -96,16 +124,12 @@ public abstract class BaseRequest implem
@Override
public int getAPIVersion() {
- return 0;
+ return 1;
}
@Override
- public Predicate getQueryPredicate() throws InvalidQueryException {
- String uri = getURI();
- int qsBegin = uri.indexOf("?");
-
- return (qsBegin == -1) ? null :
- getPredicateCompiler().compile(uri.substring(qsBegin + 1));
+ public Predicate getQueryPredicate() {
+ return m_predicate;
}
@Override
@@ -158,29 +182,60 @@ public abstract class BaseRequest implem
@Override
public String getHttpBody() {
- return m_body;
+ return m_body.getBody();
}
@Override
- public Set<Map<String, Object>> getHttpBodyProperties() {
- return getHttpBodyParser().parse(getHttpBody());
+ public Set<NamedPropertySet> getHttpBodyProperties() {
+ return m_body.getPropertySets();
}
- @Override
- public ResultSerializer getResultSerializer() {
- return new JsonSerializer();
- }
-
- @Override
- public ResultPostProcessor getResultPostProcessor() {
+ /**
+ * Obtain the result post processor for the request.
+ *
+ * @return the result post processor
+ */
+ protected ResultPostProcessor getResultPostProcessor() {
+ //todo: inject
return new ResultPostProcessorImpl(this);
}
- protected RequestBodyParser getHttpBodyParser() {
- return new JsonPropertyParser();
- }
-
+ /**
+ * Obtain the predicate compiler which is used to compile the query string into
+ * a predicate.
+ *
+ * @return the predicate compiler
+ */
protected PredicateCompiler getPredicateCompiler() {
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.
+ * If the query string didn't exist in the body use the query string in the URL.
+ *
+ * @throws InvalidQueryException if unable to parse a non-null query string into a predicate
+ */
+ private void parseQueryPredicate() throws InvalidQueryException {
+ String queryString = m_body.getQueryString();
+ if (queryString == null) {
+ String uri = getURI();
+ int qsBegin = uri.indexOf("?");
+
+ queryString = (qsBegin == -1) ? null : uri.substring(qsBegin + 1);
+ }
+
+ if (queryString != null) {
+ m_predicate = getPredicateCompiler().compile(queryString);
+ }
+ }
+
+ /**
+ * Obtain the underlying request handler for the request.
+ *
+ * @return the request handler
+ */
+ protected abstract RequestHandler getRequestHandler();
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java Mon Mar 11 19:26:49 2013
@@ -18,15 +18,15 @@
package org.apache.ambari.server.api.services;
-import org.apache.ambari.server.api.handlers.RequestHandler;
-import org.apache.ambari.server.api.handlers.RequestHandlerFactory;
import org.apache.ambari.server.api.resources.ResourceInstance;
import org.apache.ambari.server.api.resources.ResourceInstanceFactory;
import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
+import org.apache.ambari.server.api.services.parsers.BodyParseException;
+import org.apache.ambari.server.api.services.parsers.JsonRequestBodyParser;
+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.spi.Resource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
@@ -44,19 +44,14 @@ public abstract class BaseService {
private ResourceInstanceFactory m_resourceFactory = new ResourceInstanceFactoryImpl();
/**
- * Factory for creating request handlers.
+ * Result serializer.
*/
- private RequestHandlerFactory m_handlerFactory = new RequestHandlerFactory();
+ private ResultSerializer m_serializer = new JsonSerializer();
- /**
- * Logger instance.
- */
- private final static Logger LOG = LoggerFactory.getLogger(BaseService.class);
/**
* All requests are funneled through this method so that common logic can be executed.
- * This consists of creating a {@link Request} instance, invoking the correct {@link RequestHandler} and
- * applying the proper {@link ResultSerializer} to the result.
+ * Creates a request instance and invokes it's process method.
*
* @param headers http headers
* @param body http body
@@ -66,21 +61,22 @@ public abstract class BaseService {
*
* @return the response of the operation in serialized form
*/
- protected Response handleRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType,
- ResourceInstance resource) {
-
- Request request = getRequestFactory().createRequest(
- headers, body, uriInfo, requestType, resource);
-
- LOG.info("Handling API Request: '" + request.getURI() + "'");
+ protected Response handleRequest(HttpHeaders headers, String body, UriInfo uriInfo,
+ Request.Type requestType, ResourceInstance resource) {
- Result result = getRequestHandler(request.getRequestType()).handleRequest(request);
- if (! result.getStatus().isErrorState()) {
- request.getResultPostProcessor().process(result);
+ Result result;
+ try {
+ RequestBody requestBody = getBodyParser().parse(body);
+ Request request = getRequestFactory().createRequest(
+ headers, requestBody, uriInfo, requestType, resource);
+
+ result = request.process();
+ } catch (BodyParseException e) {
+ result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
}
return Response.status(result.getStatus().getStatusCode()).entity(
- request.getResultSerializer().serialize(result)).build();
+ getResultSerializer().serialize(result)).build();
}
/**
@@ -93,17 +89,6 @@ public abstract class BaseService {
}
/**
- * Obtain the appropriate RequestHandler for the request.
- *
- * @param requestType the request type
- *
- * @return the request handler to invoke
- */
- RequestHandler getRequestHandler(Request.Type requestType) {
- return m_handlerFactory.getRequestHandler(requestType);
- }
-
- /**
* Create a resource instance.
*
* @param type the resource type
@@ -114,4 +99,12 @@ public abstract class BaseService {
ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
return m_resourceFactory.createResource(type, mapIds);
}
+
+ protected ResultSerializer getResultSerializer() {
+ return m_serializer;
+ }
+
+ protected RequestBodyParser getBodyParser() {
+ return new JsonRequestBodyParser();
+ }
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java Mon Mar 11 19:26:49 2013
@@ -18,6 +18,8 @@
package org.apache.ambari.server.api.services;
+import org.apache.ambari.server.api.handlers.DeleteHandler;
+import org.apache.ambari.server.api.handlers.RequestHandler;
import org.apache.ambari.server.api.resources.ResourceInstance;
import javax.ws.rs.core.HttpHeaders;
@@ -35,7 +37,7 @@ public class DeleteRequest extends BaseR
* @param uriInfo uri information
* @param resource associated resource definition
*/
- public DeleteRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+ public DeleteRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
super(headers, body, uriInfo, resource);
}
@@ -44,4 +46,8 @@ public class DeleteRequest extends BaseR
return Type.DELETE;
}
+ @Override
+ protected RequestHandler getRequestHandler() {
+ return new DeleteHandler();
+ }
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java Mon Mar 11 19:26:49 2013
@@ -18,6 +18,8 @@
package org.apache.ambari.server.api.services;
+import org.apache.ambari.server.api.handlers.ReadHandler;
+import org.apache.ambari.server.api.handlers.RequestHandler;
import org.apache.ambari.server.api.resources.ResourceInstance;
import javax.ws.rs.core.HttpHeaders;
@@ -35,7 +37,7 @@ public class GetRequest extends BaseRequ
* @param uriInfo uri information
* @param resource associated resource definition
*/
- public GetRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+ public GetRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
super(headers, body, uriInfo, resource);
}
@@ -43,4 +45,9 @@ public class GetRequest extends BaseRequ
public Type getRequestType() {
return Type.GET;
}
+
+ @Override
+ protected RequestHandler getRequestHandler() {
+ return new ReadHandler();
+ }
}
Added: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/NamedPropertySet.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/NamedPropertySet.java?rev=1455293&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/NamedPropertySet.java (added)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/NamedPropertySet.java Mon Mar 11 19:26:49 2013
@@ -0,0 +1,85 @@
+/**
+ * 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.api.services;
+
+import java.util.Map;
+
+/**
+ * A named set of related properties.
+ */
+public class NamedPropertySet {
+ /**
+ * The name of this set of properties.
+ */
+ private String m_name;
+
+ /**
+ * Property name/value pairs.
+ */
+ private Map<String, Object> m_mapProperties;
+
+
+ /**
+ * Constructor.
+ *
+ * @param name name of this property set
+ * @param mapProperties associated properties
+ */
+ public NamedPropertySet(String name, Map<String, Object> mapProperties) {
+ m_name = name;
+ m_mapProperties = mapProperties;
+ }
+
+ /**
+ * Obtain the name of this property set.
+ *
+ * @return the name of this property set
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * Obtain the associated properties.
+ *
+ * @return the associated properties
+ */
+ public Map<String, Object> getProperties() {
+ return m_mapProperties;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ NamedPropertySet that = (NamedPropertySet) o;
+
+ return (m_mapProperties == null ? that.m_mapProperties == null : m_mapProperties.equals(that.m_mapProperties)) &&
+ (m_name == null ? that.m_name == null : m_name.equals(that.m_name));
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = m_name != null ? m_name.hashCode() : 0;
+ result = 31 * result + (m_mapProperties != null ? m_mapProperties.hashCode() : 0);
+ return result;
+ }
+}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java Mon Mar 11 19:26:49 2013
@@ -18,6 +18,8 @@
package org.apache.ambari.server.api.services;
+import org.apache.ambari.server.api.handlers.CreateHandler;
+import org.apache.ambari.server.api.handlers.RequestHandler;
import org.apache.ambari.server.api.resources.ResourceInstance;
import javax.ws.rs.core.HttpHeaders;
@@ -35,7 +37,7 @@ public class PostRequest extends BaseReq
* @param uriInfo uri information
* @param resource associated resource definition
*/
- public PostRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+ public PostRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
super(headers, body, uriInfo, resource);
}
@@ -44,4 +46,8 @@ public class PostRequest extends BaseReq
return Type.POST;
}
+ @Override
+ protected RequestHandler getRequestHandler() {
+ return new CreateHandler();
+ }
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java Mon Mar 11 19:26:49 2013
@@ -18,6 +18,8 @@
package org.apache.ambari.server.api.services;
+import org.apache.ambari.server.api.handlers.RequestHandler;
+import org.apache.ambari.server.api.handlers.UpdateHandler;
import org.apache.ambari.server.api.resources.ResourceInstance;
import javax.ws.rs.core.HttpHeaders;
@@ -35,7 +37,7 @@ public class PutRequest extends BaseRequ
* @param uriInfo uri information
* @param resource associated resource definition
*/
- public PutRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+ public PutRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
super(headers, body, uriInfo, resource);
}
@@ -44,4 +46,8 @@ public class PutRequest extends BaseRequ
return Type.PUT;
}
+ @Override
+ protected RequestHandler getRequestHandler() {
+ return new UpdateHandler();
+ }
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java Mon Mar 11 19:26:49 2013
@@ -19,12 +19,12 @@
package org.apache.ambari.server.api.services;
+import org.apache.ambari.server.api.handlers.QueryCreateHandler;
+import org.apache.ambari.server.api.handlers.RequestHandler;
import org.apache.ambari.server.api.resources.ResourceInstance;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriInfo;
-import java.util.Map;
-import java.util.Set;
/**
* Request for creating sub-resources of instances based on a query.
@@ -38,22 +38,17 @@ public class QueryPostRequest extends Po
* @param uriInfo uri information
* @param resource associated resource instance
*/
- public QueryPostRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+ public QueryPostRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) {
super(headers, body, uriInfo, resource);
}
@Override
- public Set<Map<String, Object>> getHttpBodyProperties() {
- String httpBody = getHttpBody();
- //strip array name
- int startIdx = httpBody.indexOf("[");
- int endIdx = httpBody.lastIndexOf("]");
-
- return getHttpBodyParser().parse(httpBody.substring(startIdx, endIdx + 1));
+ public Type getRequestType() {
+ return Type.QUERY_POST;
}
@Override
- public Type getRequestType() {
- return Type.QUERY_POST;
+ protected RequestHandler getRequestHandler() {
+ return new QueryCreateHandler();
}
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java Mon Mar 11 19:26:49 2013
@@ -18,10 +18,8 @@
package org.apache.ambari.server.api.services;
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
import org.apache.ambari.server.api.resources.ResourceDefinition;
import org.apache.ambari.server.api.resources.ResourceInstance;
-import org.apache.ambari.server.api.services.serializers.ResultSerializer;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.TemporalInfo;
@@ -46,6 +44,13 @@ public interface Request {
}
/**
+ * Process the request.
+ *
+ * @return the result
+ */
+ public Result process();
+
+ /**
* Obtain the resource definition which corresponds to the resource being operated on by the request.
* The resource definition provides information about the resource type;
*
@@ -76,13 +81,12 @@ public interface Request {
/**
* Obtain the query predicate that was built from the user provided predicate fields in the query string.
- * If multiple predicates are supplied, then they will be combined using the appropriate grouping predicate
- * such as 'AND'.
+ * If multiple predicates are supplied, then they will be combined using the appropriate logical grouping
+ * predicate such as 'AND'.
*
* @return the user defined predicate
- * @throws InvalidQueryException if the query syntax is invalid
*/
- public Predicate getQueryPredicate() throws InvalidQueryException;
+ public Predicate getQueryPredicate();
/**
* Obtain the partial response fields and associated temporal information which were provided
@@ -93,21 +97,6 @@ public interface Request {
public Map<String, TemporalInfo> getFields();
/**
- * Obtain the result serializer for the request. The default serializer is of type JSON.
- *
- * @return the result serializer for the request
- */
- public ResultSerializer getResultSerializer();
-
- /**
- * Obtain the processor which processes the result returned from the request handler.
- * The post processor adds additional information such as href fields to the result.
- *
- * @return the result processor associated with the request
- */
- public ResultPostProcessor getResultPostProcessor();
-
- /**
* Obtain the http headers associated with the request.
*
* @return the http headers
@@ -116,6 +105,9 @@ public interface Request {
/**
* Obtain the http body associated with the request.
+ * If query or partial response fields exist in the original body,
+ * they are not included in the returned body. Query and partial
+ * response data are available via the corresponding getters.
*
* @return the http body
*/
@@ -126,5 +118,5 @@ public interface Request {
*
* @return a set of maps containing the properties contained in the http body
*/
- public Set<Map<String, Object>> getHttpBodyProperties();
+ public Set<NamedPropertySet> getHttpBodyProperties();
}
Added: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java?rev=1455293&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java (added)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java Mon Mar 11 19:26:49 2013
@@ -0,0 +1,124 @@
+/**
+ * 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.api.services;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Represents the http body of the request.
+ */
+public class RequestBody {
+
+ /**
+ * The associated query.
+ */
+ private String m_query;
+
+ /**
+ * The associated partial response fields.
+ */
+ private String m_fields;
+
+ /**
+ * The body properties.
+ */
+ private Set<NamedPropertySet> m_propertySets = new HashSet<NamedPropertySet>();
+
+ /**
+ * The request body. Query and partial response data is stripped before setting.
+ */
+ private String m_body;
+
+
+ /**
+ * Set the query string.
+ *
+ * @param query the query string from the body
+ */
+ public void setQueryString(String query) {
+ m_query = query;
+ }
+
+ /**
+ * Obtain that query that was specified in the body.
+ *
+ * @return the query from the body or null if no query was present in the body
+ */
+ public String getQueryString() {
+ return m_query;
+ }
+
+ /**
+ * Set the partial response fields from the body.
+ *
+ * @param fields the partial response fields
+ */
+ public void setPartialResponseFields(String fields) {
+ m_fields = fields;
+ }
+
+ /**
+ * Obtain the partial response fields that were specified in the body.
+ *
+ * @return the partial response fields or null if not specified in the body
+ */
+ public String getPartialResponseFields() {
+ return m_fields;
+ }
+
+ /**
+ * Add a property set.
+ * A property set is a set of related properties and values.
+ * For example, if the body contained properties for three different resources to
+ * be created, each would be represented as distinct property set.
+ *
+ * @param propertySet the property set to add
+ */
+ public void addPropertySet(NamedPropertySet propertySet) {
+ m_propertySets.add(propertySet);
+ }
+
+ /**
+ * Obtain all property sets or an empty set if no properties were specified in the body.
+ *
+ * @return all property sets or an empty set
+ */
+ public Set<NamedPropertySet> getPropertySets() {
+ return m_propertySets;
+ }
+
+ /**
+ * Set the body from the request.
+ *
+ * @param body the request body
+ */
+ public void setBody(String body) {
+ m_body = body;
+ }
+
+ /**
+ * Obtain the request body.
+ *
+ * @return the request body
+ */
+ public String getBody() {
+ return m_body;
+ }
+}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java Mon Mar 11 19:26:49 2013
@@ -37,7 +37,7 @@ public class RequestFactory {
*
* @return a new Request instance
*/
- public Request createRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType,
+ public Request createRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, Request.Type requestType,
ResourceInstance resource) {
switch (requestType) {
case GET:
@@ -47,7 +47,7 @@ public class RequestFactory {
case DELETE:
return new DeleteRequest(headers, body, uriInfo, resource);
case POST:
- return (uriInfo.getQueryParameters().isEmpty() || body == null) ?
+ return ((uriInfo.getQueryParameters().isEmpty() && body.getQueryString() == null) || body == null) ?
new PostRequest(headers, body, uriInfo, resource) :
new QueryPostRequest(headers, body, uriInfo, resource);
default:
Added: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/BodyParseException.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/BodyParseException.java?rev=1455293&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/BodyParseException.java (added)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/BodyParseException.java Mon Mar 11 19:26:49 2013
@@ -0,0 +1,43 @@
+/**
+ * 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.api.services.parsers;
+
+/**
+ * Exception indicating that a failure occurred while parsing the request body.
+ */
+public class BodyParseException extends Exception {
+ /**
+ * Create exception by specifying the entire message.
+ *
+ * @param msg the message to set
+ */
+ public BodyParseException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Create exception with messaged based on an exception.
+ *
+ * @param e the exception to base the msg on
+ */
+ public BodyParseException(Exception e) {
+ super("Invalid Request: Malformed Request Body. An exception occurred parsing the request body: "
+ + e.getMessage());
+ }
+}
Added: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java?rev=1455293&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java (added)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java Mon Mar 11 19:26:49 2013
@@ -0,0 +1,116 @@
+/**
+ * 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.api.services.parsers;
+
+import org.apache.ambari.server.api.services.NamedPropertySet;
+import org.apache.ambari.server.api.services.RequestBody;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * JSON parser which parses a JSON string into a map of properties and values.
+ */
+public class JsonRequestBodyParser implements RequestBodyParser {
+ /**
+ * Logger instance.
+ */
+ private final static Logger LOG = LoggerFactory.getLogger(JsonRequestBodyParser.class);
+
+ private String m_body;
+
+ @Override
+ public RequestBody parse(String s) throws BodyParseException {
+ m_body = s;
+ RequestBody body = new RequestBody();
+
+ if (s != null && s.length() != 0) {
+ s = ensureArrayFormat(s);
+ ObjectMapper mapper = new ObjectMapper();
+ try {
+ JsonNode root = mapper.readTree(s);
+
+ Iterator<JsonNode> iter = root.getElements();
+ while (iter.hasNext()) {
+ Map<String, Object> mapProperties = new HashMap<String, Object>();
+ NamedPropertySet propertySet = new NamedPropertySet("", mapProperties);
+ JsonNode node = iter.next();
+ processNode(node, "", propertySet, body);
+
+ String query = (String) mapProperties.remove(QUERY_FIELD_PATH);
+ if (query != null) {
+ body.setQueryString(query);
+ }
+ if (propertySet.getProperties().size() != 0) {
+ body.addPropertySet(propertySet);
+ }
+ }
+
+ if (body.getPropertySets().size() != 0) {
+ body.setBody(m_body);
+ }
+ } catch (IOException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Caught exception parsing msg body.");
+ LOG.debug("Message Body: " + s, e);
+ }
+ throw new BodyParseException(e);
+ }
+ }
+ return body;
+ }
+
+ private void processNode(JsonNode node, String path, NamedPropertySet propertySet, RequestBody body) {
+ Iterator<String> iter = node.getFieldNames();
+ String name;
+ while (iter.hasNext()) {
+ name = iter.next();
+ JsonNode child = node.get(name);
+ if (child.isArray()) {
+ //array
+ Iterator<JsonNode> arrayIter = child.getElements();
+ while (arrayIter.hasNext()) {
+ NamedPropertySet arrayPropertySet = new NamedPropertySet(name, new HashMap<String, Object>());
+ processNode(arrayIter.next(), "", arrayPropertySet, body);
+ body.addPropertySet(arrayPropertySet);
+ }
+ } else if (child.isContainerNode()) {
+ // object
+ if (name.equals(BODY_TITLE)) {
+ name = "";
+ m_body = child.toString();
+ }
+ processNode(child, path.isEmpty() ? name : path + '/' + name, propertySet, body);
+ } else {
+ // field
+ propertySet.getProperties().put(PropertyHelper.getPropertyId(
+ path.equals(BODY_TITLE) ? "" : path, name), child.asText());
+ }
+ }
+ }
+
+ private String ensureArrayFormat(String s) {
+ return s.startsWith("[") ? s : '[' + s + ']';
+ }
+}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/RequestBodyParser.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/RequestBodyParser.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/RequestBodyParser.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/RequestBodyParser.java Mon Mar 11 19:26:49 2013
@@ -18,20 +18,29 @@
package org.apache.ambari.server.api.services.parsers;
-import java.util.Map;
-import java.util.Set;
+import org.apache.ambari.server.api.services.RequestBody;
/**
* Parse the provided String into a map of properties and associated values.
*/
public interface RequestBodyParser {
/**
- * Parse the provided string into a map of properties and values.
- * The key contains both the category hierarchy and the property name.
+ * Path to the query property.
+ */
+ public static final String QUERY_FIELD_PATH = "RequestInfo/query";
+
+ /**
+ * Path to the body object.
+ */
+ public static final String BODY_TITLE = "Body";
+
+ /**
+ * Parse the provided string into a request body which contains all properties in the string.
+ *
*
* @param s the string body to be parsed
*
- * @return a set of maps of properties or an empty set if no properties exist
+ * @return RequestBody instance containing all properties in the string
*/
- public Set<Map<String, Object>> parse(String s);
+ public RequestBody parse(String s) throws BodyParseException;
}
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java Mon Mar 11 19:26:49 2013
@@ -24,7 +24,10 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import org.apache.ambari.server.api.services.parsers.JsonPropertyParser;
+import org.apache.ambari.server.api.services.NamedPropertySet;
+import org.apache.ambari.server.api.services.RequestBody;
+import org.apache.ambari.server.api.services.parsers.BodyParseException;
+import org.apache.ambari.server.api.services.parsers.JsonRequestBodyParser;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.PropertyProvider;
import org.apache.ambari.server.controller.spi.Request;
@@ -110,12 +113,21 @@ public class HttpProxyPropertyProvider e
InputStream in = null;
try {
in = streamProvider.readFrom(url);
- r.setProperty(propertyIdToSet, new JsonPropertyParser().parse(IOUtils.toString(in, "UTF-8")));
+ //todo: should not use JsonRequestBodyParser as this is intended only for parsing http bodies.
+ RequestBody body = (new JsonRequestBodyParser().parse(IOUtils.toString(in, "UTF-8")));
+ Set<NamedPropertySet> setNamedProps = body.getPropertySets();
+ Set<Map<String,Object>> setProps = new HashSet<Map<String, Object>>(setNamedProps.size());
+ for (NamedPropertySet ps : setNamedProps) {
+ setProps.add(ps.getProperties());
+ }
+ r.setProperty(propertyIdToSet, setProps);
}
catch (IOException ioe) {
+ //todo: should not eat exception
LOG.error("Error reading HTTP response from " + url);
- }
- finally {
+ } catch (BodyParseException e) {
+ LOG.error("Error Parsing Json.", e);
+ } finally {
if (null != in) {
try {
in.close();
Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/TestSuite.java Mon Mar 11 19:26:49 2013
@@ -29,7 +29,8 @@ import org.apache.ambari.server.api.pred
import org.apache.ambari.server.api.query.QueryImplTest;
import org.apache.ambari.server.api.resources.ResourceInstanceImplTest;
import org.apache.ambari.server.api.services.*;
-import org.apache.ambari.server.api.services.parsers.JsonPropertyParserTest;
+import org.apache.ambari.server.api.services.parsers.BodyParseExceptionTest;
+import org.apache.ambari.server.api.services.parsers.JsonRequestBodyParserTest;
import org.apache.ambari.server.api.services.serializers.JsonSerializerTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -37,12 +38,13 @@ import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({ClusterServiceTest.class, HostServiceTest.class, ServiceServiceTest.class,
ComponentServiceTest.class, HostComponentServiceTest.class, ReadHandlerTest.class, QueryImplTest.class,
- JsonPropertyParserTest.class, CreateHandlerTest.class, UpdateHandlerTest.class, DeleteHandlerTest.class,
+ JsonRequestBodyParserTest.class, CreateHandlerTest.class, UpdateHandlerTest.class, DeleteHandlerTest.class,
PersistenceManagerImplTest.class, GetRequestTest.class, PutRequestTest.class, PostRequestTest.class,
- DeleteRequestTest.class, JsonSerializerTest.class, QueryCreateHandlerTest.class, ResourceInstanceImplTest.class,
- QueryLexerTest.class, QueryParserTest.class, IsEmptyOperatorTest.class, InOperatorTest.class,
- AndOperatorTest.class, OrOperatorTest.class, EqualsOperatorTest.class, GreaterEqualsOperatorTest.class,
- GreaterOperatorTest.class, LessEqualsOperatorTest.class, LessEqualsOperatorTest.class, NotEqualsOperatorTest.class,
- NotOperatorTest.class})
+ DeleteRequestTest.class, QueryPostRequestTest.class, JsonSerializerTest.class, QueryCreateHandlerTest.class,
+ ResourceInstanceImplTest.class, QueryLexerTest.class, QueryParserTest.class, IsEmptyOperatorTest.class,
+ InOperatorTest.class,AndOperatorTest.class, OrOperatorTest.class, EqualsOperatorTest.class,
+ GreaterEqualsOperatorTest.class, GreaterOperatorTest.class, LessEqualsOperatorTest.class,
+ LessEqualsOperatorTest.class, NotEqualsOperatorTest.class, NotOperatorTest.class, RequestBodyTest.class,
+ NamedPropertySetTest.class, BodyParseExceptionTest.class})
public class TestSuite {
}
Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/CreateHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/CreateHandlerTest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/CreateHandlerTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/CreateHandlerTest.java Mon Mar 11 19:26:49 2013
@@ -18,8 +18,8 @@
package org.apache.ambari.server.api.handlers;
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.NamedPropertySet;
import org.apache.ambari.server.api.services.ResultStatus;
import org.apache.ambari.server.api.services.persistence.PersistenceManager;
import org.apache.ambari.server.api.services.Request;
@@ -27,7 +27,6 @@ import org.apache.ambari.server.api.serv
import org.apache.ambari.server.api.util.TreeNode;
import org.apache.ambari.server.controller.spi.RequestStatus;
import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.junit.Test;
import java.util.*;
@@ -41,6 +40,57 @@ import static org.junit.Assert.*;
public class CreateHandlerTest {
@Test
+ public void testHandleRequest__Synchronous_NoPropsInBody() throws Exception {
+ Request request = createNiceMock(Request.class);
+ ResourceInstance resource = createNiceMock(ResourceInstance.class);
+ PersistenceManager pm = createStrictMock(PersistenceManager.class);
+ RequestStatus status = createNiceMock(RequestStatus.class);
+ Resource resource1 = createNiceMock(Resource.class);
+ Resource resource2 = createNiceMock(Resource.class);
+
+
+ Set<Resource> setResources = new HashSet<Resource>();
+ setResources.add(resource1);
+ setResources.add(resource2);
+
+ // expectations
+ expect(request.getResource()).andReturn(resource).atLeastOnce();
+ expect(request.getQueryPredicate()).andReturn(null).atLeastOnce();
+ expect(request.getHttpBodyProperties()).andReturn(new HashSet<NamedPropertySet>()).atLeastOnce();
+
+ expect(pm.create(eq(resource), eq(new HashSet<Map<String, Object>>()))).andReturn(status);
+ expect(status.getStatus()).andReturn(RequestStatus.Status.Complete);
+ expect(status.getAssociatedResources()).andReturn(setResources);
+ expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
+ expect(resource2.getType()).andReturn(Resource.Type.Cluster).anyTimes();
+
+ replay(request, resource, pm, status, resource1, resource2);
+
+ Result result = new TestCreateHandler(pm).handleRequest(request);
+
+ assertNotNull(result);
+ TreeNode<Resource> tree = result.getResultTree();
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> resourcesNode = tree.getChild("resources");
+ assertEquals(2, resourcesNode.getChildren().size());
+ boolean foundResource1 = false;
+ boolean foundResource2 = false;
+ for(TreeNode<Resource> child : resourcesNode.getChildren()) {
+ Resource r = child.getObject();
+ if (r == resource1 && ! foundResource1) {
+ foundResource1 = true;
+ } else if (r == resource2 && ! foundResource2) {
+ foundResource2 = true;
+ } else {
+ fail();
+ }
+ }
+
+ assertEquals(ResultStatus.STATUS.CREATED, result.getStatus().getStatus());
+ verify(request, resource, pm, status, resource1, resource2);
+ }
+
+ @Test
public void testHandleRequest__Synchronous() throws Exception {
Request request = createNiceMock(Request.class);
ResourceInstance resource = createNiceMock(ResourceInstance.class);
@@ -49,7 +99,14 @@ public class CreateHandlerTest {
Resource resource1 = createNiceMock(Resource.class);
Resource resource2 = createNiceMock(Resource.class);
- Set<Map<String, Object>> setResourceProperties = new HashSet<Map<String, Object>>();
+ Set<NamedPropertySet> setResourceProperties = new HashSet<NamedPropertySet>();
+ Map<String, Object> mapProps = new HashMap<String, Object>();
+ mapProps.put("foo", "bar");
+ NamedPropertySet namedPropSet = new NamedPropertySet("name", mapProps);
+ setResourceProperties.add(namedPropSet);
+
+ Set<Map<String, Object>> setProps = new HashSet<Map<String, Object>>();
+ setProps.add(mapProps);
Set<Resource> setResources = new HashSet<Resource>();
setResources.add(resource1);
@@ -60,7 +117,7 @@ public class CreateHandlerTest {
expect(request.getQueryPredicate()).andReturn(null).atLeastOnce();
expect(request.getHttpBodyProperties()).andReturn(setResourceProperties).atLeastOnce();
- expect(pm.create(resource, setResourceProperties)).andReturn(status);
+ expect(pm.create(eq(resource), eq(setProps))).andReturn(status);
expect(status.getStatus()).andReturn(RequestStatus.Status.Complete);
expect(status.getAssociatedResources()).andReturn(setResources);
expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
@@ -102,7 +159,6 @@ public class CreateHandlerTest {
Resource resource2 = createNiceMock(Resource.class);
Resource requestResource = createNiceMock(Resource.class);
- Set<Map<String, Object>> setResourceProperties = new HashSet<Map<String, Object>>();
Set<Resource> setResources = new HashSet<Resource>();
setResources.add(resource1);
@@ -110,10 +166,10 @@ public class CreateHandlerTest {
// expectations
expect(request.getResource()).andReturn(resource);
- expect(request.getHttpBodyProperties()).andReturn(setResourceProperties);
+ expect(request.getHttpBodyProperties()).andReturn(new HashSet<NamedPropertySet>()).atLeastOnce();
expect(request.getQueryPredicate()).andReturn(null).atLeastOnce();
- expect(pm.create(resource, setResourceProperties)).andReturn(status);
+ expect(pm.create(eq(resource), eq(new HashSet<Map<String, Object>>()))).andReturn(status);
expect(status.getStatus()).andReturn(RequestStatus.Status.Accepted);
expect(status.getAssociatedResources()).andReturn(setResources);
expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
@@ -163,21 +219,4 @@ public class CreateHandlerTest {
return m_testPm;
}
}
-
- @Test
- public void testHandleRequest__InvalidQuery() throws Exception {
- Request request = createNiceMock(Request.class);
- ResourceInstance resource = createNiceMock(ResourceInstance.class);
- Exception e = new InvalidQueryException("test exception");
-
- expect(request.getResource()).andReturn(resource);
- expect(request.getQueryPredicate()).andThrow(e);
- replay(request, resource);
-
- Result result = new CreateHandler().handleRequest(request);
- assertEquals(ResultStatus.STATUS.BAD_REQUEST, result.getStatus().getStatus());
- assertTrue(result.getStatus().getMessage().contains(e.getMessage()));
-
- verify(request, resource);
- }
}
Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/DeleteHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/DeleteHandlerTest.java?rev=1455293&r1=1455292&r2=1455293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/DeleteHandlerTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/DeleteHandlerTest.java Mon Mar 11 19:26:49 2013
@@ -18,9 +18,9 @@ package org.apache.ambari.server.api.han
* limitations under the License.
*/
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
import org.apache.ambari.server.api.query.Query;
import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.NamedPropertySet;
import org.apache.ambari.server.api.services.ResultStatus;
import org.apache.ambari.server.api.services.persistence.PersistenceManager;
import org.apache.ambari.server.api.services.Request;
@@ -43,7 +43,7 @@ import static org.junit.Assert.assertEqu
public class DeleteHandlerTest {
@Test
- public void testHandleRequest__Synchronous() throws Exception {
+ public void testHandleRequest__Synchronous_NoPropsInBody() throws Exception {
Request request = createMock(Request.class);
ResourceInstance resource = createMock(ResourceInstance.class);
PersistenceManager pm = createStrictMock(PersistenceManager.class);
@@ -53,12 +53,74 @@ public class DeleteHandlerTest {
Predicate userPredicate = createNiceMock(Predicate.class);
Query query = createNiceMock(Query.class);
- Set<Map<String, Object>> setResourceProperties = new HashSet<Map<String, Object>>();
+ Set<Resource> setResources = new HashSet<Resource>();
+ setResources.add(resource1);
+ setResources.add(resource2);
+
+ // expectations
+ expect(request.getResource()).andReturn(resource).atLeastOnce();
+ expect(request.getHttpBodyProperties()).andReturn(new HashSet<NamedPropertySet>()).atLeastOnce();
+
+ expect(request.getQueryPredicate()).andReturn(userPredicate).atLeastOnce();
+ expect(resource.getQuery()).andReturn(query).atLeastOnce();
+ query.setUserPredicate(userPredicate);
+
+ expect(pm.delete(eq(resource), eq(new HashSet<Map<String, Object>>()))).andReturn(status);
+ expect(status.getStatus()).andReturn(RequestStatus.Status.Complete);
+ expect(status.getAssociatedResources()).andReturn(setResources);
+ expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
+ expect(resource2.getType()).andReturn(Resource.Type.Cluster).anyTimes();
+
+ replay(request, resource, pm, status, resource1, resource2, userPredicate, query);
+
+ Result result = new TestDeleteHandler(pm).handleRequest(request);
+
+ assertNotNull(result);
+ TreeNode<Resource> tree = result.getResultTree();
+ assertEquals(1, tree.getChildren().size());
+ TreeNode<Resource> resourcesNode = tree.getChild("resources");
+ assertEquals(2, resourcesNode.getChildren().size());
+ boolean foundResource1 = false;
+ boolean foundResource2 = false;
+ for(TreeNode<Resource> child : resourcesNode.getChildren()) {
+ Resource r = child.getObject();
+ if (r == resource1 && ! foundResource1) {
+ foundResource1 = true;
+ } else if (r == resource2 && ! foundResource2) {
+ foundResource2 = true;
+ } else {
+ fail();
+ }
+ }
+
+ assertEquals(ResultStatus.STATUS.OK, result.getStatus().getStatus());
+ verify(request, resource, pm, status, resource1, resource2, userPredicate, query);
+ }
+
+ @Test
+ public void testHandleRequest__Synchronous() throws Exception {
+ Request request = createMock(Request.class);
+ ResourceInstance resource = createMock(ResourceInstance.class);
+ PersistenceManager pm = createStrictMock(PersistenceManager.class);
+ RequestStatus status = createMock(RequestStatus.class);
+ Resource resource1 = createMock(Resource.class);
+ Resource resource2 = createMock(Resource.class);
+ Predicate userPredicate = createNiceMock(Predicate.class);
+ Query query = createNiceMock(Query.class);
Set<Resource> setResources = new HashSet<Resource>();
setResources.add(resource1);
setResources.add(resource2);
+ Set<NamedPropertySet> setResourceProperties = new HashSet<NamedPropertySet>();
+ Map<String, Object> mapProps = new HashMap<String, Object>();
+ mapProps.put("foo", "bar");
+ NamedPropertySet namedPropSet = new NamedPropertySet("name", mapProps);
+ setResourceProperties.add(namedPropSet);
+
+ Set<Map<String, Object>> setProps = new HashSet<Map<String, Object>>();
+ setProps.add(mapProps);
+
// expectations
expect(request.getResource()).andReturn(resource).atLeastOnce();
expect(request.getHttpBodyProperties()).andReturn(setResourceProperties).atLeastOnce();
@@ -67,7 +129,7 @@ public class DeleteHandlerTest {
expect(resource.getQuery()).andReturn(query).atLeastOnce();
query.setUserPredicate(userPredicate);
- expect(pm.delete(resource, setResourceProperties)).andReturn(status);
+ expect(pm.delete(eq(resource), eq(setProps))).andReturn(status);
expect(status.getStatus()).andReturn(RequestStatus.Status.Complete);
expect(status.getAssociatedResources()).andReturn(setResources);
expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
@@ -99,6 +161,7 @@ public class DeleteHandlerTest {
verify(request, resource, pm, status, resource1, resource2, userPredicate, query);
}
+
@Test
public void testHandleRequest__Asynchronous() throws Exception {
Request request = createMock(Request.class);
@@ -109,19 +172,17 @@ public class DeleteHandlerTest {
Resource resource2 = createMock(Resource.class);
Resource requestResource = createMock(Resource.class);
- Set<Map<String, Object>> setResourceProperties = new HashSet<Map<String, Object>>();
-
Set<Resource> setResources = new HashSet<Resource>();
setResources.add(resource1);
setResources.add(resource2);
// expectations
expect(request.getResource()).andReturn(resource);
- expect(request.getHttpBodyProperties()).andReturn(setResourceProperties);
+ expect(request.getHttpBodyProperties()).andReturn(new HashSet<NamedPropertySet>()).atLeastOnce();
// test delete with no user predicate
expect(request.getQueryPredicate()).andReturn(null).atLeastOnce();
- expect(pm.delete(resource, setResourceProperties)).andReturn(status);
+ expect(pm.delete(eq(resource), eq(new HashSet<Map<String, Object>>()))).andReturn(status);
expect(status.getStatus()).andReturn(RequestStatus.Status.Accepted);
expect(status.getAssociatedResources()).andReturn(setResources);
expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
@@ -171,21 +232,4 @@ public class DeleteHandlerTest {
return m_testPm;
}
}
-
- @Test
- public void testHandleRequest__InvalidQuery() throws Exception {
- Request request = createNiceMock(Request.class);
- ResourceInstance resource = createNiceMock(ResourceInstance.class);
- Exception e = new InvalidQueryException("test exception");
-
- expect(request.getResource()).andReturn(resource);
- expect(request.getQueryPredicate()).andThrow(e);
- replay(request, resource);
-
- Result result = new DeleteHandler().handleRequest(request);
- assertEquals(ResultStatus.STATUS.BAD_REQUEST, result.getStatus().getStatus());
- assertTrue(result.getStatus().getMessage().contains(e.getMessage()));
-
- verify(request, resource);
- }
}
\ No newline at end of file