diff --git a/docs/content/design/coordinator.md b/docs/content/design/coordinator.md index a95907fa670..7bed3706bb2 100644 --- a/docs/content/design/coordinator.md +++ b/docs/content/design/coordinator.md @@ -258,7 +258,7 @@ 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>` Runs a [Kill task](../misc/tasks.html) for a given interval and datasource. 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 b24539ead95..33a5af3333e 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,63 +168,49 @@ public class DatasourcesResource } @DELETE - @Deprecated @Path("/{dataSourceName}") @Produces(MediaType.APPLICATION_JSON) public Response deleteDataSource( + @PathParam("dataSourceName") final String dataSourceName + ) + { + if (!databaseSegmentManager.removeDatasource(dataSourceName)) { + return Response.noContent().build(); + } + return Response.ok().build(); + } + + @DELETE + @Path("/{dataSourceName}/intervals/{interval}") + @Produces(MediaType.APPLICATION_JSON) + public Response deleteDataSourceSpecificInterval( @PathParam("dataSourceName") final String dataSourceName, - @QueryParam("kill") final String kill, - @QueryParam("interval") final String interval + @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(interval)); + 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?" - ) - ) + return Response.serverError() + .entity(ImmutableMap.of( + "error", + "Exception occurred. Are you sure you have an indexing service?" + )) .build(); } } else { - if (!databaseSegmentManager.removeDatasource(dataSourceName)) { - return Response.noContent().build(); - } + return Response.ok(ImmutableMap.of("error", "kill is set to false")).build(); } - 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") 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 { - if (!databaseSegmentManager.removeDatasource(dataSourceName)) { - return Response.noContent().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 91aef2ac0b7..0a29e64d69d 100644 --- a/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java +++ b/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java @@ -20,12 +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; @@ -385,21 +387,56 @@ public class DatasourcesResourceTest EasyMock.verify(inventoryView); } - @Test - public void testDeleteDataSourceSpecificInterval() throws Exception - { - String interval = "2010-01-01_P1D"; - Interval theInterval = new Interval(interval.replace("_", "/")); + @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); + 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()); - EasyMock.verify(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); + } + + @Test + public void testDeleteDataSource() throws Exception + { + MetadataSegmentManager databaseSegmentManager = EasyMock.createStrictMock(MetadataSegmentManager.class); + EasyMock.expect(databaseSegmentManager.removeDatasource("datasource1")).andReturn(true).atLeastOnce(); + EasyMock.replay(server, databaseSegmentManager); + + DatasourcesResource datasourcesResource = new DatasourcesResource(null, databaseSegmentManager, null); + Response response = datasourcesResource.deleteDataSource("datasource1"); + + Assert.assertEquals(200, response.getStatus()); + Assert.assertEquals(null,response.getEntity()); + EasyMock.verify(databaseSegmentManager, server); + } }