Repository: knox Updated Branches: refs/heads/master b31c15af0 -> 335e87337
http://git-wip-us.apache.org/repos/asf/knox/blob/335e8733/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java ---------------------------------------------------------------------- diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java index 7482389..e306d24 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java @@ -449,6 +449,11 @@ public class DefaultTopologyService @Override public boolean deleteProviderConfiguration(String name) { + return deleteProviderConfiguration(name, false); + } + + @Override + public boolean deleteProviderConfiguration(String name, boolean force) { boolean result = false; // Determine if the file exists, and if so, if there are any descriptors referencing it @@ -462,7 +467,7 @@ public class DefaultTopologyService } // If the local file does not exist, or it does exist and there are NOT any referencing descriptors - if (providerConfig == null || !hasReferences) { + if (force || (providerConfig == null || !hasReferences)) { // If the remote config monitor is configured, attempt to delete the provider configuration from the remote // registry, even if it does not exist locally. http://git-wip-us.apache.org/repos/asf/knox/blob/335e8733/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java ---------------------------------------------------------------------- diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java index b29fcbc..1cfac54 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java @@ -37,6 +37,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; @@ -282,13 +283,13 @@ public class TopologiesResource { @DELETE @Produces(APPLICATION_JSON) @Path(SINGLE_PROVIDERCONFIG_API_PATH) - public Response deleteProviderConfiguration(@PathParam("name") String name) { + public Response deleteProviderConfiguration(@PathParam("name") String name, @QueryParam("force") String force) { Response response; GatewayServices services = (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE); TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE); - if (ts.deleteProviderConfiguration(name)) { + if (ts.deleteProviderConfiguration(name, Boolean.valueOf(force))) { response = ok().entity("{ \"deleted\" : \"provider config " + name + "\" }").build(); } else { response = notModified().build(); http://git-wip-us.apache.org/repos/asf/knox/blob/335e8733/gateway-spi/src/main/java/org/apache/knox/gateway/services/topology/TopologyService.java ---------------------------------------------------------------------- diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/topology/TopologyService.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/topology/TopologyService.java index 3be3a4a..337754f 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/topology/TopologyService.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/topology/TopologyService.java @@ -58,6 +58,8 @@ public interface TopologyService extends Service { boolean deleteProviderConfiguration(String name); + boolean deleteProviderConfiguration(String name, boolean force); + Map<String, List<String>> getServiceTestURLs(Topology t, GatewayConfig config); } http://git-wip-us.apache.org/repos/asf/knox/blob/335e8733/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java ---------------------------------------------------------------------- diff --git a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java index 3bd0605..5461a95 100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java @@ -1470,13 +1470,12 @@ public class GatewayAdminTopologyFuncTest { } // Attempt to delete the referenced provider configs, and verify that it is NOT deleted - responseBody = given() - .auth().preemptive().basic(username, password) - .then() - .statusCode(HttpStatus.SC_NOT_MODIFIED) - .when().delete(href1).body(); - assertTrue("Provider config deletion should have been prevented.", - (new File(sharedProvidersDir, name1)).exists()); + given() + .auth().preemptive().basic(username, password) + .then() + .statusCode(HttpStatus.SC_NOT_MODIFIED) + .when().delete(href1).body(); + assertTrue("Provider config deletion should have been prevented.", (new File(sharedProvidersDir, name1)).exists()); ///////////////////////////////////////////////////////////// // Update the descriptor to reference the other provider config, such that the first one should become eligible for @@ -1543,6 +1542,124 @@ public class GatewayAdminTopologyFuncTest { } + /** + * KNOX-1331 + */ + @Test( timeout = TestUtils.LONG_TIMEOUT ) + public void testForceDeleteReferencedProviderConfiguration() throws Exception { + LOG_ENTER(); + + final String username = "admin"; + final String password = "admin-password"; + final String serviceUrl = clusterUrl + "/api/v1/providerconfig"; + final String descriptorsUrl = clusterUrl + "/api/v1/descriptors"; + + final File sharedProvidersDir = new File(config.getGatewayConfDir(), "shared-providers"); + + // Manually add two provider config files to the shared-providers directory + File providerConfigOneFile = new File(sharedProvidersDir, "force-deleteme-one-config.xml"); + FileOutputStream stream = new FileOutputStream(providerConfigOneFile); + createProviderConfiguration().toStream(stream); + stream.close(); + assertTrue(providerConfigOneFile.exists()); + + File providerConfigTwoFile = new File(sharedProvidersDir, "force-deleteme-two-config.xml"); + stream = new FileOutputStream(providerConfigTwoFile); + createProviderConfiguration().toStream(stream); + stream.close(); + assertTrue(providerConfigTwoFile.exists()); + + // Request a listing of all the provider configs + ResponseBody responseBody = given() + .auth().preemptive().basic(username, password) + .header("Accept", MediaType.APPLICATION_JSON) + .then() + .statusCode(HttpStatus.SC_OK) + .contentType(MediaType.APPLICATION_JSON) + .when().get(serviceUrl).body(); + List<String> items = responseBody.path("items"); + assertEquals(2, items.size()); + String name1 = responseBody.path("items[0].name"); + String href1 = responseBody.path("items[0].href"); + String name2 = responseBody.path("items[1].name"); + String href2 = responseBody.path("items[1].href"); + + ///////////////////////////////////////////////////////////// + // PUT a descriptor, which references one of the provider configurations, which should make that provider + // configuration ineligible for deletion. + String descriptorName = "mycluster2"; + String newDescriptorJSON = createDescriptor(descriptorName, name1, false); + given() + .auth().preemptive().basic(username, password) + .header("Content-type", MediaType.APPLICATION_JSON) + .body(newDescriptorJSON.getBytes("utf-8")) + .then() + .statusCode(HttpStatus.SC_CREATED) + .when().put(descriptorsUrl + "/" + descriptorName); + + try { // Wait for the reference relationship to be established + Thread.sleep(10000); + } catch (InterruptedException e) { + // + } + + // Attempt to delete the referenced provider configs, and verify that it is NOT deleted + given() + .auth().preemptive().basic(username, password) + .then() + .statusCode(HttpStatus.SC_NOT_MODIFIED) + .when().delete(href1).body(); + assertTrue("Provider config deletion should have been prevented.", (new File(sharedProvidersDir, name1)).exists()); + + ///////////////////////////////////////////////////////////// + // (KNOX-1331) + // Attempt to delete the referenced provider config with the force query param, and verify that it has been deleted + responseBody = given() + .auth().preemptive().basic(username, password) + .header("Accept", MediaType.APPLICATION_JSON) + .then() + .statusCode(HttpStatus.SC_OK) + .contentType(MediaType.APPLICATION_JSON) + .when().delete(href1 + "?force=true").body(); + String deletedMsg = responseBody.path("deleted"); + assertEquals("provider config " + FilenameUtils.getBaseName(name1), deletedMsg); + assertFalse((new File(sharedProvidersDir, name1)).exists()); + + ///////////////////////////////////////////////////////////// + // Update the descriptor to reference the other provider config + String updatedDescriptorJSON = createDescriptor(descriptorName, name2, false); + given() + .auth().preemptive().basic(username, password) + .header("Content-type", MediaType.APPLICATION_JSON) + .body(updatedDescriptorJSON.getBytes("utf-8")) + .then() + .statusCode(HttpStatus.SC_NO_CONTENT) + .when().put(descriptorsUrl + "/" + descriptorName); + + try { // Wait for the reference relationship to be established + Thread.sleep(10000); + } catch (InterruptedException e) { + // + } + + ///////////////////////////////////////////////////////////// + // (KNOX-1331) + // Delete the referenced provider config with the force query param, and verify that it has been deleted + responseBody = given() + .auth().preemptive().basic(username, password) + .header("Accept", MediaType.APPLICATION_JSON) + .then() + .statusCode(HttpStatus.SC_OK) + .contentType(MediaType.APPLICATION_JSON) + .when().delete(href2 + "?force=true").body(); + deletedMsg = responseBody.path("deleted"); + assertEquals("provider config " + FilenameUtils.getBaseName(name2), deletedMsg); + assertFalse((new File(sharedProvidersDir, name2)).exists()); + + LOG_EXIT(); + } + + @Test( timeout = TestUtils.LONG_TIMEOUT ) public void testDescriptorCollection() throws Exception { LOG_ENTER();
