From a2cd5e4e41b0aa40d046c23b6624921876d93038 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Mon, 15 Jun 2026 00:37:42 +0530 Subject: [PATCH 1/3] took dump of previous PR Signed-off-by: jaykay12 --- .../unreleased/SOLR-18248-list-tasks.yml | 8 ++ .../solr/client/api/endpoint/TasksApi.java | 47 +++++++ .../client/api/model/ActiveTaskDetails.java | 33 +++++ .../api/model/ListActiveTaskResponse.java | 25 ++++ .../client/api/model/TaskStatusResponse.java | 40 ++++++ .../handler/admin/HealthCheckHandler.java | 3 - .../solr/handler/admin/api/ActiveTask.java | 61 +++++++++ .../solr/handler/admin/api/GetTaskStatus.java | 51 +++++++ .../handler/admin/api/ListActiveTasks.java | 63 +++++++++ .../handler/admin/api/ListActiveTasksAPI.java | 48 ------- .../component/ActiveTasksListComponent.java | 128 ------------------ .../component/ActiveTasksListHandler.java | 58 ++++---- .../component/TaskManagementHandler.java | 3 - .../handler/admin/api/GetTaskStatusTest.java | 75 ++++++++++ .../admin/api/ListActiveTasksTest.java | 85 ++++++++++++ .../solr/search/TestTaskManagement.java | 40 ++++++ 16 files changed, 558 insertions(+), 210 deletions(-) create mode 100644 changelog/unreleased/SOLR-18248-list-tasks.yml create mode 100644 solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java create mode 100644 solr/api/src/java/org/apache/solr/client/api/model/ActiveTaskDetails.java create mode 100644 solr/api/src/java/org/apache/solr/client/api/model/ListActiveTaskResponse.java create mode 100644 solr/api/src/java/org/apache/solr/client/api/model/TaskStatusResponse.java create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java delete mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasksAPI.java delete mode 100644 solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListComponent.java create mode 100644 solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java create mode 100644 solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java diff --git a/changelog/unreleased/SOLR-18248-list-tasks.yml b/changelog/unreleased/SOLR-18248-list-tasks.yml new file mode 100644 index 000000000000..3dc9716c12c5 --- /dev/null +++ b/changelog/unreleased/SOLR-18248-list-tasks.yml @@ -0,0 +1,8 @@ +title: Migrated ListTasks API & TaskStatus API from homegrown @EndPoint to JAX-RS +type: added +authors: + - name: Jalaz Kumar + - name: Eric Pugh +links: + - name: SOLR-18248 + url: https://issues.apache.org/jira/browse/SOLR-18248 diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java new file mode 100644 index 000000000000..98061204eebf --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.api.endpoint; + +import static org.apache.solr.client.api.util.Constants.INDEX_PATH_PREFIX; + +import io.swagger.v3.oas.annotations.Operation; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import org.apache.solr.client.api.model.ListActiveTaskResponse; +import org.apache.solr.client.api.model.TaskStatusResponse; +import org.apache.solr.client.api.util.StoreApiParameters; + +@Path(INDEX_PATH_PREFIX + "/tasks") +public interface TasksApi { + + @GET + @StoreApiParameters + @Operation( + summary = "Lists all the currently running tasks", + tags = {"tasks"}) + ListActiveTaskResponse listAllActiveTasks() throws Exception; + + @GET + @Path("/{taskUUID}") + @StoreApiParameters + @Operation( + summary = "Status of a specific taskUUID passed as pathParam", + tags = {"tasks"}) + TaskStatusResponse getTaskStatus(@PathParam("taskUUID") String taskUUID) throws Exception; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/model/ActiveTaskDetails.java b/solr/api/src/java/org/apache/solr/client/api/model/ActiveTaskDetails.java new file mode 100644 index 000000000000..8781623c5c95 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/ActiveTaskDetails.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ActiveTaskDetails { + + public ActiveTaskDetails() {} + + public ActiveTaskDetails(String taskID, String taskQuery) { + this.taskID = taskID; + this.taskQuery = taskQuery; + } + + @JsonProperty public String taskID; + @JsonProperty public String taskQuery; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/model/ListActiveTaskResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/ListActiveTaskResponse.java new file mode 100644 index 000000000000..f74ec9096077 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/ListActiveTaskResponse.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +public class ListActiveTaskResponse extends SolrJerseyResponse { + @JsonProperty public List taskList; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/model/TaskStatusResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/TaskStatusResponse.java new file mode 100644 index 000000000000..16a0f89c53bf --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/TaskStatusResponse.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class TaskStatusResponse extends SolrJerseyResponse { + + public enum TaskStatus { + ACTIVE("active"), + INACTIVE("inactive"); + + private final String value; + + TaskStatus(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + } + + @JsonProperty public TaskStatus taskStatus; +} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/HealthCheckHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/HealthCheckHandler.java index 1dab5d1d9778..8c73ac11af3b 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/HealthCheckHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/HealthCheckHandler.java @@ -59,9 +59,6 @@ * specify the acceptable generation lag follower should be with respect to its leader using the * maxGenerationLag=<max_generation_lag> request parameter. If * maxGenerationLag is not provided then health check would simply return OK. - * - *

