diff --git a/docs/content/design/coordinator.md b/docs/content/design/coordinator.md index fff3b7dcfed..e959d73d33c 100644 --- a/docs/content/design/coordinator.md +++ b/docs/content/design/coordinator.md @@ -258,7 +258,8 @@ Optional Header Parameters for auditing the config change can also be specified. Disables a datasource. -* `/druid/coordinator/v1/datasources/{dataSourceName}?kill=true&interval={myISO8601Interval}>` +* `/druid/coordinator/v1/datasources/{dataSourceName}/intervals/{interval}?kill=true` +* `@Deprecated. /druid/coordinator/v1/datasources/{dataSourceName}?kill=true&interval={myISO8601Interval}` Runs a [Kill task](../ingestion/tasks.html) for a given interval and datasource. diff --git a/integration-tests/src/main/java/io/druid/testing/clients/CoordinatorResourceTestClient.java b/integration-tests/src/main/java/io/druid/testing/clients/CoordinatorResourceTestClient.java index 2147954861e..04f7bc03a29 100644 --- a/integration-tests/src/main/java/io/druid/testing/clients/CoordinatorResourceTestClient.java +++ b/integration-tests/src/main/java/io/druid/testing/clients/CoordinatorResourceTestClient.java @@ -74,7 +74,7 @@ public class CoordinatorResourceTestClient private String getLoadStatusURL() { - return String.format("%s%s", getCoordinatorURL(), "loadstatus"); + return String.format("%s%s", getCoordinatorURL(), "loadstatus"); } // return a list of the segment dates for the specified datasource @@ -136,9 +136,9 @@ public class CoordinatorResourceTestClient makeRequest( HttpMethod.DELETE, String.format( - "%sdatasources/%s?kill=%s&interval=%s", + "%sdatasources/%s/intervals/%s?kill=%s", getCoordinatorURL(), - dataSource, kill, URLEncoder.encode(interval.toString(), "UTF-8") + dataSource, interval.toString().replace("/", "_"), kill ) ); } diff --git a/server/src/main/java/io/druid/server/http/DatasourcesResource.java b/server/src/main/java/io/druid/server/http/DatasourcesResource.java index 09354ca7121..2f6dec84c6e 100644 --- a/server/src/main/java/io/druid/server/http/DatasourcesResource.java +++ b/server/src/main/java/io/druid/server/http/DatasourcesResource.java @@ -49,6 +49,7 @@ import org.joda.time.Interval; import javax.annotation.Nullable; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -167,6 +168,7 @@ public class DatasourcesResource } @DELETE + @Deprecated @Path("/{dataSourceName}") @Produces(MediaType.APPLICATION_JSON) public Response deleteDataSource( @@ -200,6 +202,37 @@ public class DatasourcesResource return Response.ok().build(); } + @DELETE + @Path("/{dataSourceName}/intervals/{interval}") + @Produces(MediaType.APPLICATION_JSON) + public Response deleteDataSourceSpecificInterval( + @PathParam("dataSourceName") final String dataSourceName, + @PathParam("interval") final String interval, + @QueryParam("kill") @DefaultValue("true") final String kill + ) + { + if (indexingServiceClient == null) { + return Response.ok(ImmutableMap.of("error", "no indexing service found")).build(); + } + final Interval theInterval = new Interval(interval.replace("_", "/")); + if (kill != null && Boolean.valueOf(kill)) { + try { + indexingServiceClient.killSegments(dataSourceName, new Interval(theInterval)); + } + catch (Exception e) { + return Response.serverError() + .entity(ImmutableMap.of( + "error", + "Exception occurred. Are you sure you have an indexing service?" + )) + .build(); + } + } else { + return Response.ok(ImmutableMap.of("error", "kill is set to false")).build(); + } + return Response.ok().build(); + } + @GET @Path("/{dataSourceName}/intervals") @Produces(MediaType.APPLICATION_JSON) diff --git a/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java b/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java index cf3a248f1f0..55c124a806b 100644 --- a/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java +++ b/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java @@ -20,11 +20,14 @@ package io.druid.server.http; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import io.druid.client.CoordinatorServerView; import io.druid.client.DruidDataSource; import io.druid.client.DruidServer; import io.druid.client.InventoryView; +import io.druid.client.indexing.IndexingServiceClient; +import io.druid.metadata.MetadataSegmentManager; import io.druid.timeline.DataSegment; import org.easymock.EasyMock; import org.joda.time.Interval; @@ -383,4 +386,42 @@ public class DatasourcesResourceTest } EasyMock.verify(inventoryView); } + + @Test + public void testDeleteDataSourceSpecificInterval() throws Exception + { + String interval = "2010-01-01_P1D"; + Interval theInterval = new Interval(interval.replace("_", "/")); + + IndexingServiceClient indexingServiceClient = EasyMock.createStrictMock(IndexingServiceClient.class); + indexingServiceClient.killSegments("datasource1", theInterval); + EasyMock.expectLastCall().once(); + EasyMock.replay(indexingServiceClient, server); + + DatasourcesResource datasourcesResource = new DatasourcesResource(inventoryView, null, indexingServiceClient); + Response response = datasourcesResource.deleteDataSourceSpecificInterval("datasource1", interval, "true"); + + Assert.assertEquals(200, response.getStatus()); + Assert.assertEquals(null, response.getEntity()); + EasyMock.verify(indexingServiceClient, server); + } + + @Test + public void testDeleteDataSourceSpecificIntervalKillFalse() throws Exception + { + String interval = "2010-01-01_P1D"; + Interval theInterval = new Interval(interval.replace("_", "/")); + + IndexingServiceClient indexingServiceClient = EasyMock.createStrictMock(IndexingServiceClient.class); + EasyMock.replay(indexingServiceClient, server); + + DatasourcesResource datasourcesResource = new DatasourcesResource(inventoryView, null, indexingServiceClient); + Response response = datasourcesResource.deleteDataSourceSpecificInterval("datasource1", interval, "false"); + + Assert.assertEquals(200, response.getStatus()); + ImmutableMap results = (ImmutableMap) response.getEntity(); + Assert.assertEquals(results, ImmutableMap.of("error", "kill is set to false")); + EasyMock.verify(indexingServiceClient, server); + } + }