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


##########
solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaFieldAPI.java:
##########
@@ -0,0 +1,255 @@
+package org.apache.solr.handler.admin.api;
+
+import static 
org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import java.util.Map;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+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.common.MapWriter;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.SolrClassLoader;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.core.PluginInfo;
+import org.apache.solr.jersey.PermissionName;
+import org.apache.solr.jersey.SolrJerseyResponse;
+import org.apache.solr.pkg.PackageListeningClassLoader;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.security.PermissionNameProvider;
+
+public class GetSchemaFieldAPI extends GetSchemaAPI {
+
+  private final SolrParams params;
+
+  @Inject
+  public GetSchemaFieldAPI(IndexSchema indexSchema, SolrParams params) {
+    super(indexSchema);
+    this.params = params;
+  }
+
+  @GET
+  @Path("/fields")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaListFieldsResponse listSchemaFields() {
+    SchemaListFieldsResponse response = 
instantiateJerseyResponse(SchemaListFieldsResponse.class);
+    final String realName = "fields";
+
+    response.fields = listAllFieldsOfType(realName, params);
+
+    return response;
+  }
+
+  public static class SchemaListFieldsResponse extends SolrJerseyResponse {
+    @JsonProperty("fields")
+    public Object fields;
+  }
+
+  @GET
+  @Path("/fields/{fieldName}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaGetFieldInfoResponse getFieldInfo(@PathParam("fieldName") 
String fieldName) {
+    SchemaGetFieldInfoResponse response =
+        instantiateJerseyResponse(SchemaGetFieldInfoResponse.class);
+    final String realName = "fields";
+
+    SimpleOrderedMap<Object> fieldInfo = retrieveFieldInfoOfType(realName, 
fieldName, params);
+    if (fieldInfo != null) {
+      response.fieldInfo = fieldInfo;
+      return response;
+    }
+    throw new SolrException(
+        SolrException.ErrorCode.NOT_FOUND, "No such path /" + realName + "/" + 
fieldName);
+  }
+
+  public static class SchemaGetFieldInfoResponse extends SolrJerseyResponse {
+    @JsonProperty("field")
+    public SimpleOrderedMap<?> fieldInfo;
+  }
+
+  @GET
+  @Path("/copyfields")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaListCopyFieldsResponse listCopyFields() {
+    SchemaListCopyFieldsResponse response =
+        instantiateJerseyResponse(SchemaListCopyFieldsResponse.class);
+    final String realName = "copyfields";
+
+    response.copyFields = listAllFieldsOfType(realName, params);
+
+    return response;
+  }
+
+  public static class SchemaListCopyFieldsResponse extends SolrJerseyResponse {
+    @JsonProperty("copyFields")
+    public Object copyFields;
+  }
+
+  @GET
+  @Path("/dynamicfields")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaListDynamicFieldsResponse listDynamicFields() {
+    SchemaListDynamicFieldsResponse response =
+        instantiateJerseyResponse(SchemaListDynamicFieldsResponse.class);
+    final String realName = "dynamicfields";
+
+    response.dynamicFields = listAllFieldsOfType(realName, params);
+
+    return response;
+  }
+
+  public static class SchemaListDynamicFieldsResponse extends 
SolrJerseyResponse {
+    @JsonProperty("dynamicFields")
+    public Object dynamicFields;
+  }
+
+  @GET
+  @Path("/dynamicfields/{fieldName}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaGetDynamicFieldInfoResponse getDynamicFieldInfo(
+      @PathParam("fieldName") String fieldName) {
+    SchemaGetDynamicFieldInfoResponse response =
+        instantiateJerseyResponse(SchemaGetDynamicFieldInfoResponse.class);
+    final String realName = "dynamicfields";
+
+    SimpleOrderedMap<Object> dynamicFieldInfo =
+        retrieveFieldInfoOfType(realName, fieldName, params);
+    if (dynamicFieldInfo != null) {
+      response.dynamicFieldInfo = dynamicFieldInfo;
+      return response;
+    }
+    throw new SolrException(
+        SolrException.ErrorCode.NOT_FOUND, "No such path /" + realName + "/" + 
fieldName);
+  }
+
+  public static class SchemaGetDynamicFieldInfoResponse extends 
SolrJerseyResponse {
+    @JsonProperty("dynamicField")
+    public SimpleOrderedMap<?> dynamicFieldInfo;
+  }
+
+  @GET
+  @Path("/fieldtypes")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaListFieldTypesResponse listSchemaFieldTypes() {
+    SchemaListFieldTypesResponse response =
+        instantiateJerseyResponse(SchemaListFieldTypesResponse.class);
+    final String realName = "fieldtypes";
+
+    response.fieldTypes = listAllFieldsOfType(realName, params);
+
+    return response;
+  }
+
+  public static class SchemaListFieldTypesResponse extends SolrJerseyResponse {
+    @JsonProperty("fieldTypes")
+    public Object fieldTypes;
+  }
+
+  @GET
+  @Path("/fieldtypes/{fieldTypeName}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML, 
BINARY_CONTENT_TYPE_V2})
+  @PermissionName(PermissionNameProvider.Name.SCHEMA_READ_PERM)
+  public SchemaGetFieldTypeInfoResponse getFieldTypeInfo(
+      @PathParam("fieldTypeName") String fieldTypeName) {
+    SchemaGetFieldTypeInfoResponse response =
+        instantiateJerseyResponse(SchemaGetFieldTypeInfoResponse.class);
+
+    final String realName = "fieldtypes";
+
+    SimpleOrderedMap<Object> fieldTypeInfo =
+        retrieveFieldInfoOfType(realName, fieldTypeName, params);
+    if (fieldTypeInfo != null) {
+      response.fieldTypeInfo = fieldTypeInfo;
+      return response;
+    }
+    throw new SolrException(
+        SolrException.ErrorCode.NOT_FOUND, "No such path /" + realName + "/" + 
fieldTypeName);
+  }
+
+  public static class SchemaGetFieldTypeInfoResponse extends 
SolrJerseyResponse {
+    @JsonProperty("fieldType")
+    public SimpleOrderedMap<?> fieldTypeInfo;
+  }
+
+  private Object listAllFieldsOfType(String realName, SolrParams params) {
+    String camelCaseRealName = IndexSchema.nameMapping.get(realName);

Review Comment:
   6 is a lot, 🤔 
   
   Ultimately, I think there will be value in being as explicit as possible 
here.  But most of those benefits rely on JIRA tickets that haven't been 
finished yet (e.g. using these API definitions to [auto-generate client 
code](https://github.com/apache/solr/pull/1681)).
   
   So, I'm happy to go either way here.  It'll set us up really nicely if we're 
more explicit with the API params.  But if you don't want the method signature 
to be noisy in the meantime, that also makes sense to me.



##########
solr/core/src/test/org/apache/solr/handler/admin/api/GetSchemaAPITest.java:
##########
@@ -55,6 +59,38 @@ public void testReliesOnIndexSchemaWhenFetchingWholeSchema() 
{
     assertEquals("flagValue", response.schema.get("flagKey"));
   }
 
+  @Test
+  public void testLooksUpNameFromLatestCoreSchema() throws Exception {
+    when(mockSchema.getSchemaName()).thenReturn("expectedSchemaName");
+
+    final GetSchemaAPI.SchemaNameResponse response = api.getSchemaName();
+
+    assertEquals("expectedSchemaName", response.name);
+    assertNull(response.error);
+  }
+
+  /**
+   * Test the v2 to v1 response mapping for /schema/name
+   *
+   * <p>{@link SchemaHandler} uses the v2 {@link GetSchemaAPI} (and its 
response class {@link
+   * GetSchemaAPI.SchemaNameResponse}) internally to serve the v1 version of 
this functionality. So
+   * it's important to make sure that our response stays compatible with SolrJ 
- both because that's
+   * important in its own right and because that ensures we haven't 
accidentally changed the v1
+   * response format.
+   */
+  @Test
+  public void testResponseCanBeParsedBySolrJ() {

Review Comment:
   Yikes - it worries me that I didn't remember haha.
   
   > I can add similar tests to more places if you think it would be useful.
   
   Absolutely, if you're willing. I think this would be a great type of test to 
have for other APIs as well!



-- 
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-unsubscr...@solr.apache.org

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


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

Reply via email to