You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@solr.apache.org by "stillalex (via GitHub)" <gi...@apache.org> on 2023/03/14 17:02:25 UTC

[GitHub] [solr] stillalex opened a new pull request, #1459: SOLR-16393 Alias properties management

stillalex opened a new pull request, #1459:
URL: https://github.com/apache/solr/pull/1459

   https://issues.apache.org/jira/browse/SOLR-16393
   
   <!--
   _(If you are a project committer then you may remove some/all of the following template.)_
   
   Before creating a pull request, please file an issue in the ASF Jira system for Solr:
   
   * https://issues.apache.org/jira/projects/SOLR
   
   For something minor (i.e. that wouldn't be worth putting in release notes), you can skip JIRA. 
   To create a Jira issue, you will need to create an account there first.
   
   The title of the PR should reference the Jira issue number in the form:
   
   * SOLR-####: <short description of problem or changes>
   
   SOLR must be fully capitalized. A short description helps people scanning pull requests for items they can work on.
   
   Properly referencing the issue in the title ensures that Jira is correctly updated with code review comments and commits. -->
   
   
   # Description
   
   Alias properties management
   
   # Solution
   
   Please provide a short description of the approach taken to implement your solution.
   
   # Tests
   
   Please describe the tests you've developed or run to confirm this patch implements the feature or solves the problem.
   
   # Checklist
   
   Please review the following and check all that apply:
   
   - [ ] I have reviewed the guidelines for [How to Contribute](https://wiki.apache.org/solr/HowToContribute) and my code conforms to the standards described there to the best of my ability.
   - [ ] I have created a Jira issue and added the issue ID to my pull request title.
   - [ ] I have given Solr maintainers [access](https://help.github.com/en/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork) to contribute to my PR branch. (optional but recommended)
   - [ ] I have developed this patch against the `main` branch.
   - [ ] I have run `./gradlew check`.
   - [ ] I have added tests for my changes.
   - [ ] I have added documentation for the [Reference Guide](https://github.com/apache/solr/tree/main/solr/solr-ref-guide)
   


-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1137578242


##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);

Review Comment:
   sounds good. will add 404 if property is missing



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] gerlowskija commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1136901816


##########
solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java:
##########
@@ -1828,28 +1835,21 @@ public Map<String, Object> execute(
         });
 
     /**
-     * Places all prefixed properties in the sink map (or a new map) using the prefix as the key and
-     * a map of all prefixed properties as the value. The sub-map keys have the prefix removed.
+     * Collects all prefixed properties in a new. The resulting keys have the prefix removed.

Review Comment:
   [0] Typo: "in a new."  (You probably want 'map' at the end of that sentence?)



##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(

Review Comment:
   [+1] Thanks for adding in this "missing" alias API, really rounds out the v2 pattern nicely.



##########
solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc:
##########
@@ -657,7 +657,7 @@ If a key is set with a value that is empty it will be removed.
 
 [source,bash]
 ----
-http://localhost:8983/admin/collections?action=ALIASPROP&name=techproducts_alias&property.foo=bar
+curl -X POST 'http://localhost:8983/admin/collections?action=ALIASPROP&name=techproducts_alias&property.foo=bar'

Review Comment:
   [-1] Would you be willing to add some coverage here for the new v2 APIs that you added (alias-prop listing, single-alias-prop fetching, etc.)
   
   Would really help people use the alias prop functionality - I think right now the ref-guide suggests that people look in ZK if they need to know alias prop values!



##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);

Review Comment:
   [0] What do you think about throwing a `new SolrException(NOT_FOUND, "Some message")` here if the requested alias property didn't exist?



##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);
+    }
+
+    return response;
+  }
+
+  private Aliases readAliasesFromZk() throws Exception {
+    final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer();
+    final ZkStateReader zkStateReader = coreContainer.getZkController().getZkStateReader();
+    // Make sure we have the latest alias info, since a user has explicitly invoked an alias API
+    zkStateReader.getAliasesManager().update();
+    return zkStateReader.getAliases();
+  }
+
+  @PUT
+  @PermissionName(COLL_EDIT_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Update properties for a collection alias.",
+      tags = {"aliases"})
+  public SolrJerseyResponse updateAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @RequestBody(description = "Properties that need to be updated", required = true)
+          UpdateAliasPropertiesRequestBody requestBody)
+      throws Exception {
+
+    if (requestBody == null) {

Review Comment:
   Good question!
   
   You're right that any constraints added to the `@RequestBody` annotation are only considered in the docs and generated OpenAPI spec.
   
   Jersey does offer a way to validate requests based on constraint annotations, but we're not using it currently.  They call it "bean validation".  Basically you add an extra gradle dep on `org.glassfish.jersey.ext:jersey-bean-validation`, enable validation in your Jersey apps with a specific property (`jersey.config.beanValidation.enableOutputValidationErrorEntity.server`), and add any constraint annotations (like `@NotNull`) that you need.  You can even define your own annotations which is kindof cool.
   
   I think that we'll eventually want to utilize this everywhere we can, but right now it's hard to take advantage of it due to how the v1 code explicitly calls the Jersey classes and methods internally.  The v1 code isn't using the Jersey framework, so it can't take advantage of any bean validation, so any input checking still needs to happen explicitly as you've done here.
   
   At least, unless there's some other option I'm missing?  Maybe we should enable bean-validation for the benefit of those v2 APIs that don't have v1 counterparts (like the list-aliases you've added in this PR)?
   
   > checked some of the other apis and I could not find details
   
   This is probably just looseness on my part.  I'm probably not being as rigorous in input-validation as I should be 😬 



##########
solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java:
##########
@@ -291,20 +316,25 @@ public void testModifyPropertiesCAR() throws Exception {
     setAliasProperty.addProperty("foo", "baz");
     setAliasProperty.addProperty("bar", "bam");
     setAliasProperty.process(cluster.getSolrClient());
-    checkFooAndBarMeta(aliasName, zkStateReader);
+    checkFooAndBarMeta(aliasName, zkStateReader, "baz", "bam");
 
     // now verify we can delete
     setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
     setAliasProperty.addProperty("foo", "");
     setAliasProperty.process(cluster.getSolrClient());
+    checkFooAndBarMeta(aliasName, zkStateReader, null, "bam");
+
+    // TODO is this a bug? should "bar" be null after the following

Review Comment:
   I'm not sure whether it's a bug or not, but I agree that it's very surprising.  It seems like empty-string is the only way to delete alias properties.  Might be worth a thread on dev@ to see whether anyone knows if this is intentional or not.



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1137562476


##########
solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java:
##########
@@ -291,20 +316,25 @@ public void testModifyPropertiesCAR() throws Exception {
     setAliasProperty.addProperty("foo", "baz");
     setAliasProperty.addProperty("bar", "bam");
     setAliasProperty.process(cluster.getSolrClient());
-    checkFooAndBarMeta(aliasName, zkStateReader);
+    checkFooAndBarMeta(aliasName, zkStateReader, "baz", "bam");
 
     // now verify we can delete
     setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
     setAliasProperty.addProperty("foo", "");
     setAliasProperty.process(cluster.getSolrClient());
+    checkFooAndBarMeta(aliasName, zkStateReader, null, "bam");
+
+    // TODO is this a bug? should "bar" be null after the following

Review Comment:
   email sent to dev list



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on PR #1459:
URL: https://github.com/apache/solr/pull/1459#issuecomment-1470566279

   to answer the questions you posted:
   
   
   > Does this PR change any of the API responses (for those APIs which preexisted this PR? It doesn't look like it (which is good), but just wanted to double check.
   
   hmm. I did not touch the v1 apis, but I did remove the v2 collections support. let me know if this was not the right decision
   
   > I'm a little ambivalent about the response for GET /api/aliases/aName/properties/foo (which looks to be an API that's brand new to this PR?). Do we need to include "property": "foo" - presumably the user already knows which replica property they requested? I don't feel strongly in either direction here, just wondering aloud...
   
   I think I agree to remove it. you are right, doesn't feel like it's adding too much value
   
   > Does the v2 code need to support "deleting" a property via empty-string? It legitimately may because of the way that the v1 code is now structured to call into v2. But it'd be a nice thing to avoid bringing into v2, since v2 has an explicit DELETE API for that purpose now.
   
   I'm using much of the preexisting code, it might not be possible to change the apis to this level. plus if you are using the bulk property update, there would be no way to remove more properties in one go.
   
   


-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] gerlowskija merged pull request #1459: SOLR-16393 Alias properties management

Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija merged PR #1459:
URL: https://github.com/apache/solr/pull/1459


-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1135928319


##########
solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java:
##########
@@ -291,20 +316,25 @@ public void testModifyPropertiesCAR() throws Exception {
     setAliasProperty.addProperty("foo", "baz");
     setAliasProperty.addProperty("bar", "bam");
     setAliasProperty.process(cluster.getSolrClient());
-    checkFooAndBarMeta(aliasName, zkStateReader);
+    checkFooAndBarMeta(aliasName, zkStateReader, "baz", "bam");
 
     // now verify we can delete
     setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
     setAliasProperty.addProperty("foo", "");
     setAliasProperty.process(cluster.getSolrClient());
+    checkFooAndBarMeta(aliasName, zkStateReader, null, "bam");
+
+    // TODO is this a bug? should "bar" be null after the following

Review Comment:
   @gerlowskija this might be a bug? I added some assertions to this older test and results are a bit surprising. my understanding is that setting value to null should remove it, but it doesn't. maybe I am reading it wrong.



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1137581075


##########
solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc:
##########
@@ -657,7 +657,7 @@ If a key is set with a value that is empty it will be removed.
 
 [source,bash]
 ----
-http://localhost:8983/admin/collections?action=ALIASPROP&name=techproducts_alias&property.foo=bar
+curl -X POST 'http://localhost:8983/admin/collections?action=ALIASPROP&name=techproducts_alias&property.foo=bar'

Review Comment:
   not sure I follow, could you clarify a bit?
   
   I have alias prop listing https://github.com/apache/solr/pull/1459/files#diff-2cc6e0ae57c6bf17247dd5a4386f98b3123544cb816a12fdb864068705970f00R670 and property level get https://github.com/apache/solr/pull/1459/files#diff-2cc6e0ae57c6bf17247dd5a4386f98b3123544cb816a12fdb864068705970f00R685



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1137624480


##########
solr/solr-ref-guide/modules/deployment-guide/pages/alias-management.adoc:
##########
@@ -657,7 +657,7 @@ If a key is set with a value that is empty it will be removed.
 
 [source,bash]
 ----
-http://localhost:8983/admin/collections?action=ALIASPROP&name=techproducts_alias&property.foo=bar
+curl -X POST 'http://localhost:8983/admin/collections?action=ALIASPROP&name=techproducts_alias&property.foo=bar'

Review Comment:
   will add a property listing section, let's see how it looks



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] gerlowskija commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1139107003


##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);
+    }
+
+    return response;
+  }
+
+  private Aliases readAliasesFromZk() throws Exception {
+    final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer();
+    final ZkStateReader zkStateReader = coreContainer.getZkController().getZkStateReader();
+    // Make sure we have the latest alias info, since a user has explicitly invoked an alias API
+    zkStateReader.getAliasesManager().update();
+    return zkStateReader.getAliases();
+  }
+
+  @PUT
+  @PermissionName(COLL_EDIT_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Update properties for a collection alias.",
+      tags = {"aliases"})
+  public SolrJerseyResponse updateAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @RequestBody(description = "Properties that need to be updated", required = true)
+          UpdateAliasPropertiesRequestBody requestBody)
+      throws Exception {
+
+    if (requestBody == null) {

Review Comment:
   Sorry for being unclear.  I was attempting to convey that there _are_ mechanisms in Jersey to enforce this, but that we shouldn't use those mechanisms (yet).
   
   What you have here is perfect for now 👍 



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on PR #1459:
URL: https://github.com/apache/solr/pull/1459#issuecomment-1470880898

   @gerlowskija PR updated based on feedback. please take another look. thanks!


-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on PR #1459:
URL: https://github.com/apache/solr/pull/1459#issuecomment-1472280564

   fyi there were some merge errors on crave side, so I merged main branch again in the hope this gets unstuck


-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1135927504


##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);
+    }
+
+    return response;
+  }
+
+  private Aliases readAliasesFromZk() throws Exception {
+    final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer();
+    final ZkStateReader zkStateReader = coreContainer.getZkController().getZkStateReader();
+    // Make sure we have the latest alias info, since a user has explicitly invoked an alias API
+    zkStateReader.getAliasesManager().update();
+    return zkStateReader.getAliases();
+  }
+
+  @PUT
+  @PermissionName(COLL_EDIT_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Update properties for a collection alias.",
+      tags = {"aliases"})
+  public SolrJerseyResponse updateAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @RequestBody(description = "Properties that need to be updated", required = true)
+          UpdateAliasPropertiesRequestBody requestBody)
+      throws Exception {
+
+    if (requestBody == null) {

Review Comment:
   @gerlowskija leaving a comment for you here. I am fuzzy on how enforcing the not-null param works here. I realized the annotations with 'required=true' are just for docs, the actual null check is not performed by the framework. checked some of the other apis and I could not find details. please let me know your thoughts.



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] stillalex commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "stillalex (via GitHub)" <gi...@apache.org>.
stillalex commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1137543029


##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);
+    }
+
+    return response;
+  }
+
+  private Aliases readAliasesFromZk() throws Exception {
+    final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer();
+    final ZkStateReader zkStateReader = coreContainer.getZkController().getZkStateReader();
+    // Make sure we have the latest alias info, since a user has explicitly invoked an alias API
+    zkStateReader.getAliasesManager().update();
+    return zkStateReader.getAliases();
+  }
+
+  @PUT
+  @PermissionName(COLL_EDIT_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Update properties for a collection alias.",
+      tags = {"aliases"})
+  public SolrJerseyResponse updateAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @RequestBody(description = "Properties that need to be updated", required = true)
+          UpdateAliasPropertiesRequestBody requestBody)
+      throws Exception {
+
+    if (requestBody == null) {

Review Comment:
   I can't tell which way you are leaning here. are you suggesting I go for the new dependency and enable it for this api, or are you ok with leaving this as is and having a different PR for enabling annotation driven input validation for all existing apis that might need it? for me it works either way.



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] gerlowskija commented on pull request #1459: SOLR-16393 Alias properties management

Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on PR #1459:
URL: https://github.com/apache/solr/pull/1459#issuecomment-1469818743

   Hey Alex, thanks for the PR!
   
   A few comments/questions on the v2 endpoints themselves (since you summarized them in a comment above):
   
   1. Does this PR change any of the API responses (for those APIs which preexisted this PR?  It doesn't look like it (which is good), but just wanted to double check.
   2. I'm a little ambivalent about the response for `GET /api/collections/cName/replica/rName/properties/foo` (which looks to be an API that's brand new to this PR?).  Do we need to include `"property": "foo"` - presumably the user already knows which replica property they requested?  I don't feel strongly in either direction here, just wondering aloud...
   3. Does the v2 code need to support "deleting" a property via empty-string?  It legitimately may because of the way that the v1 code is now structured to call into v2.  But it'd be a nice thing to avoid bringing into v2, since v2 has an explicit DELETE API for that purpose now.
   
   That's all on the endpoints.  Will leave comments on the code itself inline.


-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org


[GitHub] [solr] gerlowskija commented on a diff in pull request #1459: SOLR-16393 Alias properties management

Posted by "gerlowskija (via GitHub)" <gi...@apache.org>.
gerlowskija commented on code in PR #1459:
URL: https://github.com/apache/solr/pull/1459#discussion_r1139107003


##########
solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java:
##########
@@ -0,0 +1,262 @@
+/*
+ * 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 static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.Aliases;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+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.JacksonReflectMapWriter;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/** V2 APIs for managing and inspecting properties for collection aliases */
+@Path("/aliases/{aliasName}/properties")
+public class AliasPropertyAPI extends AdminAPIBase {
+
+  @Inject
+  public AliasPropertyAPI(
+      CoreContainer coreContainer,
+      SolrQueryRequest solrQueryRequest,
+      SolrQueryResponse solrQueryResponse) {
+    super(coreContainer, solrQueryRequest, solrQueryResponse);
+  }
+
+  @GET
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get properties for a collection alias.",
+      tags = {"aliases"})
+  public GetAllAliasPropertiesResponse getAllAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAllAliasPropertiesResponse response =
+        instantiateJerseyResponse(GetAllAliasPropertiesResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.properties = aliases.getCollectionAliasProperties(aliasName);
+    }
+
+    return response;
+  }
+
+  @GET
+  @Path("/{propName}")
+  @PermissionName(COLL_READ_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Get a specific property for a collection alias.",
+      tags = {"aliases"})
+  public GetAliasPropertyResponse getAliasProperty(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @Parameter(description = "Property Name") @PathParam("propName") String propName)
+      throws Exception {
+    recordCollectionForLogAndTracing(null, solrQueryRequest);
+
+    final GetAliasPropertyResponse response =
+        instantiateJerseyResponse(GetAliasPropertyResponse.class);
+    final Aliases aliases = readAliasesFromZk();
+    if (aliases != null) {
+      response.property = propName;
+      response.value = aliases.getCollectionAliasProperties(aliasName).get(propName);
+    }
+
+    return response;
+  }
+
+  private Aliases readAliasesFromZk() throws Exception {
+    final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer();
+    final ZkStateReader zkStateReader = coreContainer.getZkController().getZkStateReader();
+    // Make sure we have the latest alias info, since a user has explicitly invoked an alias API
+    zkStateReader.getAliasesManager().update();
+    return zkStateReader.getAliases();
+  }
+
+  @PUT
+  @PermissionName(COLL_EDIT_PERM)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, BINARY_CONTENT_TYPE_V2})
+  @Operation(
+      summary = "Update properties for a collection alias.",
+      tags = {"aliases"})
+  public SolrJerseyResponse updateAliasProperties(
+      @Parameter(description = "Alias Name") @PathParam("aliasName") String aliasName,
+      @RequestBody(description = "Properties that need to be updated", required = true)
+          UpdateAliasPropertiesRequestBody requestBody)
+      throws Exception {
+
+    if (requestBody == null) {

Review Comment:
   Sorry for being unclear.  I was attempting to convey that there _are_ mechanisms in Jersey to enforce this, but that we shouldn't use those mechanisms (yet).
   
   We should probably file a separate ticket to start thinking about using that, but definitely not a part of this PR.
   
   What you have here is perfect for now 👍 



-- 
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: issues-unsubscribe@solr.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org