gerlowskija commented on code in PR #5284:
URL: https://github.com/apache/solr/pull/5284#discussion_r4526428548


##########
changelog/unreleased/SOLR-16398-rebalance-migrate.yml:
##########
@@ -0,0 +1,7 @@
+title: Migrate the v2 rebalance-leaders and migrate-docs APIs to JAX-RS

Review Comment:
   [-0] These changelog entries ultimately end up in front of our users, and I 
kindof doubt most users care about "minor" details like what framework is used 
under-the-hood to implement the APIs.
   
   IMO changelog entries for v2 APIs should highlight either the changes to the 
API cosmetics, or the SolrJ request/response classes that users can now start 
using.  (Converting an API to JAX-RS has it picked up by our OpenAPI 
Specification, which we use to generate client code for Java and other 
languages.  So while customers likely don't care about JAX-RS in and of 
itself...they probably do care that about the new SolrJ goodies that a JAX-RS 
migration implicitly creates.)



##########
solr/api/src/java/org/apache/solr/client/api/endpoint/RebalanceLeadersApi.java:
##########
@@ -0,0 +1,38 @@
+/*
+ * 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 io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import org.apache.solr.client.api.model.FlexibleSolrJerseyResponse;
+import org.apache.solr.client.api.model.RebalanceLeadersRequestBody;
+
+@Path("/collections/{collectionName}/rebalance-leaders")
+public interface RebalanceLeadersApi {
+  @POST
+  @Operation(
+      summary = "Rebalance shard leaders in a collection according to 
preferred leader settings.",
+      tags = {"collections"})
+  FlexibleSolrJerseyResponse rebalanceLeaders(

Review Comment:
   [-0] FlexibleSolrJerseyResponse technically works, but it would better to 
create a new response type that provides a richer description of what we expect 
the response to look like.  This response type gets incorporated into our 
OpenAPI Specification and there's client code generated from that, so the more 
detail we can give about what users should actually expect this response to 
look like, the better.
   
   The best way to do this is to read through the rebalance-leaders logic used 
by both v1 and v2 and figure out what fields it's looking for and setting in 
the response.  For example, you can see that the response needs [at least a 
"summary" 
field](https://github.com/apache/solr/blob/main/solr/core/src/java/org/apache/solr/handler/admin/RebalanceLeaders.java#L165-L167).



##########
solr/core/src/java/org/apache/solr/handler/admin/api/RebalanceLeaders.java:
##########
@@ -0,0 +1,82 @@
+/*
+ * 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.common.cloud.ZkStateReader.COLLECTION_PROP;
+import static org.apache.solr.common.cloud.ZkStateReader.MAX_AT_ONCE_PROP;
+import static org.apache.solr.common.cloud.ZkStateReader.MAX_WAIT_SECONDS_PROP;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
+
+import jakarta.inject.Inject;
+import java.util.Map;
+import org.apache.solr.client.api.endpoint.RebalanceLeadersApi;
+import org.apache.solr.client.api.model.FlexibleSolrJerseyResponse;
+import org.apache.solr.client.api.model.RebalanceLeadersRequestBody;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/**
+ * V2 API for rebalancing shard leaders in a collection.
+ *
+ * <p>This API (POST /v2/collections/collectionName/rebalance-leaders) is 
analogous to the v1
+ * /admin/collections?action=REBALANCELEADERS command.
+ */
+public class RebalanceLeaders extends AdminAPIBase implements 
RebalanceLeadersApi {
+
+  @Inject
+  public RebalanceLeaders(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @Override
+  @PermissionName(COLL_EDIT_PERM)
+  @SuppressWarnings("unchecked")
+  public FlexibleSolrJerseyResponse rebalanceLeaders(
+      String collectionName, RebalanceLeadersRequestBody requestBody) throws 
Exception {
+    final var response = 
instantiateJerseyResponse(FlexibleSolrJerseyResponse.class);
+    fetchAndValidateZooKeeperAwareCoreContainer();
+    ensureRequiredParameterProvided(COLLECTION_PROP, collectionName);
+    recordCollectionForLogAndTracing(collectionName, solrQueryRequest);
+    if (requestBody == null) {
+      requestBody = new RebalanceLeadersRequestBody();
+    }
+
+    final var params = new ModifiableSolrParams(solrQueryRequest.getParams());
+    params.set(COLLECTION_PROP, collectionName);
+    if (requestBody.maxAtOnce != null) {
+      params.set(MAX_AT_ONCE_PROP, requestBody.maxAtOnce);
+    }
+    if (requestBody.maxWaitSeconds != null) {
+      params.set(MAX_WAIT_SECONDS_PROP, requestBody.maxWaitSeconds);
+    }
+    solrQueryRequest.setParams(params);
+
+    new org.apache.solr.handler.admin.RebalanceLeaders(

Review Comment:
   [-0] Wdyt about reworking `org.apache.solr.handler.admin.RebalanceLeaders` 
to fit with our v2 approach a little better.  It looks like we're the only 
caller of this class, so rather than it taking in a 
SolrQueryRequest/SolrQueryResponse (very v1-specific classes), we could modify 
its to consume the strongly-type parameters we have access to here.
   
   That'd make this code look much nicer as most of the SolrParams-building 
code here could be dropped.
   
   If we don't want to do it for scope reasons, fair enough, but IMO it's worth 
considering.



##########
solr/core/src/test/org/apache/solr/handler/admin/api/CollectionCommandsV2IntegrationTest.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.request.SolrQuery;
+import org.apache.solr.client.solrj.request.V2Request;
+import org.apache.solr.client.solrj.response.RequestStatusState;
+import org.apache.solr.client.solrj.response.V2Response;
+import org.apache.solr.client.solrj.response.json.JsonMapResponseParser;
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.RoutingRule;
+import org.apache.solr.common.cloud.Slice;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/** Drives the JAX-RS collection command APIs over HTTP against a running 
SolrCloud cluster. */
+public class CollectionCommandsV2IntegrationTest extends SolrCloudTestCase {

Review Comment:
   [-1] I love having integration tests like this for the v2 APIs, but IMO they 
should use the generated SolrJ request/response classes instead of the somewhat 
"raw" V2Request/V2Response usage.  Two reasons for that:
   
   1. It gives us validation for the generated code, which otherwise doesn't 
have test coverage.
   2. Dogfooding - starting to use these generated client classes will help us 
notice things that we wish were different about them.
   
   ----
   
   [-1]  Do we need a whole new integration test class for this functionality, 
or could we accomplish the same coverage by adding or modifying existing test 
classes?  `TestRebalanceLeaders` and `MigrateRouteKeyTest` already have similar 
"full SolrCloud" tests for these capabilities.  If there's not a specific 
reason you think we should create a new test class, let's push the contents of 
this file down into those two test classes that already exist.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to