All health-check logic lives in the v2 {@link NodeHealth}; this handler is a thin v1 bridge - * that extracts request parameters and delegates. */ public class HealthCheckHandler extends RequestHandlerBase { diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java new file mode 100644 index 000000000000..3b02b6eba3b6 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java @@ -0,0 +1,61 @@ +package org.apache.solr.handler.admin.api; + +import jakarta.inject.Inject; +import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.endpoint.TasksApi; +import org.apache.solr.client.api.model.ActiveTaskDetails; +import org.apache.solr.client.api.model.ListActiveTaskResponse; +import org.apache.solr.client.api.model.TaskStatusResponse; +import org.apache.solr.jersey.PermissionName; +import org.apache.solr.request.SolrQueryRequest; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static org.apache.solr.security.PermissionNameProvider.Name.READ_PERM; + +public class ActiveTask extends JerseyResource implements TasksApi { + + private final SolrQueryRequest solrQueryRequest; + + @Inject + public ActiveTask(SolrQueryRequest solrQueryRequest) { + this.solrQueryRequest = solrQueryRequest; + } + + @Override + @PermissionName(READ_PERM) + public ListActiveTaskResponse listAllActiveTasks() throws Exception { + final ListActiveTaskResponse response = instantiateJerseyResponse(ListActiveTaskResponse.class); + response.taskList = extractActiveTaskLists(); + return response; + } + + @Override + @PermissionName(READ_PERM) + public TaskStatusResponse getTaskStatus(String taskID) throws Exception { + final TaskStatusResponse response = instantiateJerseyResponse(TaskStatusResponse.class); + + boolean isTaskActive = + solrQueryRequest.getCore().getCancellableQueryTracker().isQueryIdActive(taskID); + + response.taskStatus = (isTaskActive) ? TaskStatusResponse.TaskStatus.ACTIVE : TaskStatusResponse.TaskStatus.INACTIVE; + + return response; + } + + private List extractActiveTaskLists() { + Iterator> iterator = + solrQueryRequest.getCore().getCancellableQueryTracker().getActiveQueriesGenerated(); + + List activeTaskDetails = new ArrayList<>(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + activeTaskDetails.add(new ActiveTaskDetails(entry.getKey(), entry.getValue())); + } + + return activeTaskDetails; + } + +} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java new file mode 100644 index 000000000000..4819fd7f95c5 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.handler.admin.api; + +import static org.apache.solr.client.api.model.TaskStatusResponse.TaskStatus; +import static org.apache.solr.security.PermissionNameProvider.Name.READ_PERM; + +import jakarta.inject.Inject; +import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.endpoint.TasksApi; +import org.apache.solr.client.api.model.TaskStatusResponse; +import org.apache.solr.jersey.PermissionName; +import org.apache.solr.request.SolrQueryRequest; + +//public class GetTaskStatus extends JerseyResource implements TasksApi.Status { +// +// private final SolrQueryRequest solrQueryRequest; +// +// @Inject +// public GetTaskStatus(SolrQueryRequest solrQueryRequest) { +// this.solrQueryRequest = solrQueryRequest; +// } +// +// @Override +// @PermissionName(READ_PERM) +// public TaskStatusResponse getTaskStatus(String taskID) throws Exception { +// final TaskStatusResponse response = instantiateJerseyResponse(TaskStatusResponse.class); +// +// boolean isTaskActive = +// solrQueryRequest.getCore().getCancellableQueryTracker().isQueryIdActive(taskID); +// +// response.taskStatus = (isTaskActive) ? TaskStatus.ACTIVE : TaskStatus.INACTIVE; +// +// return response; +// } +//} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java new file mode 100644 index 000000000000..ed65a644e056 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.handler.admin.api; + +import static org.apache.solr.security.PermissionNameProvider.Name.READ_PERM; + +import jakarta.inject.Inject; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.endpoint.TasksApi; +import org.apache.solr.client.api.model.ActiveTaskDetails; +import org.apache.solr.client.api.model.ListActiveTaskResponse; +import org.apache.solr.jersey.PermissionName; +import org.apache.solr.request.SolrQueryRequest; + +//public class ListActiveTasks extends JerseyResource implements TasksApi.List { + +// private final SolrQueryRequest solrQueryRequest; +// +// @Inject +// public ListActiveTasks(SolrQueryRequest solrQueryRequest) { +// this.solrQueryRequest = solrQueryRequest; +// } +// +// @Override +// @PermissionName(READ_PERM) +// public ListActiveTaskResponse listAllActiveTasks() throws Exception { +// final ListActiveTaskResponse response = instantiateJerseyResponse(ListActiveTaskResponse.class); +// response.taskList = extractActiveTaskLists(); +// return response; +// } +// +// private List extractActiveTaskLists() { +// Iterator> iterator = +// solrQueryRequest.getCore().getCancellableQueryTracker().getActiveQueriesGenerated(); +// +// List activeTaskDetails = new ArrayList<>(); +// while (iterator.hasNext()) { +// Map.Entry entry = iterator.next(); +// activeTaskDetails.add(new ActiveTaskDetails(entry.getKey(), entry.getValue())); +// } +// +// return activeTaskDetails; +// } +//} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasksAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasksAPI.java deleted file mode 100644 index fba3d9d26f3f..000000000000 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasksAPI.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.solr.handler.admin.api; - -import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET; - -import org.apache.solr.api.EndPoint; -import org.apache.solr.handler.component.ActiveTasksListHandler; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.security.PermissionNameProvider; - -/** - * V2 API for listing any currently running "tasks". - * - *

This API (GET /v2/collections/collectionName/tasks/list) is analogous to the v1 - * /solr/collectionName/tasks/list API. - */ -public class ListActiveTasksAPI { - private final ActiveTasksListHandler listTaskHandler; - - public ListActiveTasksAPI(ActiveTasksListHandler listTaskHandler) { - this.listTaskHandler = listTaskHandler; - } - - @EndPoint( - path = {"/tasks/list"}, - method = GET, - permission = PermissionNameProvider.Name.READ_PERM) - public void listActiveTasks(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - listTaskHandler.handleRequestBody(req, rsp); - } -} diff --git a/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListComponent.java b/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListComponent.java deleted file mode 100644 index ce8a31335c2f..000000000000 --- a/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListComponent.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.solr.handler.component; - -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import org.apache.solr.common.MapWriter; -import org.apache.solr.common.util.NamedList; - -/** List the active tasks that can be cancelled */ -public class ActiveTasksListComponent extends SearchComponent { - public static final String COMPONENT_NAME = "activetaskslist"; - - private boolean shouldProcess; - - @Override - public void prepare(ResponseBuilder rb) throws IOException { - if (rb.isTaskListRequest()) { - shouldProcess = true; - } - } - - @Override - public void process(ResponseBuilder rb) { - if (!shouldProcess) { - return; - } - - if (rb.getTaskStatusCheckUUID() != null) { - boolean isActiveOnThisShard = - rb.req - .getCore() - .getCancellableQueryTracker() - .isQueryIdActive(rb.getTaskStatusCheckUUID()); - - rb.rsp.add("taskStatus", isActiveOnThisShard); - return; - } - - rb.rsp.add( - "taskList", - (MapWriter) - ew -> { - Iterator> iterator = - rb.req.getCore().getCancellableQueryTracker().getActiveQueriesGenerated(); - - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - ew.put(entry.getKey(), entry.getValue()); - } - }); - } - - @Override - @SuppressWarnings("unchecked") - public void handleResponses(ResponseBuilder rb, ShardRequest sreq) { - if (!shouldProcess) { - return; - } - - NamedList resultList = new NamedList<>(); - - for (ShardResponse r : sreq.responses) { - - if (rb.getTaskStatusCheckUUID() != null) { - boolean isTaskActiveOnShard = r.getSolrResponse().getResponse().getBooleanArg("taskStatus"); - - if (isTaskActiveOnShard) { - rb.rsp - .getValues() - .add("taskStatus", "id:" + rb.getTaskStatusCheckUUID() + ", status: active"); - return; - } else { - continue; - } - } - - LinkedHashMap result = - (LinkedHashMap) r.getSolrResponse().getResponse().get("taskList"); - - Iterator> iterator = result.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - - resultList.add(entry.getKey(), entry.getValue()); - } - } - - if (rb.getTaskStatusCheckUUID() != null) { - // We got here with the specific taskID check being specified -- this means that the taskID - // was not found in active tasks on any shard - rb.rsp - .getValues() - .add("taskStatus", "id:" + rb.getTaskStatusCheckUUID() + ", status: inactive"); - return; - } - - rb.rsp.getValues().add("taskList", resultList); - } - - @Override - public String getDescription() { - return "Responsible for listing all active cancellable tasks and also supports checking the status of " - + "a particular task"; - } - - @Override - public Category getCategory() { - return Category.OTHER; - } -} diff --git a/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java b/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java index f1ce12cd9378..77fe7bb59d3a 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java @@ -19,49 +19,54 @@ import static org.apache.solr.common.params.CommonParams.TASK_CHECK_UUID; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import org.apache.solr.api.AnnotatedApi; import org.apache.solr.api.Api; -import org.apache.solr.handler.admin.api.ListActiveTasksAPI; +import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.ActiveTaskDetails; +import org.apache.solr.client.api.model.TaskStatusResponse; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.handler.admin.api.ActiveTask; +//import org.apache.solr.handler.admin.api.GetTaskStatus; +//import org.apache.solr.handler.admin.api.ListActiveTasks; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestHandler; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.security.AuthorizationContext; import org.apache.solr.security.PermissionNameProvider; -/** Handles request for listing all active cancellable tasks */ +/** Handles request for listing all active cancellable tasks and get status check of any taskId. */ public class ActiveTasksListHandler extends TaskManagementHandler { // This can be a parent level member but we keep it here to allow future handlers to have // a custom list of components - private List components; @Override public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - Map extraParams = null; - ResponseBuilder rb = buildResponseBuilder(req, rsp, getComponentsList()); - - rb.setIsTaskListRequest(true); - String taskStatusCheckUUID = req.getParams().get(TASK_CHECK_UUID, null); if (taskStatusCheckUUID != null) { - if (rb.isDistrib) { - extraParams = new HashMap<>(); - - extraParams.put(TASK_CHECK_UUID, taskStatusCheckUUID); + TaskStatusResponse taskStatusResponse = + new ActiveTask(req).getTaskStatus(taskStatusCheckUUID); + String taskStatus = + "id: " + taskStatusCheckUUID + ", status: " + taskStatusResponse.taskStatus.getValue(); + rsp.add("taskStatus", taskStatus); + + } else { + NamedList tasks = new NamedList<>(); + List taskList = new ActiveTask(req).listAllActiveTasks().taskList; + if (taskList != null) { + for (ActiveTaskDetails task : taskList) { + tasks.add(task.taskID, task.taskQuery); + } } - - rb.setTaskStatusCheckUUID(taskStatusCheckUUID); + rsp.add("taskList", tasks); } - - processRequest(req, rb, extraParams); } + // ////////////////////// SolrInfoMBeans methods ////////////////////// + @Override public String getDescription() { - return "activetaskslist"; + return "Active Tasks List"; } @Override @@ -79,7 +84,6 @@ public SolrRequestHandler getSubHandler(String path) { if (path.startsWith("/tasks/list")) { return this; } - return null; } @@ -90,14 +94,12 @@ public Boolean registerV2() { @Override public Collection getApis() { - return AnnotatedApi.getApis(new ListActiveTasksAPI(this)); + return List.of(); } - private List getComponentsList() { - if (components == null) { - components = buildComponentsList(); - } - - return components; + @Override + public Collection> getJerseyResources() { +// return List.of(ListActiveTasks.class, GetTaskStatus.class); + return List.of(ActiveTask.class); } } diff --git a/solr/core/src/java/org/apache/solr/handler/component/TaskManagementHandler.java b/solr/core/src/java/org/apache/solr/handler/component/TaskManagementHandler.java index afb7a05c5868..3e9c5ec21160 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/TaskManagementHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/TaskManagementHandler.java @@ -115,9 +115,6 @@ public static List buildComponentsList() { QueryCancellationComponent component = new QueryCancellationComponent(); components.add(component); - ActiveTasksListComponent activeTasksListComponent = new ActiveTasksListComponent(); - components.add(activeTasksListComponent); - return components; } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java new file mode 100644 index 000000000000..9ea347190b1e --- /dev/null +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.handler.admin.api; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.api.model.TaskStatusResponse; +import org.apache.solr.core.CancellableQueryTracker; +import org.apache.solr.core.SolrCore; +import org.apache.solr.request.SolrQueryRequest; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class GetTaskStatusTest extends SolrTestCaseJ4 { + +// private SolrQueryRequest mockQueryRequest; +// private SolrCore solrCore; +// private CancellableQueryTracker cancellableQueryTracker; +// +// private GetTaskStatus.java getTaskStatus; +// +// @BeforeClass +// public static void ensureWorkingMockito() { +// assumeWorkingMockito(); +// } +// +// @Override +// @Before +// public void setUp() throws Exception { +// super.setUp(); +// +// mockQueryRequest = mock(SolrQueryRequest.class); +// solrCore = mock(SolrCore.class); +// cancellableQueryTracker = mock(CancellableQueryTracker.class); +// +// getTaskStatus = new GetTaskStatus.java(mockQueryRequest); +// } +// +// @Test +// public void testGetTaskStatus() throws Exception { +// +// when(mockQueryRequest.getCore()).thenReturn(solrCore); +// when(solrCore.getCancellableQueryTracker()).thenReturn(cancellableQueryTracker); +// when(cancellableQueryTracker.isQueryIdActive("taskID_running")).thenReturn(true); +// when(cancellableQueryTracker.isQueryIdActive("taskID_stopped")).thenReturn(false); +// +// TaskStatusResponse taskStatusResponse; +// +// taskStatusResponse = getTaskStatus.getTaskStatus("taskID_running"); +// assertEquals(TaskStatusResponse.TaskStatus.ACTIVE, taskStatusResponse.taskStatus); +// assertNull(taskStatusResponse.error); +// +// taskStatusResponse = getTaskStatus.getTaskStatus("taskID_stopped"); +// assertEquals(TaskStatusResponse.TaskStatus.INACTIVE, taskStatusResponse.taskStatus); +// assertNull(taskStatusResponse.error); +// } +} diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java new file mode 100644 index 000000000000..f7c89e174a81 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.handler.admin.api; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.api.model.ListActiveTaskResponse; +import org.apache.solr.core.CancellableQueryTracker; +import org.apache.solr.core.SolrCore; +import org.apache.solr.request.SolrQueryRequest; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ListActiveTasksTest extends SolrTestCaseJ4 { + +// private SolrQueryRequest mockQueryRequest; +// private SolrCore solrCore; +// private CancellableQueryTracker cancellableQueryTracker; +// +// private ListActiveTasks listActiveTasks; +// +// @BeforeClass +// public static void ensureWorkingMockito() { +// assumeWorkingMockito(); +// } +// +// @Override +// @Before +// public void setUp() throws Exception { +// super.setUp(); +// +// mockQueryRequest = mock(SolrQueryRequest.class); +// solrCore = mock(SolrCore.class); +// cancellableQueryTracker = mock(CancellableQueryTracker.class); +// +// listActiveTasks = new ListActiveTasks(mockQueryRequest); +// } +// +// @Test +// public void testGetActiveTasks() throws Exception { +// +// Map myMap = new LinkedHashMap<>(); +// myMap.put("taskID1", "/search?q=h&gf=text-1"); +// myMap.put("taskID2", "/search?q=h&gf=text-2"); +// Iterator> mockIterator = myMap.entrySet().iterator(); +// +// when(mockQueryRequest.getCore()).thenReturn(solrCore); +// when(solrCore.getCancellableQueryTracker()).thenReturn(cancellableQueryTracker); +// when(cancellableQueryTracker.getActiveQueriesGenerated()).thenReturn(mockIterator); +// +// ListActiveTaskResponse response = listActiveTasks.listAllActiveTasks(); +// assertNotNull(response.taskList); +// +// assertEquals(2, response.taskList.size()); +// +// assertEquals("taskID1", response.taskList.get(0).taskID); +// assertEquals("/search?q=h&gf=text-1", response.taskList.get(0).taskQuery); +// +// assertEquals("taskID2", response.taskList.get(1).taskID); +// assertEquals("/search?q=h&gf=text-2", response.taskList.get(1).taskQuery); +// +// assertNull(response.error); +// } +} diff --git a/solr/core/src/test/org/apache/solr/search/TestTaskManagement.java b/solr/core/src/test/org/apache/solr/search/TestTaskManagement.java index 13c98d87aceb..ed6a0bb121c0 100644 --- a/solr/core/src/test/org/apache/solr/search/TestTaskManagement.java +++ b/solr/core/src/test/org/apache/solr/search/TestTaskManagement.java @@ -213,6 +213,46 @@ public void testCheckSpecificQueryStatus() throws Exception { assertTrue(result.contains("inactive")); } + @Test + public void testCheckSpecificQueryStatus_Active() throws Exception { + for (int i = 0; i < 10; i++) { + executeQueryAsync(Integer.toString(i)); + } + + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("taskUUID", "5"); + + var request = + new GenericSolrRequest( + SolrRequest.METHOD.GET, "/tasks/list", SolrRequest.SolrRequestType.ADMIN, params) + .setRequiresCollection(true); + NamedList queryResponse = cluster.getSolrClient(COLLECTION_NAME).request(request); + + String result = (String) queryResponse.get("taskStatus"); + + assertTrue(result.contains("active")); + } + + @Test + public void testCheckSpecificQueryStatus_Inactive() throws Exception { + for (int i = 0; i < 10; i++) { + executeQueryAsync(Integer.toString(i)); + } + + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("taskUUID", "15"); + + var request = + new GenericSolrRequest( + SolrRequest.METHOD.GET, "/tasks/list", SolrRequest.SolrRequestType.ADMIN, params) + .setRequiresCollection(true); + NamedList queryResponse = cluster.getSolrClient(COLLECTION_NAME).request(request); + + String result = (String) queryResponse.get("taskStatus"); + + assertTrue(result.contains("inactive")); + } + private CompletableFuture cancelQuery( final String queryID, Set cancelledQueryIdsSet, Set notFoundQueryIdSet) { return CompletableFuture.runAsync( From bfc4aa5bca7c05b4929ad0900ae494feadb61eae Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Fri, 19 Jun 2026 01:07:01 +0530 Subject: [PATCH 2/3] refactored code bau --- .../unreleased/SOLR-18248-list-tasks.yml | 5 +- .../solr/client/api/endpoint/TasksApi.java | 31 +++--- .../solr/handler/admin/api/ActiveTask.java | 61 ------------ .../solr/handler/admin/api/GetTaskStatus.java | 44 ++++----- .../handler/admin/api/ListActiveTasks.java | 60 ++++++------ .../component/ActiveTasksListHandler.java | 19 ++-- .../handler/admin/api/GetTaskStatusTest.java | 82 ++++++++-------- .../admin/api/ListActiveTasksTest.java | 96 +++++++++---------- 8 files changed, 170 insertions(+), 228 deletions(-) delete mode 100644 solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java diff --git a/changelog/unreleased/SOLR-18248-list-tasks.yml b/changelog/unreleased/SOLR-18248-list-tasks.yml index 3dc9716c12c5..bfbf28648ca1 100644 --- a/changelog/unreleased/SOLR-18248-list-tasks.yml +++ b/changelog/unreleased/SOLR-18248-list-tasks.yml @@ -1,8 +1,7 @@ -title: Migrated ListTasks API & TaskStatus API from homegrown @EndPoint to JAX-RS -type: added +title: Refactor Tasks API to use Nested Interfaces +type: updated authors: - name: Jalaz Kumar - - name: Eric Pugh links: - name: SOLR-18248 url: https://issues.apache.org/jira/browse/SOLR-18248 diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java index 98061204eebf..ff2762dbf5c4 100644 --- a/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/TasksApi.java @@ -30,18 +30,23 @@ @Path(INDEX_PATH_PREFIX + "/tasks") public interface TasksApi { - @GET - @StoreApiParameters - @Operation( - summary = "Lists all the currently running tasks", - tags = {"tasks"}) - ListActiveTaskResponse listAllActiveTasks() throws Exception; + @Path("") + interface List { + @GET + @StoreApiParameters + @Operation( + summary = "Lists all the active tasks.", + tags = {"tasks"}) + ListActiveTaskResponse listAllActiveTasks() throws Exception; + } - @GET - @Path("/{taskUUID}") - @StoreApiParameters - @Operation( - summary = "Status of a specific taskUUID passed as pathParam", - tags = {"tasks"}) - TaskStatusResponse getTaskStatus(@PathParam("taskUUID") String taskUUID) throws Exception; + @Path("{taskID}") + interface Status { + @GET + @StoreApiParameters + @Operation( + summary = "Status of a specific task.", + tags = {"tasks"}) + TaskStatusResponse getTaskStatus(@PathParam("taskID") String taskID) throws Exception; + } } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java deleted file mode 100644 index 3b02b6eba3b6..000000000000 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ActiveTask.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.apache.solr.handler.admin.api; - -import jakarta.inject.Inject; -import org.apache.solr.api.JerseyResource; -import org.apache.solr.client.api.endpoint.TasksApi; -import org.apache.solr.client.api.model.ActiveTaskDetails; -import org.apache.solr.client.api.model.ListActiveTaskResponse; -import org.apache.solr.client.api.model.TaskStatusResponse; -import org.apache.solr.jersey.PermissionName; -import org.apache.solr.request.SolrQueryRequest; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import static org.apache.solr.security.PermissionNameProvider.Name.READ_PERM; - -public class ActiveTask extends JerseyResource implements TasksApi { - - private final SolrQueryRequest solrQueryRequest; - - @Inject - public ActiveTask(SolrQueryRequest solrQueryRequest) { - this.solrQueryRequest = solrQueryRequest; - } - - @Override - @PermissionName(READ_PERM) - public ListActiveTaskResponse listAllActiveTasks() throws Exception { - final ListActiveTaskResponse response = instantiateJerseyResponse(ListActiveTaskResponse.class); - response.taskList = extractActiveTaskLists(); - return response; - } - - @Override - @PermissionName(READ_PERM) - public TaskStatusResponse getTaskStatus(String taskID) throws Exception { - final TaskStatusResponse response = instantiateJerseyResponse(TaskStatusResponse.class); - - boolean isTaskActive = - solrQueryRequest.getCore().getCancellableQueryTracker().isQueryIdActive(taskID); - - response.taskStatus = (isTaskActive) ? TaskStatusResponse.TaskStatus.ACTIVE : TaskStatusResponse.TaskStatus.INACTIVE; - - return response; - } - - private List extractActiveTaskLists() { - Iterator> iterator = - solrQueryRequest.getCore().getCancellableQueryTracker().getActiveQueriesGenerated(); - - List activeTaskDetails = new ArrayList<>(); - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - activeTaskDetails.add(new ActiveTaskDetails(entry.getKey(), entry.getValue())); - } - - return activeTaskDetails; - } - -} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java index 4819fd7f95c5..95ca04837b9d 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetTaskStatus.java @@ -27,25 +27,25 @@ import org.apache.solr.jersey.PermissionName; import org.apache.solr.request.SolrQueryRequest; -//public class GetTaskStatus extends JerseyResource implements TasksApi.Status { -// -// private final SolrQueryRequest solrQueryRequest; -// -// @Inject -// public GetTaskStatus(SolrQueryRequest solrQueryRequest) { -// this.solrQueryRequest = solrQueryRequest; -// } -// -// @Override -// @PermissionName(READ_PERM) -// public TaskStatusResponse getTaskStatus(String taskID) throws Exception { -// final TaskStatusResponse response = instantiateJerseyResponse(TaskStatusResponse.class); -// -// boolean isTaskActive = -// solrQueryRequest.getCore().getCancellableQueryTracker().isQueryIdActive(taskID); -// -// response.taskStatus = (isTaskActive) ? TaskStatus.ACTIVE : TaskStatus.INACTIVE; -// -// return response; -// } -//} +public class GetTaskStatus extends JerseyResource implements TasksApi.Status { + + private final SolrQueryRequest solrQueryRequest; + + @Inject + public GetTaskStatus(SolrQueryRequest solrQueryRequest) { + this.solrQueryRequest = solrQueryRequest; + } + + @Override + @PermissionName(READ_PERM) + public TaskStatusResponse getTaskStatus(String taskID) throws Exception { + final TaskStatusResponse response = instantiateJerseyResponse(TaskStatusResponse.class); + + boolean isTaskActive = + solrQueryRequest.getCore().getCancellableQueryTracker().isQueryIdActive(taskID); + + response.taskStatus = (isTaskActive) ? TaskStatus.ACTIVE : TaskStatus.INACTIVE; + + return response; + } +} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java index ed65a644e056..56c4a1ba8a3f 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ListActiveTasks.java @@ -31,33 +31,33 @@ import org.apache.solr.jersey.PermissionName; import org.apache.solr.request.SolrQueryRequest; -//public class ListActiveTasks extends JerseyResource implements TasksApi.List { - -// private final SolrQueryRequest solrQueryRequest; -// -// @Inject -// public ListActiveTasks(SolrQueryRequest solrQueryRequest) { -// this.solrQueryRequest = solrQueryRequest; -// } -// -// @Override -// @PermissionName(READ_PERM) -// public ListActiveTaskResponse listAllActiveTasks() throws Exception { -// final ListActiveTaskResponse response = instantiateJerseyResponse(ListActiveTaskResponse.class); -// response.taskList = extractActiveTaskLists(); -// return response; -// } -// -// private List extractActiveTaskLists() { -// Iterator> iterator = -// solrQueryRequest.getCore().getCancellableQueryTracker().getActiveQueriesGenerated(); -// -// List activeTaskDetails = new ArrayList<>(); -// while (iterator.hasNext()) { -// Map.Entry entry = iterator.next(); -// activeTaskDetails.add(new ActiveTaskDetails(entry.getKey(), entry.getValue())); -// } -// -// return activeTaskDetails; -// } -//} +public class ListActiveTasks extends JerseyResource implements TasksApi.List { + + private final SolrQueryRequest solrQueryRequest; + + @Inject + public ListActiveTasks(SolrQueryRequest solrQueryRequest) { + this.solrQueryRequest = solrQueryRequest; + } + + @Override + @PermissionName(READ_PERM) + public ListActiveTaskResponse listAllActiveTasks() throws Exception { + final ListActiveTaskResponse response = instantiateJerseyResponse(ListActiveTaskResponse.class); + response.taskList = extractActiveTaskLists(); + return response; + } + + private List extractActiveTaskLists() { + Iterator> iterator = + solrQueryRequest.getCore().getCancellableQueryTracker().getActiveQueriesGenerated(); + + List activeTaskDetails = new ArrayList<>(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + activeTaskDetails.add(new ActiveTaskDetails(entry.getKey(), entry.getValue())); + } + + return activeTaskDetails; + } +} diff --git a/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java b/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java index 77fe7bb59d3a..c34bd5cbcbd1 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/ActiveTasksListHandler.java @@ -16,6 +16,7 @@ */ package org.apache.solr.handler.component; +import static org.apache.solr.client.api.model.TaskStatusResponse.TaskStatus.ACTIVE; import static org.apache.solr.common.params.CommonParams.TASK_CHECK_UUID; import java.util.Collection; @@ -25,9 +26,9 @@ import org.apache.solr.client.api.model.ActiveTaskDetails; import org.apache.solr.client.api.model.TaskStatusResponse; import org.apache.solr.common.util.NamedList; -import org.apache.solr.handler.admin.api.ActiveTask; -//import org.apache.solr.handler.admin.api.GetTaskStatus; -//import org.apache.solr.handler.admin.api.ListActiveTasks; +import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.handler.admin.api.GetTaskStatus; +import org.apache.solr.handler.admin.api.ListActiveTasks; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestHandler; import org.apache.solr.response.SolrQueryResponse; @@ -45,14 +46,13 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw if (taskStatusCheckUUID != null) { TaskStatusResponse taskStatusResponse = - new ActiveTask(req).getTaskStatus(taskStatusCheckUUID); - String taskStatus = - "id: " + taskStatusCheckUUID + ", status: " + taskStatusResponse.taskStatus.getValue(); + new GetTaskStatus(req).getTaskStatus(taskStatusCheckUUID); + boolean taskStatus = taskStatusResponse.taskStatus.equals(ACTIVE); rsp.add("taskStatus", taskStatus); } else { - NamedList tasks = new NamedList<>(); - List taskList = new ActiveTask(req).listAllActiveTasks().taskList; + NamedList tasks = new SimpleOrderedMap<>(); + List taskList = new ListActiveTasks(req).listAllActiveTasks().taskList; if (taskList != null) { for (ActiveTaskDetails task : taskList) { tasks.add(task.taskID, task.taskQuery); @@ -99,7 +99,6 @@ public Collection getApis() { @Override public Collection> getJerseyResources() { -// return List.of(ListActiveTasks.class, GetTaskStatus.class); - return List.of(ActiveTask.class); + return List.of(ListActiveTasks.class, GetTaskStatus.class); } } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java index 9ea347190b1e..d824d6438e22 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/GetTaskStatusTest.java @@ -31,45 +31,45 @@ public class GetTaskStatusTest extends SolrTestCaseJ4 { -// private SolrQueryRequest mockQueryRequest; -// private SolrCore solrCore; -// private CancellableQueryTracker cancellableQueryTracker; -// -// private GetTaskStatus.java getTaskStatus; -// -// @BeforeClass -// public static void ensureWorkingMockito() { -// assumeWorkingMockito(); -// } -// -// @Override -// @Before -// public void setUp() throws Exception { -// super.setUp(); -// -// mockQueryRequest = mock(SolrQueryRequest.class); -// solrCore = mock(SolrCore.class); -// cancellableQueryTracker = mock(CancellableQueryTracker.class); -// -// getTaskStatus = new GetTaskStatus.java(mockQueryRequest); -// } -// -// @Test -// public void testGetTaskStatus() throws Exception { -// -// when(mockQueryRequest.getCore()).thenReturn(solrCore); -// when(solrCore.getCancellableQueryTracker()).thenReturn(cancellableQueryTracker); -// when(cancellableQueryTracker.isQueryIdActive("taskID_running")).thenReturn(true); -// when(cancellableQueryTracker.isQueryIdActive("taskID_stopped")).thenReturn(false); -// -// TaskStatusResponse taskStatusResponse; -// -// taskStatusResponse = getTaskStatus.getTaskStatus("taskID_running"); -// assertEquals(TaskStatusResponse.TaskStatus.ACTIVE, taskStatusResponse.taskStatus); -// assertNull(taskStatusResponse.error); -// -// taskStatusResponse = getTaskStatus.getTaskStatus("taskID_stopped"); -// assertEquals(TaskStatusResponse.TaskStatus.INACTIVE, taskStatusResponse.taskStatus); -// assertNull(taskStatusResponse.error); -// } + private SolrQueryRequest mockQueryRequest; + private SolrCore solrCore; + private CancellableQueryTracker cancellableQueryTracker; + + private GetTaskStatus getTaskStatus; + + @BeforeClass + public static void ensureWorkingMockito() { + assumeWorkingMockito(); + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + + mockQueryRequest = mock(SolrQueryRequest.class); + solrCore = mock(SolrCore.class); + cancellableQueryTracker = mock(CancellableQueryTracker.class); + + getTaskStatus = new GetTaskStatus(mockQueryRequest); + } + + @Test + public void testGetTaskStatus() throws Exception { + + when(mockQueryRequest.getCore()).thenReturn(solrCore); + when(solrCore.getCancellableQueryTracker()).thenReturn(cancellableQueryTracker); + when(cancellableQueryTracker.isQueryIdActive("taskID_running")).thenReturn(true); + when(cancellableQueryTracker.isQueryIdActive("taskID_stopped")).thenReturn(false); + + TaskStatusResponse taskStatusResponse; + + taskStatusResponse = getTaskStatus.getTaskStatus("taskID_running"); + assertEquals(TaskStatusResponse.TaskStatus.ACTIVE, taskStatusResponse.taskStatus); + assertNull(taskStatusResponse.error); + + taskStatusResponse = getTaskStatus.getTaskStatus("taskID_stopped"); + assertEquals(TaskStatusResponse.TaskStatus.INACTIVE, taskStatusResponse.taskStatus); + assertNull(taskStatusResponse.error); + } } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java index f7c89e174a81..5c543baf97f1 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/ListActiveTasksTest.java @@ -34,52 +34,52 @@ public class ListActiveTasksTest extends SolrTestCaseJ4 { -// private SolrQueryRequest mockQueryRequest; -// private SolrCore solrCore; -// private CancellableQueryTracker cancellableQueryTracker; -// -// private ListActiveTasks listActiveTasks; -// -// @BeforeClass -// public static void ensureWorkingMockito() { -// assumeWorkingMockito(); -// } -// -// @Override -// @Before -// public void setUp() throws Exception { -// super.setUp(); -// -// mockQueryRequest = mock(SolrQueryRequest.class); -// solrCore = mock(SolrCore.class); -// cancellableQueryTracker = mock(CancellableQueryTracker.class); -// -// listActiveTasks = new ListActiveTasks(mockQueryRequest); -// } -// -// @Test -// public void testGetActiveTasks() throws Exception { -// -// Map myMap = new LinkedHashMap<>(); -// myMap.put("taskID1", "/search?q=h&gf=text-1"); -// myMap.put("taskID2", "/search?q=h&gf=text-2"); -// Iterator> mockIterator = myMap.entrySet().iterator(); -// -// when(mockQueryRequest.getCore()).thenReturn(solrCore); -// when(solrCore.getCancellableQueryTracker()).thenReturn(cancellableQueryTracker); -// when(cancellableQueryTracker.getActiveQueriesGenerated()).thenReturn(mockIterator); -// -// ListActiveTaskResponse response = listActiveTasks.listAllActiveTasks(); -// assertNotNull(response.taskList); -// -// assertEquals(2, response.taskList.size()); -// -// assertEquals("taskID1", response.taskList.get(0).taskID); -// assertEquals("/search?q=h&gf=text-1", response.taskList.get(0).taskQuery); -// -// assertEquals("taskID2", response.taskList.get(1).taskID); -// assertEquals("/search?q=h&gf=text-2", response.taskList.get(1).taskQuery); -// -// assertNull(response.error); -// } + private SolrQueryRequest mockQueryRequest; + private SolrCore solrCore; + private CancellableQueryTracker cancellableQueryTracker; + + private ListActiveTasks listActiveTasks; + + @BeforeClass + public static void ensureWorkingMockito() { + assumeWorkingMockito(); + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + + mockQueryRequest = mock(SolrQueryRequest.class); + solrCore = mock(SolrCore.class); + cancellableQueryTracker = mock(CancellableQueryTracker.class); + + listActiveTasks = new ListActiveTasks(mockQueryRequest); + } + + @Test + public void testGetActiveTasks() throws Exception { + + Map myMap = new LinkedHashMap<>(); + myMap.put("taskID1", "/search?q=h&gf=text-1"); + myMap.put("taskID2", "/search?q=h&gf=text-2"); + Iterator> mockIterator = myMap.entrySet().iterator(); + + when(mockQueryRequest.getCore()).thenReturn(solrCore); + when(solrCore.getCancellableQueryTracker()).thenReturn(cancellableQueryTracker); + when(cancellableQueryTracker.getActiveQueriesGenerated()).thenReturn(mockIterator); + + ListActiveTaskResponse response = listActiveTasks.listAllActiveTasks(); + assertNotNull(response.taskList); + + assertEquals(2, response.taskList.size()); + + assertEquals("taskID1", response.taskList.get(0).taskID); + assertEquals("/search?q=h&gf=text-1", response.taskList.get(0).taskQuery); + + assertEquals("taskID2", response.taskList.get(1).taskID); + assertEquals("/search?q=h&gf=text-2", response.taskList.get(1).taskQuery); + + assertNull(response.error); + } } From 287c8cfc23f7aa6644825594babc5d062a85d644 Mon Sep 17 00:00:00 2001 From: jaykay12 Date: Fri, 19 Jun 2026 01:11:23 +0530 Subject: [PATCH 3/3] cl updated Signed-off-by: jaykay12 --- ...SOLR-18248-list-tasks.yml => SOLR-18248-refactor-list-api.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog/unreleased/{SOLR-18248-list-tasks.yml => SOLR-18248-refactor-list-api.yml} (100%) diff --git a/changelog/unreleased/SOLR-18248-list-tasks.yml b/changelog/unreleased/SOLR-18248-refactor-list-api.yml similarity index 100% rename from changelog/unreleased/SOLR-18248-list-tasks.yml rename to changelog/unreleased/SOLR-18248-refactor-list-api.yml