Fix overlord api and console (#6686)

* Fix overlord APIs and console

* remove getRunningTasksByDataSource

* add missing path to isApplicable
This commit is contained in:
Jihoon Son 2018-11-29 23:45:28 -08:00 committed by Clint Wylie
parent 624f328ea1
commit d6539abd0a
5 changed files with 17 additions and 76 deletions

View File

@ -405,7 +405,7 @@ Endpoint for submitting tasks and supervisor specs to the overlord. Returns the
Shuts down a task. Shuts down a task.
* `druid/indexer/v1/task/{dataSource}/shutdownAllTasks` * `druid/indexer/v1/datasources/{dataSource}/shutdownAllTasks`
Shuts down all tasks for a dataSource. Shuts down all tasks for a dataSource.

View File

@ -59,6 +59,7 @@ import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.logger.Logger; import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.metadata.EntryExistsException; import org.apache.druid.metadata.EntryExistsException;
import org.apache.druid.server.http.security.ConfigResourceFilter; import org.apache.druid.server.http.security.ConfigResourceFilter;
import org.apache.druid.server.http.security.DatasourceResourceFilter;
import org.apache.druid.server.http.security.StateResourceFilter; import org.apache.druid.server.http.security.StateResourceFilter;
import org.apache.druid.server.security.Access; import org.apache.druid.server.security.Access;
import org.apache.druid.server.security.Action; import org.apache.druid.server.security.Action;
@ -338,8 +339,9 @@ public class OverlordResource
} }
@POST @POST
@Path("/task/{dataSource}/shutdownAllTasks") @Path("/datasources/{dataSource}/shutdownAllTasks")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(DatasourceResourceFilter.class)
public Response shutdownTasksForDataSource(@PathParam("dataSource") final String dataSource) public Response shutdownTasksForDataSource(@PathParam("dataSource") final String dataSource)
{ {
return asLeaderWith( return asLeaderWith(
@ -1000,26 +1002,6 @@ public class OverlordResource
} }
} }
@GET
@Path("/dataSources/{dataSource}")
@Produces(MediaType.APPLICATION_JSON)
public Response getRunningTasksByDataSource(@PathParam("dataSource") String dataSource,
@Context HttpServletRequest request)
{
Optional<TaskRunner> ts = taskMaster.getTaskRunner();
if (!ts.isPresent()) {
return Response.status(Response.Status.NOT_FOUND).entity("No tasks are running").build();
}
Collection<? extends TaskRunnerWorkItem> runningTasks = ts.get().getRunningTasks();
if (runningTasks == null || runningTasks.isEmpty()) {
return Response.status(Response.Status.NOT_FOUND)
.entity("No running tasks found for the datasource : " + dataSource).build();
}
List<TaskRunnerWorkItem> taskRunnerWorkItemList = runningTasks.stream()
.filter(task -> dataSource.equals(task.getDataSource())).collect(Collectors.toList());
return Response.ok(taskRunnerWorkItemList).build();
}
private <T> Response asLeaderWith(Optional<T> x, Function<T, Response> f) private <T> Response asLeaderWith(Optional<T> x, Function<T, Response> f)
{ {
if (x.isPresent()) { if (x.isPresent()) {

View File

@ -24,7 +24,7 @@ var killTask = function(taskId) {
if(confirm('Do you really want to kill: '+taskId)) { if(confirm('Do you really want to kill: '+taskId)) {
$.ajax({ $.ajax({
type:'POST', type:'POST',
url: '/druid/indexer/v1/task/'+ taskId +'/terminate', url: '/druid/indexer/v1/task/'+ taskId +'/shutdown',
data: '' data: ''
}).done(function(data) { }).done(function(data) {
setTimeout(function() { location.reload(true) }, 750); setTimeout(function() { location.reload(true) }, 750);

View File

@ -125,11 +125,11 @@ public class OverlordResourceTest
); );
} }
public void expectAuthorizationTokenCheck() private void expectAuthorizationTokenCheck()
{ {
AuthenticationResult authenticationResult = new AuthenticationResult("druid", "druid", null, null); AuthenticationResult authenticationResult = new AuthenticationResult("druid", "druid", null, null);
EasyMock.expect(req.getAttribute(AuthConfig.DRUID_ALLOW_UNSECURED_PATH)).andReturn(null).anyTimes(); EasyMock.expect(req.getAttribute(AuthConfig.DRUID_ALLOW_UNSECURED_PATH)).andReturn(null).anyTimes();
EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED)).andReturn(null).anyTimes(); EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED)).andReturn(null).atLeastOnce();
EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT)) EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT))
.andReturn(authenticationResult) .andReturn(authenticationResult)
.anyTimes(); .anyTimes();
@ -833,7 +833,10 @@ public class OverlordResourceTest
@Test @Test
public void testGetTaskPayload() throws Exception public void testGetTaskPayload() throws Exception
{ {
expectAuthorizationTokenCheck(); // This is disabled since OverlordResource.getTaskStatus() is annotated with TaskResourceFilter which is supposed to
// set authorization token properly, but isn't called in this test.
// This should be fixed in https://github.com/apache/incubator-druid/issues/6685.
// expectAuthorizationTokenCheck();
final NoopTask task = NoopTask.create("mydatasource"); final NoopTask task = NoopTask.create("mydatasource");
EasyMock.expect(taskStorageQueryAdapter.getTask("mytask")) EasyMock.expect(taskStorageQueryAdapter.getTask("mytask"))
.andReturn(Optional.of(task)); .andReturn(Optional.of(task));
@ -861,7 +864,10 @@ public class OverlordResourceTest
@Test @Test
public void testGetTaskStatus() throws Exception public void testGetTaskStatus() throws Exception
{ {
expectAuthorizationTokenCheck(); // This is disabled since OverlordResource.getTaskStatus() is annotated with TaskResourceFilter which is supposed to
// set authorization token properly, but isn't called in this test.
// This should be fixed in https://github.com/apache/incubator-druid/issues/6685.
// expectAuthorizationTokenCheck();
final Task task = NoopTask.create("mytask", 0); final Task task = NoopTask.create("mytask", 0);
final TaskStatus status = TaskStatus.running("mytask"); final TaskStatus status = TaskStatus.running("mytask");
@ -910,54 +916,6 @@ public class OverlordResourceTest
Assert.assertEquals(new TaskStatusResponse("othertask", null), taskStatusResponse2); Assert.assertEquals(new TaskStatusResponse("othertask", null), taskStatusResponse2);
} }
@Test
public void testGetRunningTasksByDataSource()
{
List<String> tasksIds = ImmutableList.of("id_1", "id_2");
EasyMock.<Collection<? extends TaskRunnerWorkItem>>expect(taskRunner.getRunningTasks()).andReturn(
ImmutableList.of(
new MockTaskRunnerWorkItem(tasksIds.get(0), null),
new MockTaskRunnerWorkItem(tasksIds.get(1), null)));
EasyMock.expect(taskStorageQueryAdapter.getTask(tasksIds.get(0))).andReturn(
Optional.of(getTaskWithIdAndDatasource(tasksIds.get(0), "deny"))).once();
EasyMock.expect(taskStorageQueryAdapter.getTask(tasksIds.get(1))).andReturn(
Optional.of(getTaskWithIdAndDatasource(tasksIds.get(1), "allow"))).once();
EasyMock.replay(taskRunner, taskMaster, taskStorageQueryAdapter, indexerMetadataStorageAdapter, req);
List<TaskRunnerWorkItem> responseObjects = (List) overlordResource.getRunningTasksByDataSource("ds_test", req)
.getEntity();
Assert.assertEquals(2, responseObjects.size());
Assert.assertEquals(taskStorageQueryAdapter.getTask("id_1").get().getId(), responseObjects.get(0).getTaskId());
Assert.assertEquals(taskStorageQueryAdapter.getTask("id_2").get().getId(), responseObjects.get(1).getTaskId());
Assert.assertTrue("DataSource Check", "ds_test".equals(responseObjects.get(0).getDataSource()));
}
@Test
public void testGetRunningTasksByDataSourceNeg()
{
expectAuthorizationTokenCheck();
List<String> tasksIds = ImmutableList.of("id_1", "id_2");
EasyMock.<Collection<? extends TaskRunnerWorkItem>>expect(taskRunner.getRunningTasks()).andReturn(
ImmutableList.of(
new MockTaskRunnerWorkItem(tasksIds.get(0), null),
new MockTaskRunnerWorkItem(tasksIds.get(1), null)));
EasyMock.expect(taskStorageQueryAdapter.getTask(tasksIds.get(0))).andReturn(
Optional.of(getTaskWithIdAndDatasource(tasksIds.get(0), "deny"))).once();
EasyMock.expect(taskStorageQueryAdapter.getTask(tasksIds.get(1))).andReturn(
Optional.of(getTaskWithIdAndDatasource(tasksIds.get(1), "allow"))).once();
EasyMock.replay(taskRunner, taskMaster, taskStorageQueryAdapter, indexerMetadataStorageAdapter, req);
Assert.assertTrue(taskStorageQueryAdapter.getTask("id_1").isPresent());
Assert.assertTrue(taskStorageQueryAdapter.getTask("id_2").isPresent());
List<TaskRunnerWorkItem> responseObjects = (List) overlordResource.getRunningTasksByDataSource("ds_NA", req)
.getEntity();
Assert.assertEquals(0, responseObjects.size());
}
@After @After
public void tearDown() public void tearDown()
{ {

View File

@ -100,7 +100,8 @@ public class DatasourceResourceFilter extends AbstractResourceFilter
List<String> applicablePaths = ImmutableList.of( List<String> applicablePaths = ImmutableList.of(
"druid/coordinator/v1/datasources/", "druid/coordinator/v1/datasources/",
"druid/coordinator/v1/metadata/datasources/", "druid/coordinator/v1/metadata/datasources/",
"druid/v2/datasources/" "druid/v2/datasources/",
"druid/indexer/v1/datasources"
); );
for (String path : applicablePaths) { for (String path : applicablePaths) {
if (requestPath.startsWith(path) && !requestPath.equals(path)) { if (requestPath.startsWith(path) && !requestPath.equals(path)) {