Repository: searchbox-io/Jest
Pull request #587 (2018-04-12 10:34:29)

Add Field-Stats and Cat-Recovery Apis support
This PR add 2 Operations to jest -
* add Cat Recovery api support
* add Field Stats api support




Patch:
diff --git a/jest-common/src/main/java/io/searchbox/core/Cat.java b/jest-common/src/main/java/io/searchbox/core/Cat.java
index 185139dc..dbb06ab2 100644
--- a/jest-common/src/main/java/io/searchbox/core/Cat.java
+++ b/jest-common/src/main/java/io/searchbox/core/Cat.java
@@ -103,10 +103,25 @@ public class Cat extends AbstractAction<CatResult> {
             return new Cat(this);
         }
 
+        @Override
+        public String operationPath() { return operationPath; }
+    }
+
+    public static class RecoveryBuilder extends AbstractMultiIndexActionBuilder<Cat, RecoveryBuilder> implements CatBuilder {
+        private static final String operationPath = "recovery";
+        public RecoveryBuilder() {
+            setHeader("accept", "application/json");
+            setHeader("content-type", "application/json");
+        }
+
+        @Override
+        public Cat build() { return new Cat(this); }
+
         @Override
         public String operationPath() {
             return operationPath;
         }
+
     }
 
     public static class ShardsBuilder extends AbstractMultiIndexActionBuilder<Cat, ShardsBuilder> implements CatBuilder {
diff --git a/jest-common/src/main/java/io/searchbox/fields/FieldStats.java b/jest-common/src/main/java/io/searchbox/fields/FieldStats.java
new file mode 100644
index 00000000..fc1de457
--- /dev/null
+++ b/jest-common/src/main/java/io/searchbox/fields/FieldStats.java
@@ -0,0 +1,62 @@
+package io.searchbox.fields;
+
+import io.searchbox.action.AbstractAction;
+import io.searchbox.action.GenericResultAbstractAction;
+import io.searchbox.client.config.ElasticsearchVersion;
+import io.searchbox.params.Parameters;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class FieldStats extends GenericResultAbstractAction {
+    protected FieldStats(FieldStats.Builder builder) {
+        super(builder);
+
+        this.indexName = builder.index;
+
+        Map<String, Object> fieldStatsBody = new HashMap<>();
+        fieldStatsBody.put("fields", builder.fields);
+
+        this.payload = fieldStatsBody;
+    }
+
+    @Override
+    public String getRestMethodName() {
+        return "POST";
+    }
+
+    @Override
+    protected String buildURI(ElasticsearchVersion elasticsearchVersion) {
+        String buildURI = super.buildURI(elasticsearchVersion);
+        if (buildURI.isEmpty())
+            return "_field_stats";
+
+        return buildURI + "/_field_stats";
+    }
+
+
+    public static class Builder extends AbstractAction.Builder<FieldStats, FieldStats.Builder> {
+
+        private String index;
+        private Object fields;
+
+        public Builder(Object fields) {
+            this.fields = fields;
+        }
+
+        public FieldStats.Builder setIndex(String index) {
+            this.index = index;
+            return this;
+        }
+
+        public FieldStats.Builder setLevel(String level) {
+            parameters.put(Parameters.LEVEL, level);
+            return this;
+        }
+
+        @Override
+        public FieldStats build() {
+            return new FieldStats(this);
+        }
+    }
+}
diff --git a/jest-common/src/main/java/io/searchbox/params/Parameters.java b/jest-common/src/main/java/io/searchbox/params/Parameters.java
index c0236c60..fc1ca4a6 100644
--- a/jest-common/src/main/java/io/searchbox/params/Parameters.java
+++ b/jest-common/src/main/java/io/searchbox/params/Parameters.java
@@ -71,6 +71,9 @@ public class Parameters {
 
     public static final String SCROLL = "scroll";
 
+    // indices, cluster (default)
+    public static final String LEVEL = "level";
+
     public static final String SCROLL_ID = "scroll_id";
 
     public static final String SEARCH_TYPE = "search_type";


Test patch:
diff --git a/jest-common/src/test/java/io/searchbox/core/CatRecoveryBuilderTest.java b/jest-common/src/test/java/io/searchbox/core/CatRecoveryBuilderTest.java
new file mode 100644
index 00000000..eeb2da1d
--- /dev/null
+++ b/jest-common/src/test/java/io/searchbox/core/CatRecoveryBuilderTest.java
@@ -0,0 +1,33 @@
+package io.searchbox.core;
+
+import io.searchbox.client.config.ElasticsearchVersion;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CatRecoveryBuilderTest {
+    @Test
+    public void shouldSetApplicationJsonHeader() {
+        Cat cat = new Cat.RecoveryBuilder().build();
+        assertEquals("application/json", cat.getHeader("accept"));
+        assertEquals("application/json", cat.getHeader("content-type"));
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexNotGiven() {
+        Cat cat = new Cat.RecoveryBuilder().build();
+        assertEquals("_cat/recovery/_all", cat.getURI(ElasticsearchVersion.UNKNOWN));
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexGiven() {
+        Cat cat = new Cat.RecoveryBuilder().addIndex("testIndex").build();
+        assertEquals("_cat/recovery/testIndex", cat.getURI(ElasticsearchVersion.UNKNOWN));
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenParameterGiven() {
+        Cat cat = new Cat.RecoveryBuilder().setParameter("v", "true").build();
+        assertEquals("_cat/recovery/_all?v=true", cat.getURI(ElasticsearchVersion.UNKNOWN));
+    }
+}
diff --git a/jest-common/src/test/java/io/searchbox/fields/FieldsStatsTest.java b/jest-common/src/test/java/io/searchbox/fields/FieldsStatsTest.java
new file mode 100644
index 00000000..8bfa1876
--- /dev/null
+++ b/jest-common/src/test/java/io/searchbox/fields/FieldsStatsTest.java
@@ -0,0 +1,40 @@
+package io.searchbox.fields;
+
+import com.google.gson.Gson;
+import io.searchbox.client.config.ElasticsearchVersion;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class FieldsStatsTest {
+    static final String TEST_FIELD = "test_name";
+    static final String INDEX = "twitter";
+    static final List FIELDS = Collections.singletonList(TEST_FIELD);
+
+    @Test
+    public void testBasicUriGeneration() {
+        FieldStats fieldStats = new FieldStats.Builder(FIELDS).setIndex(INDEX).build();
+        assertEquals("POST", fieldStats.getRestMethodName());
+        assertEquals(INDEX + "/_field_stats", fieldStats.getURI(ElasticsearchVersion.UNKNOWN));
+        assertEquals("{\"fields\":[\"" + TEST_FIELD + "\"]}", fieldStats.getData(new Gson()));
+    }
+
+    @Test
+    public void testBasicUriGenerationNoIndex() {
+        FieldStats fieldStats = new FieldStats.Builder(FIELDS).build();
+        assertEquals("POST", fieldStats.getRestMethodName());
+        assertEquals("_field_stats", fieldStats.getURI(ElasticsearchVersion.UNKNOWN));
+        assertEquals("{\"fields\":[\"" + TEST_FIELD + "\"]}", fieldStats.getData(new Gson()));
+    }
+
+    @Test
+    public void testBasicUriGenerationWithLevel() {
+        FieldStats fieldStats = new FieldStats.Builder(FIELDS).setIndex(INDEX).setLevel("indices").build();
+        assertEquals("POST", fieldStats.getRestMethodName());
+        assertEquals(INDEX + "/_field_stats?level=indices", fieldStats.getURI(ElasticsearchVersion.UNKNOWN));
+        assertEquals("{\"fields\":[\"" + TEST_FIELD + "\"]}", fieldStats.getData(new Gson()));
+    }
+}
diff --git a/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java b/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java
index f66379d1..eaaac250 100644
--- a/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java
+++ b/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java
@@ -1,9 +1,11 @@
 package io.searchbox.core;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.stream.IntStream;
 
 import com.google.gson.JsonElement;
 import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction;
@@ -74,6 +76,30 @@ public class CatIntegrationTest extends AbstractIntegrationTest {
         JSONAssert.assertEquals("[{\"alias\":\"catintegrationalias\",\"index\":\"catintegrationindex\"}]", result.getSourceAsString(), false);
     }
 
+    @Test
+    public void shouldDisplayRecoveryForSingleResult() throws IOException, JSONException {
+        createIndex(INDEX);
+        ensureSearchable(INDEX);
+
+        CatResult result = client.execute(new Cat.RecoveryBuilder().addIndex(INDEX).setParameter("h", "index,stage").build());
+
+        ArrayList<String[]> expectedPlainText = new ArrayList<>();
+        ArrayList<String> recoveryResponsePerShared = new ArrayList<>();
+
+        String expectedLine = "{\"index\":\"catintegrationindex\",\"stage\":\"done\"}";
+        expectedPlainText.add(new String[]{"index", "stage"});
+
+        IntStream.range(0, getNumShards(INDEX).totalNumShards).forEach(value -> {
+            expectedPlainText.add(new String[]{INDEX, "done"});
+            recoveryResponsePerShared.add(expectedLine);
+        });
+        assertArrayEquals(expectedPlainText.toArray(), result.getPlainText());
+
+        String expectedSourceAsString = "[" + String.join(",", recoveryResponsePerShared) + "]";
+
+        JSONAssert.assertEquals(expectedSourceAsString, result.getSourceAsString(), false);
+    }
+
     @Test
     public void shouldChangeOrderOfColumnsByspecifyingParameters() throws IOException, JSONException {
         createIndex(INDEX);
diff --git a/jest/src/test/java/io/searchbox/fields/FieldStatsIntegrationTest.java b/jest/src/test/java/io/searchbox/fields/FieldStatsIntegrationTest.java
new file mode 100644
index 00000000..4266355c
--- /dev/null
+++ b/jest/src/test/java/io/searchbox/fields/FieldStatsIntegrationTest.java
@@ -0,0 +1,46 @@
+package io.searchbox.fields;
+
+import com.google.common.collect.ImmutableMap;
+import io.searchbox.client.JestResult;
+import io.searchbox.common.AbstractIntegrationTest;
+import io.searchbox.core.DocumentResult;
+import io.searchbox.core.Index;
+import org.elasticsearch.test.ESIntegTestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.SUITE, numDataNodes = 1)
+public class FieldStatsIntegrationTest  extends AbstractIntegrationTest {
+
+    private static final String INDEX = "twitter";
+    private static final String TYPE = "tweet";
+    private static final String TEST_FIELD = "test_name";
+    private static final List FIELDS = Collections.singletonList(TEST_FIELD);
+
+    @Test
+    public void testFieldStats() throws IOException {
+
+        Map<String, String> source = ImmutableMap.of(
+                TEST_FIELD, "testFieldStats");
+
+        DocumentResult documentResult = client.execute(
+                new Index.Builder(source)
+                        .index(INDEX)
+                        .type(TYPE)
+                        .refresh(true)
+                        .build()
+        );
+
+        assertTrue(documentResult.getErrorMessage(), documentResult.isSucceeded());
+
+        FieldStats fieldStats = new FieldStats.Builder(FIELDS).setIndex(INDEX).build();
+
+        JestResult fieldStatsResult = client.execute(fieldStats);
+
+        assertTrue(fieldStatsResult.getErrorMessage(), fieldStatsResult.isSucceeded());
+    }
+}