This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new bf7a15afe3d Migrate RenameCoreAPI from homegrown @EndPoint/@Command to
JAX-RS (#4172)
bf7a15afe3d is described below
commit bf7a15afe3d59d2e71e5cf48f87ad6468e758bf3
Author: Eric Pugh <[email protected]>
AuthorDate: Tue Mar 3 05:47:36 2026 -0500
Migrate RenameCoreAPI from homegrown @EndPoint/@Command to JAX-RS (#4172)
Co-authored-by: copilot-swe-agent[bot]
<[email protected]>
Co-authored-by: epugh <[email protected]>
---
changelog/unreleased/migrate-rename-core-api.yml | 7 ++
.../solr/handler/admin/api/RenameCoreAPI.java | 74 ---------------
.../solr/handler/admin/api/RenameCoreAPITest.java | 103 +++++++++++++++++++++
.../handler/admin/api/V2CoreAPIMappingTest.java | 13 ---
4 files changed, 110 insertions(+), 87 deletions(-)
diff --git a/changelog/unreleased/migrate-rename-core-api.yml
b/changelog/unreleased/migrate-rename-core-api.yml
new file mode 100644
index 00000000000..432763e9e9e
--- /dev/null
+++ b/changelog/unreleased/migrate-rename-core-api.yml
@@ -0,0 +1,7 @@
+title: Remove dead code related to the V2 RenameCore API. Add additional
tests.
+type: removed
+authors:
+ - name: Eric Pugh
+links:
+- name: PR#4172
+ url: https://github.com/apache/solr/pull/4172
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java
deleted file mode 100644
index c2235af6894..00000000000
--- a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java
+++ /dev/null
@@ -1,74 +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.POST;
-import static org.apache.solr.handler.ClusterAPI.wrapParams;
-import static
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import org.apache.solr.api.Command;
-import org.apache.solr.api.EndPoint;
-import org.apache.solr.api.PayloadObj;
-import org.apache.solr.common.annotation.JsonProperty;
-import org.apache.solr.common.params.CoreAdminParams;
-import org.apache.solr.common.util.ReflectMapWriter;
-import org.apache.solr.handler.admin.CoreAdminHandler;
-
-/**
- * V2 API for renaming an existing Solr core.
- *
- * <p>The new API (POST /v2/cores/coreName {'rename': {...}}) is equivalent to
the v1
- * /admin/cores?action=rename command.
- */
-@EndPoint(
- path = {"/cores/{core}"},
- method = POST,
- permission = CORE_EDIT_PERM)
-public class RenameCoreAPI {
- private static final String V2_RENAME_CORE_CMD = "rename";
-
- private final CoreAdminHandler coreHandler;
-
- public RenameCoreAPI(CoreAdminHandler coreHandler) {
- this.coreHandler = coreHandler;
- }
-
- @Command(name = V2_RENAME_CORE_CMD)
- public void renameCore(PayloadObj<RenameCorePayload> obj) throws Exception {
- final RenameCorePayload v2Body = obj.get();
- final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
- v1Params.put(
- CoreAdminParams.ACTION,
-
CoreAdminParams.CoreAdminAction.RENAME.name().toLowerCase(Locale.ROOT));
- v1Params.put(
- CoreAdminParams.CORE,
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE));
-
- // V1 API uses 'other' instead of 'to' to represent the new core name.
- v1Params.put(CoreAdminParams.OTHER, v1Params.remove("to"));
-
- coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params),
obj.getResponse());
- }
-
- public static class RenameCorePayload implements ReflectMapWriter {
- @JsonProperty(required = true)
- public String to;
- }
-}
diff --git
a/solr/core/src/test/org/apache/solr/handler/admin/api/RenameCoreAPITest.java
b/solr/core/src/test/org/apache/solr/handler/admin/api/RenameCoreAPITest.java
new file mode 100644
index 00000000000..9e88889ac59
--- /dev/null
+++
b/solr/core/src/test/org/apache/solr/handler/admin/api/RenameCoreAPITest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.core.CoreContainer.ALLOW_PATHS_SYSPROP;
+
+import java.nio.charset.StandardCharsets;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.api.model.SolrJerseyResponse;
+import org.apache.solr.client.solrj.RemoteSolrException;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.request.CoresApi;
+import org.apache.solr.client.solrj.request.GenericV2SolrRequest;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.EnvUtils;
+import org.apache.solr.util.ExternalPaths;
+import org.apache.solr.util.SolrJettyTestRule;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * The success case and the missing-parameter error case use the generated
{@link
+ * org.apache.solr.client.solrj.request.CoresApi.RenameCore} request type,
asserting directly on
+ * {@link SolrJerseyResponse#responseHeader} status and {@link
+ * org.apache.solr.client.api.model.ErrorInfo#msg} because the generated typed
client uses {@code
+ * JacksonDataBindResponseParser}, which does not yet propagate errors as
exceptions (SOLR-17549).
+ *
+ * <p>The missing-body error case uses {@link GenericV2SolrRequest} with an
explicit {@code "null"}
+ * JSON body, because {@link
org.apache.solr.client.solrj.request.CoresApi.RenameCore} always
+ * serializes a request body and therefore cannot represent a truly absent
body. The standard
+ * response parser used by {@link GenericV2SolrRequest} does propagate 4xx
responses as {@link
+ * RemoteSolrException}s.
+ *
+ * <p>TODO: Deal with this when generated code does properly throw an
exception!
+ */
+public class RenameCoreAPITest extends SolrTestCaseJ4 {
+
+ @ClassRule public static SolrJettyTestRule solrTestRule = new
SolrJettyTestRule();
+
+ @BeforeClass
+ public static void beforeTest() throws Exception {
+ EnvUtils.setProperty(
+ ALLOW_PATHS_SYSPROP,
ExternalPaths.SERVER_HOME.toAbsolutePath().toString());
+ solrTestRule.startSolr(createTempDir());
+ solrTestRule
+ .newCollection(DEFAULT_TEST_CORENAME)
+ .withConfigSet(ExternalPaths.DEFAULT_CONFIGSET)
+ .create();
+ }
+
+ @Test
+ public void testRenameCoreToSameNameSucceeds() throws Exception {
+ CoresApi.RenameCore renameRequest = new
CoresApi.RenameCore(DEFAULT_TEST_CORENAME);
+ renameRequest.setTo(DEFAULT_TEST_CORENAME);
+ SolrJerseyResponse response =
renameRequest.process(solrTestRule.getAdminClient());
+ assertEquals(0, response.responseHeader.status);
+ }
+
+ @Test
+ public void testMissingRequestBodyThrowsError() {
+ // Sending JSON "null" as the body causes Jersey to deserialize it to a
null requestBody,
+ // triggering the handler's "Required request-body is missing" guard.
+ GenericV2SolrRequest renameRequest =
+ new GenericV2SolrRequest(
+ SolrRequest.METHOD.POST,
+ "/cores/" + DEFAULT_TEST_CORENAME + "/rename",
+ SolrRequest.SolrRequestType.ADMIN);
+ renameRequest.withContent("null".getBytes(StandardCharsets.UTF_8),
"application/json");
+ final RemoteSolrException solrException =
+ expectThrows(
+ RemoteSolrException.class, () ->
renameRequest.process(solrTestRule.getAdminClient()));
+ assertEquals(400, solrException.code());
+ assertTrue(solrException.getMessage().contains("Required request-body is
missing"));
+ }
+
+ @Test
+ public void testMissingToParameterThrowsError() throws Exception {
+ // CoresApi.RenameCore always serializes a body, so leaving setTo()
uncalled sends a body
+ // whose "to" field is null. The handler's ensureRequiredParameterProvided
guard returns a 400,
+ // which JacksonDataBindResponseParser surfaces via the response fields
rather than as an
+ // exception (SOLR-17549), so we assert directly on responseHeader.status
and error.msg.
+ CoresApi.RenameCore renameRequest = new
CoresApi.RenameCore(DEFAULT_TEST_CORENAME);
+ SolrJerseyResponse response =
renameRequest.process(solrTestRule.getAdminClient());
+ assertEquals(SolrException.ErrorCode.BAD_REQUEST.code,
response.responseHeader.status);
+ assertNotNull(response.error);
+ assertTrue(response.error.msg.contains("Missing required parameter: to"));
+ }
+}
diff --git
a/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
b/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
index bd3171cd1c3..f33e0df9dc8 100644
---
a/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
+++
b/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
@@ -24,7 +24,6 @@ import static org.apache.solr.common.params.CommonParams.PATH;
import static org.apache.solr.common.params.CoreAdminParams.CORE;
import static org.apache.solr.common.params.CoreAdminParams.CORE_NODE_NAME;
import static org.apache.solr.common.params.CoreAdminParams.NAME;
-import static org.apache.solr.common.params.CoreAdminParams.OTHER;
import static org.apache.solr.common.params.CoreAdminParams.RANGES;
import static org.apache.solr.common.params.CoreAdminParams.TARGET_CORE;
@@ -62,7 +61,6 @@ public class V2CoreAPIMappingTest extends
V2ApiMappingTest<CoreAdminHandler> {
@Override
public void populateApiBag() {
final CoreAdminHandler handler = getRequestHandler();
- apiBag.registerObject(new RenameCoreAPI(handler));
apiBag.registerObject(new SplitCoreAPI(handler));
apiBag.registerObject(new RequestCoreRecoveryAPI(handler));
apiBag.registerObject(new PrepareCoreRecoveryAPI(handler));
@@ -71,17 +69,6 @@ public class V2CoreAPIMappingTest extends
V2ApiMappingTest<CoreAdminHandler> {
apiBag.registerObject(new RequestBufferUpdatesAPI(handler));
}
- @Test
- public void testRenameCoreAllParams() throws Exception {
- final SolrParams v1Params =
- captureConvertedV1Params(
- "/cores/coreName", "POST", "{\"rename\": {\"to\":
\"otherCore\"}}");
-
- assertEquals("rename", v1Params.get(ACTION));
- assertEquals("coreName", v1Params.get(CORE));
- assertEquals("otherCore", v1Params.get(OTHER));
- }
-
@Test
public void testSplitCoreAllParams() throws Exception {
final SolrParams v1Params =