Repository: ambari Updated Branches: refs/heads/trunk 116d98534 -> 80f1beaac
AMBARI-16142. Add getDeleteDirectives to ResourceDefinition (ajit) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/80f1beaa Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/80f1beaa Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/80f1beaa Branch: refs/heads/trunk Commit: 80f1beaac13812a5c0f743242247f6b8e6b0aea2 Parents: 116d985 Author: Ajit Kumar <[email protected]> Authored: Wed Apr 27 16:10:07 2016 -0700 Committer: Ajit Kumar <[email protected]> Committed: Wed Apr 27 16:10:07 2016 -0700 ---------------------------------------------------------------------- .../api/resources/BaseResourceDefinition.java | 18 ++--- .../api/resources/ResourceDefinition.java | 45 +++++++----- .../ambari/server/api/services/BaseRequest.java | 3 + .../server/api/services/RequestFactory.java | 12 +++- .../server/api/services/BaseRequestTest.java | 16 ++--- .../server/api/services/RequestFactoryTest.java | 76 ++++++++++++++++++++ .../creator/AuditEventCreatorTestHelper.java | 5 ++ 7 files changed, 142 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseResourceDefinition.java index c8bf87d..dcc5217 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseResourceDefinition.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseResourceDefinition.java @@ -147,6 +147,16 @@ public abstract class BaseResourceDefinition implements ResourceDefinition { } @Override + public Collection<String> getUpdateDirectives() { + return new HashSet<>(); + } + + @Override + public Collection<String> getDeleteDirectives() { + return new HashSet<>(); + } + + @Override public boolean equals(Object o) { boolean result =false; if(this == o) result = true; @@ -215,12 +225,4 @@ public abstract class BaseResourceDefinition implements ResourceDefinition { } } } - - /** - * Returns a collection which can be modified by sub resources - */ - @Override - public Collection<String> getUpdateDirectives() { - return new HashSet<String>(); - } } http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceDefinition.java index f98379c..8df1a02 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceDefinition.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceDefinition.java @@ -39,28 +39,28 @@ public interface ResourceDefinition { * * @return the plural name of the resource */ - public String getPluralName(); + String getPluralName(); /** * Obtain the singular name of the resource. * * @return the singular name of the resource */ - public String getSingularName(); + String getSingularName(); /** * Obtain the type of resource. Is one of {@link Resource.Type}. * * @return the type of resource */ - public Resource.Type getType(); + Resource.Type getType(); /** * Obtain a set of all child resource types. * * @return set of sub-resource definitions */ - public Set<SubResourceDefinition> getSubResourceDefinitions(); + Set<SubResourceDefinition> getSubResourceDefinitions(); /** * Obtain any resource post processors. A resource processor is used to provide resource specific processing of @@ -68,7 +68,7 @@ public interface ResourceDefinition { * * @return list of resource specific result processors */ - public List<PostProcessor> getPostProcessors(); + List<PostProcessor> getPostProcessors(); /** * Obtain the associated renderer based on name. @@ -78,7 +78,7 @@ public interface ResourceDefinition { * @return associated renderer instance * @throws IllegalArgumentException if name is invalid for this resource */ - public Renderer getRenderer(String name) throws IllegalArgumentException; + Renderer getRenderer(String name) throws IllegalArgumentException; /** * Obtain the set of create directives for the resource. A create directive is @@ -87,29 +87,42 @@ public interface ResourceDefinition { * map of request info properties used by the resource provider when creating * the resource. */ - public Collection<String> getCreateDirectives(); + Collection<String> getCreateDirectives(); + + /** + * Obtain the set of update directives for the resource. An update directive is + * information that can be provided in the query string of a PUT operation for + * the resource. These directives are not predicates but are put into the + * map of request info properties used by the resource provider when updating + * the resource. + */ + Collection<String> getUpdateDirectives(); + + /** + * Obtain the set of delete directives for the resource. A delete directive is + * information that can be provided in the query string of a DELETE operation for + * the resource. These directives are not predicates but are put into the + * map of request info properties used by the resource provider when updating + * the resource. + */ + Collection<String> getDeleteDirectives(); /** * Defines if resource is actually created on the server side during POST * operation. - * + * * @see <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5"> * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5</a> * @return {@code true} if resource is creatable, {@code false} otherwise */ - public boolean isCreatable(); + boolean isCreatable(); /** * Resource specific result processor. * Used to provide resource specific processing of a result. */ - public interface PostProcessor { - public void process(Request request, TreeNode<Resource> resultNode, String href); + interface PostProcessor { + void process(Request request, TreeNode<Resource> resultNode, String href); } - - /** - * Retrieves directives from the URI - */ - public Collection<String> getUpdateDirectives(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/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 88b8170..0ebeb19 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 @@ -329,6 +329,9 @@ public abstract class BaseRequest implements Request { case POST: ignoredProperties = m_resource.getResourceDefinition().getCreateDirectives(); break; + case DELETE: + ignoredProperties = m_resource.getResourceDefinition().getDeleteDirectives(); + break; default: break; } http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java index e12cb42..19fee8e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java @@ -50,7 +50,7 @@ public class RequestFactory { case PUT: return createPutRequest(headers, body, uriInfo, resource); case DELETE: - return new DeleteRequest(headers, body, uriInfo, resource); + return createDeleteRequest(headers, body, uriInfo, resource); case POST: return createPostRequest(headers, body, uriInfo, resource); default: @@ -85,6 +85,13 @@ public class RequestFactory { return new PutRequest(headers, body, uriInfo, resource); } + /** + * Creates a DELETE request. It will apply any eligible directives supplied in the URI + */ + private DeleteRequest createDeleteRequest(HttpHeaders headers, RequestBody body, UriInfo uriInfo, ResourceInstance resource) { + applyDirectives(Request.Type.DELETE, body, uriInfo, resource); + return new DeleteRequest(headers, body, uriInfo, resource); + } /** * Gather query parameters from uri and body query string. @@ -145,6 +152,9 @@ public class RequestFactory { case POST: directives = resourceDefinition.getCreateDirectives(); break; + case DELETE: + directives = resourceDefinition.getDeleteDirectives(); + break; default: // not yet implemented for other types return false; http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java index d4affea..a361f98 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java @@ -19,6 +19,7 @@ package org.apache.ambari.server.api.services; import com.sun.jersey.core.util.MultivaluedMapImpl; +import com.sun.jersey.core.util.UnmodifiableMultivaluedMap; import org.apache.ambari.server.api.handlers.RequestHandler; import org.apache.ambari.server.api.predicate.InvalidQueryException; import org.apache.ambari.server.api.predicate.PredicateCompiler; @@ -134,7 +135,7 @@ public abstract class BaseRequestTest { Predicate predicate = createNiceMock(Predicate.class); UriInfo uriInfo = createMock(UriInfo.class); @SuppressWarnings("unchecked") - MultivaluedMap<String, String> queryParams = createMock(MultivaluedMap.class); + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); RequestHandler handler = createStrictMock(RequestHandler.class); Result result = createMock(Result.class); ResultStatus resultStatus = createMock(ResultStatus.class); @@ -142,23 +143,22 @@ public abstract class BaseRequestTest { RequestBody body = createNiceMock(RequestBody.class); ResourceInstance resource = createNiceMock(ResourceInstance.class); ResourceDefinition resourceDefinition = createNiceMock(ResourceDefinition.class); - Set<String> directives = new HashSet<String>(); - directives.add("my_directive"); + Set<String> directives = Collections.singleton("my_directive"); Renderer renderer = new DefaultRenderer(); Request request = getTestRequest(headers, body, uriInfo, compiler, handler, processor, resource); //expectations expect(uriInfo.getQueryParameters()).andReturn(queryParams).anyTimes(); - expect(queryParams.getFirst(QueryLexer.QUERY_MINIMAL)).andReturn(null); - expect(queryParams.getFirst(QueryLexer.QUERY_FORMAT)).andReturn(null); expect(resource.getResourceDefinition()).andReturn(resourceDefinition).anyTimes(); expect(resourceDefinition.getUpdateDirectives()).andReturn(directives).anyTimes(); // for PUT implementation expect(resourceDefinition.getCreateDirectives()).andReturn(directives).anyTimes(); // for POST implementation + expect(resourceDefinition.getDeleteDirectives()).andReturn(directives).anyTimes(); // for DELETE implementation expect(resourceDefinition.getRenderer(null)).andReturn(renderer); expect(uriInfo.getRequestUri()).andReturn(uri).anyTimes(); expect(body.getQueryString()).andReturn(null); - if (request.getRequestType().equals(Request.Type.POST) || request.getRequestType().equals(Request.Type.PUT)) + if (request.getRequestType() == Request.Type.POST || request.getRequestType() == Request.Type.PUT + || request.getRequestType() == Request.Type.DELETE) { expect(compiler.compile("foo=foo-value&bar=bar-value", directives)).andReturn(predicate); } @@ -172,12 +172,12 @@ public abstract class BaseRequestTest { processor.process(result); - replay(headers, compiler, uriInfo, handler, queryParams, resource, + replay(headers, compiler, uriInfo, handler, resource, resourceDefinition, result, resultStatus, processor, predicate, body); Result processResult = request.process(); - verify(headers, compiler, uriInfo, handler, queryParams, resource, + verify(headers, compiler, uriInfo, handler, resource, resourceDefinition, result, resultStatus, processor, predicate, body); assertSame(processResult, result); http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestFactoryTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestFactoryTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestFactoryTest.java index 0ef4312..11568c9 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestFactoryTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/RequestFactoryTest.java @@ -30,6 +30,7 @@ import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; +import com.sun.jersey.core.util.MultivaluedMapImpl; import org.apache.ambari.server.api.resources.ResourceDefinition; import org.apache.ambari.server.api.resources.ResourceInstance; import org.junit.Test; @@ -182,6 +183,81 @@ public class RequestFactoryTest { } @Test + // delete with delete directive in URI + public void testCreate_Delete__WithUriDirective() { + HttpHeaders headers = createNiceMock(HttpHeaders.class); + UriInfo uriInfo = createNiceMock(UriInfo.class); + RequestBody body = createNiceMock(RequestBody.class); + ResourceInstance resource = createNiceMock(ResourceInstance.class); + ResourceDefinition resourceDefinition = createNiceMock(ResourceDefinition.class); + + @SuppressWarnings("unchecked") + MultivaluedMap<String, String> mapQueryParams = createMock(MultivaluedMap.class); + Map<String, List<String>> mapProps = new HashMap<>(); + mapProps.put("foo", Collections.singletonList("bar")); + + Map<String, String> requestInfoMap = new HashMap<>(); + + //expectations + expect(uriInfo.getQueryParameters()).andReturn(mapQueryParams).anyTimes(); + expect(mapQueryParams.entrySet()).andReturn(mapProps.entrySet()).anyTimes(); + expect(resource.getResourceDefinition()).andReturn(resourceDefinition).anyTimes(); + expect(resourceDefinition.getDeleteDirectives()).andReturn(Collections.singleton("foo")); + expect(body.getQueryString()).andReturn(null); + expect(body.getRequestInfoProperties()).andReturn(requestInfoMap).anyTimes(); + + replay(headers, uriInfo, body, resource, mapQueryParams, resourceDefinition); + + //test + RequestFactory factory = new RequestFactory(); + Request request = factory.createRequest(headers, body, uriInfo, Request.Type.DELETE, resource); + + assertEquals(resource, request.getResource()); + assertEquals(body, request.getBody()); + assertEquals(Request.Type.DELETE, request.getRequestType()); + assertEquals("bar", requestInfoMap.get("foo")); + + verify(headers, uriInfo, body, resource, mapQueryParams, resourceDefinition); + } + + @Test + // delete w/o delete directive in URI + public void testCreate_Delete__WithoutUriDirective() { + HttpHeaders headers = createNiceMock(HttpHeaders.class); + UriInfo uriInfo = createNiceMock(UriInfo.class); + RequestBody body = createNiceMock(RequestBody.class); + ResourceInstance resource = createNiceMock(ResourceInstance.class); + ResourceDefinition resourceDefinition = createNiceMock(ResourceDefinition.class); + + @SuppressWarnings("unchecked") + MultivaluedMap<String, String> mapQueryParams = createMock(MultivaluedMap.class); + Map<String, List<String>> mapProps = new HashMap<>(); + mapProps.put("foo", Collections.singletonList("bar")); + + Map<String, String> requestInfoMap = new HashMap<>(); + + //expectations + expect(uriInfo.getQueryParameters()).andReturn(mapQueryParams).anyTimes(); + expect(mapQueryParams.entrySet()).andReturn(mapProps.entrySet()).anyTimes(); + expect(resource.getResourceDefinition()).andReturn(resourceDefinition).anyTimes(); + expect(resourceDefinition.getDeleteDirectives()).andReturn(Collections.<String>emptySet()); + expect(body.getQueryString()).andReturn(null); + expect(body.getRequestInfoProperties()).andReturn(requestInfoMap).anyTimes(); + + replay(headers, uriInfo, body, resource, mapQueryParams, resourceDefinition); + + //test + RequestFactory factory = new RequestFactory(); + Request request = factory.createRequest(headers, body, uriInfo, Request.Type.DELETE, resource); + + assertEquals(resource, request.getResource()); + assertEquals(body, request.getBody()); + assertEquals(Request.Type.DELETE, request.getRequestType()); + assertEquals(null, requestInfoMap.get("foo")); + verify(headers, uriInfo, body, resource, mapQueryParams, resourceDefinition); + } + + @Test // query post : body contains query string public void testCreate_Post__BodyQueryParams() { HttpHeaders headers = createNiceMock(HttpHeaders.class); http://git-wip-us.apache.org/repos/asf/ambari/blob/80f1beaa/ambari-server/src/test/java/org/apache/ambari/server/audit/request/creator/AuditEventCreatorTestHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/audit/request/creator/AuditEventCreatorTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/audit/request/creator/AuditEventCreatorTestHelper.java index 29bd8e9..2642418 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/audit/request/creator/AuditEventCreatorTestHelper.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/audit/request/creator/AuditEventCreatorTestHelper.java @@ -148,6 +148,11 @@ public class AuditEventCreatorTestHelper { public Collection<String> getUpdateDirectives() { return null; } + + @Override + public Collection<String> getDeleteDirectives() { + return null; + } }; }
