You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ge...@apache.org on 2023/03/15 14:22:38 UTC
[solr] branch main updated: SOLR-16393: Migrate alias-deletion to JAX-RS (#1452)
This is an automated email from the ASF dual-hosted git repository.
gerlowskija 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 52504fa27dd SOLR-16393: Migrate alias-deletion to JAX-RS (#1452)
52504fa27dd is described below
commit 52504fa27dd5f603e74b10e84e0ff830c55c9fc3
Author: Jason Gerlowski <ge...@apache.org>
AuthorDate: Wed Mar 15 10:22:29 2023 -0400
SOLR-16393: Migrate alias-deletion to JAX-RS (#1452)
This commit makes various cosmetic improvements to Solr's v2 delete
alias API, to bring it more into line with the more REST-ful v2
design. In the process it also converts the API to the JAX-RS
framework.
As of this commit, the delete-alias API is now
- DELETE /api/aliases/aliasName
---
solr/CHANGES.txt | 6 ++
.../org/apache/solr/handler/CollectionsAPI.java | 12 ---
.../solr/handler/admin/CollectionsHandler.java | 13 ++-
.../solr/handler/admin/api/DeleteAliasAPI.java | 92 ++++++++++++++++++++++
.../apache/solr/jersey/AsyncJerseyResponse.java} | 12 ++-
.../SubResponseAccumulatingJerseyResponse.java | 5 +-
.../solr/handler/admin/TestCollectionAPIs.java | 7 --
.../handler/admin/V2CollectionsAPIMappingTest.java | 13 ---
.../solr/handler/admin/api/DeleteAliasAPITest.java | 45 +++++++++++
.../deployment-guide/pages/alias-management.adoc | 10 +--
10 files changed, 163 insertions(+), 52 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index c33f66c9a77..202d941b40c 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -45,6 +45,12 @@ Improvements
Bug Fixes
---------------------
+Improvements
+---------------------
+
+* SOLR-16393: The path of the v2 "delete alias" API has been tweaked slightly to be more intuitive, and is now available at
+ `DELETE /api/aliases/aliasName`. (Jason Gerlowski)
+
================== 9.2.0 ==================
New Features
diff --git a/solr/core/src/java/org/apache/solr/handler/CollectionsAPI.java b/solr/core/src/java/org/apache/solr/handler/CollectionsAPI.java
index a2b76ced5b8..1e3aeac45ee 100644
--- a/solr/core/src/java/org/apache/solr/handler/CollectionsAPI.java
+++ b/solr/core/src/java/org/apache/solr/handler/CollectionsAPI.java
@@ -39,7 +39,6 @@ import org.apache.solr.api.PayloadObj;
import org.apache.solr.client.solrj.request.beans.BackupCollectionPayload;
import org.apache.solr.client.solrj.request.beans.CreateAliasPayload;
import org.apache.solr.client.solrj.request.beans.CreatePayload;
-import org.apache.solr.client.solrj.request.beans.DeleteAliasPayload;
import org.apache.solr.client.solrj.request.beans.RestoreCollectionPayload;
import org.apache.solr.client.solrj.request.beans.SetAliasPropertyPayload;
import org.apache.solr.client.solrj.request.beans.V2ApiConstants;
@@ -55,7 +54,6 @@ public class CollectionsAPI {
public static final String V2_RESTORE_CMD = "restore-collection";
public static final String V2_CREATE_ALIAS_CMD = "create-alias";
public static final String V2_SET_ALIAS_PROP_CMD = "set-alias-property";
- public static final String V2_DELETE_ALIAS_CMD = "delete-alias";
private final CollectionsHandler collectionsHandler;
@@ -142,16 +140,6 @@ public class CollectionsAPI {
wrapParams(obj.getRequest(), v1Params), obj.getResponse());
}
- @Command(name = V2_DELETE_ALIAS_CMD)
- public void deleteAlias(PayloadObj<DeleteAliasPayload> obj) throws Exception {
- final DeleteAliasPayload v2Body = obj.get();
- final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
- v1Params.put(ACTION, CollectionAction.DELETEALIAS.toLower());
-
- collectionsHandler.handleRequestBody(
- wrapParams(obj.getRequest(), v1Params), obj.getResponse());
- }
-
@Command(name = V2_CREATE_COLLECTION_CMD)
public void create(PayloadObj<CreatePayload> obj) throws Exception {
final CreatePayload v2Body = obj.get();
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index bcbe2ce66b0..8371e1041b1 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@ -210,6 +210,7 @@ import org.apache.solr.handler.admin.api.BalanceShardUniqueAPI;
import org.apache.solr.handler.admin.api.CollectionPropertyAPI;
import org.apache.solr.handler.admin.api.CollectionStatusAPI;
import org.apache.solr.handler.admin.api.CreateShardAPI;
+import org.apache.solr.handler.admin.api.DeleteAliasAPI;
import org.apache.solr.handler.admin.api.DeleteCollectionAPI;
import org.apache.solr.handler.admin.api.DeleteNodeAPI;
import org.apache.solr.handler.admin.api.DeleteReplicaAPI;
@@ -857,7 +858,16 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
return result;
}),
- DELETEALIAS_OP(DELETEALIAS, (req, rsp, h) -> copy(req.getParams().required(), null, NAME)),
+ DELETEALIAS_OP(
+ DELETEALIAS,
+ (req, rsp, h) -> {
+ final DeleteAliasAPI deleteAliasAPI = new DeleteAliasAPI(h.coreContainer, req, rsp);
+ final SolrJerseyResponse response =
+ deleteAliasAPI.deleteAlias(
+ req.getParams().required().get(NAME), req.getParams().get(ASYNC));
+ V2ApiUtils.squashIntoSolrResponseWithoutHeader(rsp, response);
+ return null;
+ }),
/**
* Change properties for an alias (use CREATEALIAS_OP to change the actual value of the alias)
@@ -2074,6 +2084,7 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
public Collection<Class<? extends JerseyResource>> getJerseyResources() {
return List.of(
AddReplicaPropertyAPI.class,
+ DeleteAliasAPI.class,
DeleteCollectionAPI.class,
DeleteReplicaPropertyAPI.class,
ListCollectionsAPI.class,
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAliasAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAliasAPI.java
new file mode 100644
index 00000000000..4b9a4480507
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAliasAPI.java
@@ -0,0 +1,92 @@
+/*
+ * 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.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+import static org.apache.solr.cloud.Overseer.QUEUE_OPERATION;
+import static org.apache.solr.common.params.CommonAdminParams.ASYNC;
+import static org.apache.solr.common.params.CommonParams.NAME;
+import static org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT;
+import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.params.CollectionParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.handler.admin.CollectionsHandler;
+import org.apache.solr.jersey.AsyncJerseyResponse;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+@Path("/aliases/{aliasName}")
+public class DeleteAliasAPI extends AdminAPIBase {
+ @Inject
+ public DeleteAliasAPI(
+ CoreContainer coreContainer,
+ SolrQueryRequest solrQueryRequest,
+ SolrQueryResponse solrQueryResponse) {
+ super(coreContainer, solrQueryRequest, solrQueryResponse);
+ }
+
+ @DELETE
+ @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2})
+ @PermissionName(COLL_EDIT_PERM)
+ public SolrJerseyResponse deleteAlias(
+ @PathParam("aliasName") String aliasName, @QueryParam("async") String asyncId)
+ throws Exception {
+ final AsyncJerseyResponse response = instantiateJerseyResponse(AsyncJerseyResponse.class);
+ final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer();
+
+ final ZkNodeProps remoteMessage = createRemoteMessage(aliasName, asyncId);
+ final SolrResponse remoteResponse =
+ CollectionsHandler.submitCollectionApiCommand(
+ coreContainer,
+ coreContainer.getDistributedCollectionCommandRunner(),
+ remoteMessage,
+ CollectionParams.CollectionAction.DELETEALIAS,
+ DEFAULT_COLLECTION_OP_TIMEOUT);
+ if (remoteResponse.getException() != null) {
+ throw remoteResponse.getException();
+ }
+
+ if (asyncId != null) {
+ response.requestId = asyncId;
+ }
+
+ return response;
+ }
+
+ public static ZkNodeProps createRemoteMessage(String aliasName, String asyncId) {
+ final Map<String, Object> remoteMessage = new HashMap<>();
+ remoteMessage.put(QUEUE_OPERATION, CollectionParams.CollectionAction.DELETEALIAS.toLower());
+ remoteMessage.put(NAME, aliasName);
+ if (asyncId != null) remoteMessage.put(ASYNC, asyncId);
+
+ return new ZkNodeProps(remoteMessage);
+ }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/DeleteAliasPayload.java b/solr/core/src/java/org/apache/solr/jersey/AsyncJerseyResponse.java
similarity index 71%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/DeleteAliasPayload.java
rename to solr/core/src/java/org/apache/solr/jersey/AsyncJerseyResponse.java
index 4ccd0601a66..af08d227172 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/DeleteAliasPayload.java
+++ b/solr/core/src/java/org/apache/solr/jersey/AsyncJerseyResponse.java
@@ -14,14 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.solr.client.solrj.request.beans;
-import org.apache.solr.common.annotation.JsonProperty;
-import org.apache.solr.common.util.ReflectMapWriter;
+package org.apache.solr.jersey;
-public class DeleteAliasPayload implements ReflectMapWriter {
- @JsonProperty(required = true)
- public String name;
+import com.fasterxml.jackson.annotation.JsonProperty;
- @JsonProperty public String async;
+public class AsyncJerseyResponse extends SolrJerseyResponse {
+ @JsonProperty("requestid")
+ public String requestId;
}
diff --git a/solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java b/solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java
index ab476771d75..6f02e9b6b1c 100644
--- a/solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java
+++ b/solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java
@@ -27,10 +27,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* during the APIs execution. (e.g. the collection-deletion response itself contains the responses
* from the 'UNLOAD' call send to each core.) This class encapsulates those responses as possible.
*/
-public class SubResponseAccumulatingJerseyResponse extends SolrJerseyResponse {
-
- @JsonProperty("requestid")
- public String requestId;
+public class SubResponseAccumulatingJerseyResponse extends AsyncJerseyResponse {
// TODO The 'Object' value in this and the failure prop below have a more defined structure.
// Specifically, each value is a map whose keys are node names and whose values are full
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
index 326066239ad..35847701431 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
@@ -129,13 +129,6 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 {
"{create-alias:{name: aliasName , collections:[c1,c2] }}",
"{operation : createalias, name: aliasName, collections:\"c1,c2\" }");
- compareOutput(
- apiBag,
- "/collections",
- POST,
- "{delete-alias:{ name: aliasName}}",
- "{operation : deletealias, name: aliasName}");
-
compareOutput(
apiBag, "/collections/collName", POST, "{reload:{}}", "{name:collName, operation :reload}");
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java b/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java
index 2949fd38a67..ae099f24cb7 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java
@@ -175,19 +175,6 @@ public class V2CollectionsAPIMappingTest extends V2ApiMappingTest<CollectionsHan
RoutedAlias.CREATE_COLLECTION_PREFIX + ZkStateReader.REPLICATION_FACTOR));
}
- @Test
- public void testDeleteAliasAllProperties() throws Exception {
- final SolrParams v1Params =
- captureConvertedV1Params(
- "/collections",
- "POST",
- "{'delete-alias': {" + "'name': 'aliasName', " + "'async': 'requestTrackingId'" + "}}");
-
- assertEquals(CollectionParams.CollectionAction.DELETEALIAS.lowerName, v1Params.get(ACTION));
- assertEquals("aliasName", v1Params.get(CommonParams.NAME));
- assertEquals("requestTrackingId", v1Params.get(CommonAdminParams.ASYNC));
- }
-
@Test
public void testSetAliasAllProperties() throws Exception {
final SolrParams v1Params =
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java
new file mode 100644
index 00000000000..2dcaf14d183
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.cloud.Overseer.QUEUE_OPERATION;
+import static org.apache.solr.common.params.CommonAdminParams.ASYNC;
+import static org.apache.solr.common.params.CoreAdminParams.NAME;
+
+import java.util.Map;
+import org.apache.solr.SolrTestCaseJ4;
+import org.junit.Test;
+
+/** Unit tests for {@link DeleteAliasAPI}. */
+public class DeleteAliasAPITest extends SolrTestCaseJ4 {
+
+ @Test
+ public void testConstructsValidRemoteMessage() {
+ Map<String, Object> props =
+ DeleteAliasAPI.createRemoteMessage("aliasName", null).getProperties();
+ assertEquals(2, props.size());
+ assertEquals("deletealias", props.get(QUEUE_OPERATION));
+ assertEquals("aliasName", props.get(NAME));
+
+ props = DeleteAliasAPI.createRemoteMessage("aliasName", "asyncId").getProperties();
+ assertEquals(3, props.size());
+ assertEquals("deletealias", props.get(QUEUE_OPERATION));
+ assertEquals("aliasName", props.get(NAME));
+ assertEquals("asyncId", props.get(ASYNC));
+ }
+}
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc
index bb1f98c98f6..b3f5d1d93a1 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc
@@ -749,13 +749,7 @@ http://localhost:8983/solr/admin/collections?action=DELETEALIAS&name=testalias
[source,bash]
----
-curl -X POST http://localhost:8983/api/collections -H 'Content-Type: application/json' -d '
-{
- "delete-alias":{
- "name":"testalias"
- }
-}
-'
+curl -X DELETE http://localhost:8983/api/aliases/testalias
----
====
--
@@ -770,7 +764,7 @@ curl -X POST http://localhost:8983/api/collections -H 'Content-Type: application
s|Required |Default: none
|===
+
-The name of the alias to delete.
+The name of the alias to delete. Specified in the path of v2 requests, and as an explicit request parameter for v1 requests.
`async`::
+