فهرست منبع

Expose 'features' option in Get Index API (#83083)

Dan Hermann 3 سال پیش
والد
کامیت
4ad7814a76

+ 6 - 0
docs/changelog/83083.yaml

@@ -0,0 +1,6 @@
+pr: 83083
+summary: Expose 'features' option in Get Index API
+area: Indices APIs
+type: enhancement
+issues:
+ - 82948

+ 10 - 0
rest-api-spec/src/main/resources/rest-api-spec/api/indices.get.json

@@ -50,6 +50,16 @@
         "default":"open",
         "description":"Whether wildcard expressions should get expanded to open or closed indices (default: open)"
       },
+      "features":{
+        "type":"enum",
+        "options":[
+          "aliases",
+          "mappings",
+          "settings"
+        ],
+        "default":"aliases,mappings,settings",
+        "description":"Return only information on specified index features"
+      },
       "flat_settings":{
         "type":"boolean",
         "description":"Return settings in flat format (default: false)"

+ 15 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.get/10_basic.yml

@@ -169,3 +169,18 @@ setup:
      catch: bad_request
      indices.get:
        index: _foo
+
+---
+"Should return only selected features":
+  - skip:
+      version: " - 8.0.99"
+      reason: "features option added in 8.1.0"
+
+  - do:
+      indices.get:
+        index: test_index
+        features: aliases,settings
+
+  - is_true: test_index.aliases
+  - is_true: test_index.settings
+  - match:   { test_index.mappings: {}}

+ 31 - 1
server/src/main/java/org/elasticsearch/action/admin/indices/get/GetIndexRequest.java

@@ -13,8 +13,14 @@ import org.elasticsearch.action.support.master.info.ClusterInfoRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.util.ArrayUtils;
+import org.elasticsearch.rest.RestRequest;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
 
 /**
  * A request to retrieve information about an index.
@@ -50,9 +56,33 @@ public class GetIndexRequest extends ClusterInfoRequest<GetIndexRequest> {
             }
             return FEATURES[id];
         }
+
+        public static Feature[] fromRequest(RestRequest request) {
+            if (request.hasParam("features")) {
+                String[] featureNames = request.param("features").split(",");
+                Set<Feature> features = new HashSet<>();
+                List<String> invalidFeatures = new ArrayList<>();
+                for (int k = 0; k < featureNames.length; k++) {
+                    try {
+                        features.add(Feature.valueOf(featureNames[k].toUpperCase(Locale.ROOT)));
+                    } catch (IllegalArgumentException e) {
+                        invalidFeatures.add(featureNames[k]);
+                    }
+                }
+                if (invalidFeatures.size() > 0) {
+                    throw new IllegalArgumentException(
+                        String.format(Locale.ROOT, "Invalid features specified [%s]", String.join(",", invalidFeatures))
+                    );
+                } else {
+                    return features.toArray(Feature[]::new);
+                }
+            } else {
+                return DEFAULT_FEATURES;
+            }
+        }
     }
 
-    private static final Feature[] DEFAULT_FEATURES = new Feature[] { Feature.ALIASES, Feature.MAPPINGS, Feature.SETTINGS };
+    static final Feature[] DEFAULT_FEATURES = new Feature[] { Feature.ALIASES, Feature.MAPPINGS, Feature.SETTINGS };
     private Feature[] features = DEFAULT_FEATURES;
     private boolean humanReadable = false;
     private transient boolean includeDefaults = false;

+ 1 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetIndicesAction.java

@@ -69,6 +69,7 @@ public class RestGetIndicesAction extends BaseRestHandler {
         getIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getIndexRequest.masterNodeTimeout()));
         getIndexRequest.humanReadable(request.paramAsBoolean("human", false));
         getIndexRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
+        getIndexRequest.features(GetIndexRequest.Feature.fromRequest(request));
         return channel -> client.admin().indices().getIndex(getIndexRequest, new RestToXContentListener<>(channel));
     }
 

+ 77 - 0
server/src/test/java/org/elasticsearch/action/admin/indices/get/GetIndexRequestTests.java

@@ -0,0 +1,77 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.action.admin.indices.get;
+
+import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.RestRequestTests;
+import org.elasticsearch.test.ESTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+
+public class GetIndexRequestTests extends ESTestCase {
+
+    public void testFeaturesFromRequest() {
+        int numFeatures = randomIntBetween(1, GetIndexRequest.DEFAULT_FEATURES.length);
+        List<String> featureNames = new ArrayList<>();
+        List<GetIndexRequest.Feature> expectedFeatures = new ArrayList<>();
+        for (int k = 0; k < numFeatures; k++) {
+            GetIndexRequest.Feature feature = randomValueOtherThanMany(
+                f -> featureNames.contains(f.name()),
+                () -> randomFrom(GetIndexRequest.DEFAULT_FEATURES)
+            );
+            featureNames.add(feature.name());
+            expectedFeatures.add(feature);
+        }
+
+        RestRequest request = RestRequestTests.contentRestRequest("", Map.of("features", String.join(",", featureNames)));
+        GetIndexRequest.Feature[] featureArray = GetIndexRequest.Feature.fromRequest(request);
+        assertThat(featureArray, arrayContainingInAnyOrder(expectedFeatures.toArray(GetIndexRequest.Feature[]::new)));
+    }
+
+    public void testDuplicateFeatures() {
+        int numFeatures = randomIntBetween(1, 5);
+        GetIndexRequest.Feature feature = randomFrom(GetIndexRequest.DEFAULT_FEATURES);
+        List<String> featureList = new ArrayList<>();
+        for (int k = 0; k < numFeatures; k++) {
+            featureList.add(feature.name());
+        }
+        RestRequest request = RestRequestTests.contentRestRequest("", Map.of("features", String.join(",", featureList)));
+        GetIndexRequest.Feature[] features = GetIndexRequest.Feature.fromRequest(request);
+        assertThat(features.length, equalTo(1));
+        assertThat(features[0], equalTo(feature));
+    }
+
+    public void testMissingFeatures() {
+        RestRequest request = RestRequestTests.contentRestRequest("", Map.of());
+        GetIndexRequest.Feature[] features = GetIndexRequest.Feature.fromRequest(request);
+        assertThat(features, arrayContainingInAnyOrder(GetIndexRequest.DEFAULT_FEATURES));
+    }
+
+    public void testInvalidFeatures() {
+        int numFeatures = randomIntBetween(1, 4);
+        List<String> invalidFeatures = new ArrayList<>();
+        for (int k = 0; k < numFeatures; k++) {
+            invalidFeatures.add(randomAlphaOfLength(5));
+        }
+
+        RestRequest request = RestRequestTests.contentRestRequest("", Map.of("features", String.join(",", invalidFeatures)));
+        IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> GetIndexRequest.Feature.fromRequest(request));
+        assertThat(
+            e.getMessage(),
+            containsString(String.format(Locale.ROOT, "Invalid features specified [%s]", String.join(",", invalidFeatures)))
+        );
+    }
+}

+ 2 - 2
server/src/test/java/org/elasticsearch/rest/RestRequestTests.java

@@ -236,7 +236,7 @@ public class RestRequestTests extends ESTestCase {
         assertEquals("unknown content type", e.getMessage());
     }
 
-    private static RestRequest contentRestRequest(String content, Map<String, String> params) {
+    public static RestRequest contentRestRequest(String content, Map<String, String> params) {
         Map<String, List<String>> headers = new HashMap<>();
         headers.put("Content-Type", Collections.singletonList("application/json"));
         return contentRestRequest(content, params, headers);
@@ -250,7 +250,7 @@ public class RestRequestTests extends ESTestCase {
         return new ContentRestRequest(builder.build());
     }
 
-    private static final class ContentRestRequest extends RestRequest {
+    public static final class ContentRestRequest extends RestRequest {
 
         private final RestRequest restRequest;