You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by aj...@apache.org on 2016/04/21 01:01:32 UTC
ambari git commit: AMBARI-15847. add bulk host delete api
Repository: ambari
Updated Branches:
refs/heads/trunk 5af48693e -> cc10ec0b4
AMBARI-15847. add bulk host delete api
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/cc10ec0b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/cc10ec0b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/cc10ec0b
Branch: refs/heads/trunk
Commit: cc10ec0b4acdfb522ff193fc66f777aa82b9f6be
Parents: 5af4869
Author: Ajit Kumar <aj...@apache.org>
Authored: Wed Apr 20 16:01:24 2016 -0700
Committer: Ajit Kumar <aj...@apache.org>
Committed: Wed Apr 20 16:01:24 2016 -0700
----------------------------------------------------------------------
.../ambari/server/api/services/HostService.java | 8 ++
.../internal/HostResourceProvider.java | 82 +++++++++++++-------
.../server/api/handlers/UpdateHandlerTest.java | 60 +-------------
.../creator/AuditEventCreatorTestHelper.java | 11 +++
4 files changed, 77 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc10ec0b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
index c54d30f..0ce29ae 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
@@ -195,6 +195,14 @@ public class HostService extends BaseService {
createHostResource(m_clusterName, hostName, ui));
}
+ @DELETE
+ @Produces("text/plain")
+ public Response deleteHosts(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+
+ return handleRequest(headers, body, ui, Request.Type.DELETE,
+ createHostResource(m_clusterName, null, ui));
+ }
+
/**
* Get the host_components sub-resource.
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc10ec0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
index 2bd1664..4dc47be 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
@@ -333,22 +333,21 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
protected RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
- final Set<HostRequest> requests = new HashSet<HostRequest>();
+ final Set<HostRequest> requests = new HashSet<>();
for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
requests.add(getRequest(propertyMap));
}
- modifyResources(new Command<Void>() {
+ DeleteStatusMetaData deleteStatusMetaData = modifyResources(new Command<DeleteStatusMetaData>() {
@Override
- public Void invoke() throws AmbariException {
- deleteHosts(requests);
- return null;
+ public DeleteStatusMetaData invoke() throws AmbariException {
+ return deleteHosts(requests);
}
});
notifyDelete(Resource.Type.Host, predicate);
- return getRequestStatus(null);
+ return getRequestStatus(null, null, deleteStatusMetaData);
}
@Override
@@ -828,13 +827,14 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
}
@Transactional
- protected void deleteHosts(Set<HostRequest> requests)
+ protected DeleteStatusMetaData deleteHosts(Set<HostRequest> requests)
throws AmbariException {
AmbariManagementController controller = getManagementController();
Clusters clusters = controller.getClusters();
+ DeleteStatusMetaData deleteStatusMetaData = new DeleteStatusMetaData();
- List<HostRequest> okToRemove = new ArrayList<HostRequest>();
+ List<HostRequest> okToRemove = new ArrayList<>();
for (HostRequest hostRequest : requests) {
String hostName = hostRequest.getHostname();
@@ -842,7 +842,54 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
continue;
}
- Set<String> clusterNamesForHost = new HashSet<String>();
+ try {
+ validateHostInDeleteFriendlyState(hostRequest, clusters);
+ okToRemove.add(hostRequest);
+ } catch (Exception ex) {
+ deleteStatusMetaData.addException(hostName, ex);
+ }
+ }
+
+ for (HostRequest hostRequest : okToRemove) {
+ // Assume the user also wants to delete it entirely, including all clusters.
+ String hostname = hostRequest.getHostname();
+ try {
+ clusters.deleteHost(hostname);
+ deleteStatusMetaData.addDeletedKey(hostname);
+ } catch (Exception ex) {
+ deleteStatusMetaData.addException(hostname, ex);
+ }
+ for (LogicalRequest logicalRequest: topologyManager.getRequests(Collections.<Long>emptyList())) {
+ logicalRequest.removeHostRequestByHostName(hostname);
+ }
+
+ if (null != hostRequest.getClusterName()) {
+ clusters.getCluster(hostRequest.getClusterName()).recalculateAllClusterVersionStates();
+ }
+ }
+
+ //Do not break behavior for existing clients where delete request contains only 1 host.
+ //Response for these requests will have empty body with appropriate error code.
+ if (deleteStatusMetaData.getDeletedKeys().size() + deleteStatusMetaData.getExceptionForKeys().size() == 1) {
+ if (deleteStatusMetaData.getDeletedKeys().size() == 1) {
+ return null;
+ }
+ for (Map.Entry<String, Exception> entry : deleteStatusMetaData.getExceptionForKeys().entrySet()) {
+ Exception ex = entry.getValue();
+ if (ex instanceof AmbariException) {
+ throw (AmbariException)ex;
+ } else {
+ throw new AmbariException(ex.getMessage(), ex);
+ }
+ }
+ }
+
+ return deleteStatusMetaData;
+ }
+
+ private void validateHostInDeleteFriendlyState(HostRequest hostRequest, Clusters clusters ) throws AmbariException {
+ Set<String> clusterNamesForHost = new HashSet<>();
+ String hostName = hostRequest.getHostname();
if (null != hostRequest.getClusterName()) {
clusterNamesForHost.add(hostRequest.getClusterName());
} else {
@@ -885,23 +932,6 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
}
}
}
- okToRemove.add(hostRequest);
- }
-
- for (HostRequest hostRequest : okToRemove) {
- // Assume the user also wants to delete it entirely, including all clusters.
- clusters.deleteHost(hostRequest.getHostname());
-
- removeHostFromClusterTopology(clusters, hostRequest);
-
- for (LogicalRequest logicalRequest: topologyManager.getRequests(Collections.<Long>emptyList())) {
- logicalRequest.removeHostRequestByHostName(hostRequest.getHostname());
- }
-
- if (null != hostRequest.getClusterName()) {
- clusters.getCluster(hostRequest.getClusterName()).recalculateAllClusterVersionStates();
- }
- }
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc10ec0b/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/UpdateHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/UpdateHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/UpdateHandlerTest.java
index 85eea31..797ba65 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/UpdateHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/handlers/UpdateHandlerTest.java
@@ -51,64 +51,6 @@ public class UpdateHandlerTest {
ViewRegistry.initInstance(new ViewRegistry(publisher));
}
- @Test
- public void testHandleRequest__Synchronous_NoPropsInBody() throws Exception {
- Request request = createMock(Request.class);
- RequestBody body = createNiceMock(RequestBody.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);
- Renderer renderer = new DefaultRenderer();
-
- Set<Resource> setResources = new HashSet<Resource>();
- setResources.add(resource1);
- setResources.add(resource2);
-
- // expectations
- expect(request.getResource()).andReturn(resource).anyTimes();
- expect(request.getBody()).andReturn(body).anyTimes();
- expect(request.getQueryPredicate()).andReturn(userPredicate).atLeastOnce();
- expect(request.getRenderer()).andReturn(renderer);
-
- expect(resource.getQuery()).andReturn(query).atLeastOnce();
- query.setRenderer(renderer);
- query.setUserPredicate(userPredicate);
-
- expect(pm.update(resource, body)).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, body, resource, pm, status, resource1, resource2, userPredicate, query);
-
- Result result = new TestUpdateHandler(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, body, resource, pm, status, resource1, resource2, userPredicate, query);
- }
@Test
public void testHandleRequest__Synchronous() throws Exception {
@@ -139,6 +81,7 @@ public class UpdateHandlerTest {
expect(pm.update(resource, body)).andReturn(status);
expect(status.getStatus()).andReturn(RequestStatus.Status.Complete);
+ expect(status.getStatusMetadata()).andReturn(null);
expect(status.getAssociatedResources()).andReturn(setResources);
expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
expect(resource2.getType()).andReturn(Resource.Type.Cluster).anyTimes();
@@ -199,6 +142,7 @@ public class UpdateHandlerTest {
expect(pm.update(resource, body)).andReturn(status);
expect(status.getStatus()).andReturn(RequestStatus.Status.Accepted);
+ expect(status.getStatusMetadata()).andReturn(null);
expect(status.getAssociatedResources()).andReturn(setResources);
expect(resource1.getType()).andReturn(Resource.Type.Cluster).anyTimes();
expect(resource2.getType()).andReturn(Resource.Type.Cluster).anyTimes();
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc10ec0b/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 86c1ebb..29bd8e9 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
@@ -33,6 +33,7 @@ import org.apache.ambari.server.api.services.NamedPropertySet;
import org.apache.ambari.server.api.services.Request;
import org.apache.ambari.server.api.services.RequestBody;
import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultMetadata;
import org.apache.ambari.server.api.services.ResultStatus;
import org.apache.ambari.server.api.util.TreeNode;
import org.apache.ambari.server.audit.AuditLogger;
@@ -248,6 +249,16 @@ public class AuditEventCreatorTestHelper {
public void setResultStatus(ResultStatus status) {
}
+
+ @Override
+ public void setResultMetadata(ResultMetadata resultMetadata) {
+
+ }
+
+ @Override
+ public ResultMetadata getResultMetadata() {
+ return null;
+ }
};
}
}