mirror of https://github.com/apache/druid.git
Fix overlord api and console (#6686)
* Fix overlord APIs and console * remove getRunningTasksByDataSource * add missing path to isApplicable
This commit is contained in:
parent
624f328ea1
commit
d6539abd0a
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue