Repository: searchbox-io/Jest
Pull request #224 (2015-07-15 00:35:12)

add support for cat actions


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
new file mode 100644
index 00000000..4c256f97
--- /dev/null
+++ b/jest-common/src/main/java/io/searchbox/core/Cat.java
@@ -0,0 +1,100 @@
+package io.searchbox.core;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import io.searchbox.action.AbstractAction;
+import io.searchbox.action.AbstractMultiIndexActionBuilder;
+import io.searchbox.action.AbstractMultiTypeActionBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * @author Bartosz Polnik
+ */
+public class Cat extends AbstractAction<CatResult> {
+    private final static String PATH_TO_RESULT = "result";
+    private final String operationPath;
+
+    protected <T extends AbstractAction.Builder<Cat, ? extends Builder> & CatBuilder> Cat(T builder) {
+        super(builder);
+        this.operationPath = builder.operationPath();
+        setURI(buildURI());
+    }
+
+    @Override
+    protected String buildURI() {
+        String uriSuffix = super.buildURI();
+        return "_cat/" + this.operationPath + (uriSuffix.isEmpty() ? "" : "/") + uriSuffix;
+    }
+
+    @Override
+    public String getRestMethodName() {
+        return "GET";
+    }
+
+    @Override
+    public String getPathToResult() {
+        return PATH_TO_RESULT;
+    }
+
+    @Override
+    public CatResult createNewElasticSearchResult(String responseBody, int statusCode, String reasonPhrase, Gson gson) {
+        return createNewElasticSearchResult(new CatResult(gson), responseBody, statusCode, reasonPhrase, gson);
+    }
+
+    @Override
+    protected JsonObject parseResponseBody(String responseBody) {
+        JsonObject result = new JsonObject();
+        if (responseBody != null && !responseBody.trim().isEmpty()) {
+            result.add(PATH_TO_RESULT, new JsonParser().parse(responseBody).getAsJsonArray());
+        }
+
+        return result;
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder()
+                .append(super.hashCode())
+                .toHashCode();
+    }
+
+    public static class IndicesBuilder extends AbstractMultiTypeActionBuilder<Cat, IndicesBuilder> implements CatBuilder {
+        private static final String operationPath = "indices";
+
+        public IndicesBuilder() {
+            setHeader("content-type", "application/json");
+        }
+
+        @Override
+        public Cat build() {
+            return new Cat(this);
+        }
+
+        @Override
+        public String operationPath() {
+            return operationPath;
+        }
+    }
+
+    public static class AliasesBuilder extends AbstractMultiIndexActionBuilder<Cat, AliasesBuilder> implements CatBuilder {
+        private static final String operationPath = "aliases";
+        public AliasesBuilder() {
+            setHeader("content-type", "application/json");
+        }
+
+        @Override
+        public Cat build() {
+            return new Cat(this);
+        }
+
+        @Override
+        public String operationPath() {
+            return operationPath;
+        }
+    }
+
+    protected interface CatBuilder {
+        String operationPath();
+    }
+}
diff --git a/jest-common/src/main/java/io/searchbox/core/CatResult.java b/jest-common/src/main/java/io/searchbox/core/CatResult.java
new file mode 100644
index 00000000..790e6608
--- /dev/null
+++ b/jest-common/src/main/java/io/searchbox/core/CatResult.java
@@ -0,0 +1,61 @@
+package io.searchbox.core;
+
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.searchbox.client.JestResult;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+* @author Bartosz Polnik
+*/
+public class CatResult extends JestResult {
+
+    public CatResult(CatResult catResult) {
+        super(catResult);
+    }
+
+    public CatResult(Gson gson) {
+        super(gson);
+    }
+
+    /**
+     *
+     * @return empty array if response is not present, otherwise column names as first row plus one additional row per single result
+     */
+    public String[][] getPlainText() {
+        JsonObject jsonObject = getJsonObject();
+        if(jsonObject != null && jsonObject.has(getPathToResult()) && jsonObject.get(getPathToResult()).isJsonArray()) {
+            JsonArray esResultRows = jsonObject.get(getPathToResult()).getAsJsonArray();
+            if(esResultRows.size() > 0 && esResultRows.get(0).isJsonObject()) {
+                return parseResultArray(esResultRows);
+            }
+        }
+
+        return new String[0][0];
+    }
+
+    private String[][] parseResultArray(JsonArray esResponse) {
+        List<Map.Entry<String, JsonElement>> fieldsInFirstResponseRow = Lists.newArrayList(esResponse.get(0).getAsJsonObject().entrySet());
+        String[][] result = new String[esResponse.size() + 1][fieldsInFirstResponseRow.size()];
+        for(int i = 0; i < fieldsInFirstResponseRow.size(); i++) {
+            result[0][i] = fieldsInFirstResponseRow.get(i).getKey();
+        }
+
+        int rowNum = 1;
+        for(JsonElement row: esResponse) {
+            JsonObject currentObj = row.getAsJsonObject();
+            for (int colId = 0; colId < fieldsInFirstResponseRow.size(); colId++) {
+                result[rowNum][colId] = currentObj.get(result[0][colId]).getAsString();
+            }
+
+            rowNum++;
+        }
+
+        return result;
+    }
+}


Test patch:
diff --git a/jest-common/src/test/java/io/searchbox/core/CatAliasesBuilderTest.java b/jest-common/src/test/java/io/searchbox/core/CatAliasesBuilderTest.java
new file mode 100644
index 00000000..2b58a9ba
--- /dev/null
+++ b/jest-common/src/test/java/io/searchbox/core/CatAliasesBuilderTest.java
@@ -0,0 +1,34 @@
+package io.searchbox.core;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Bartosz Polnik
+ */
+public class CatAliasesBuilderTest {
+    @Test
+    public void shouldSetApplicationJsonHeader() {
+        Cat cat = new Cat.AliasesBuilder().build();
+        assertEquals("application/json", cat.getHeader("content-type"));
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexNotGiven() {
+        Cat cat = new Cat.AliasesBuilder().build();
+        assertEquals("_cat/aliases/_all", cat.getURI());
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexGiven() {
+        Cat cat = new Cat.AliasesBuilder().addIndex("testIndex").build();
+        assertEquals("_cat/aliases/testIndex", cat.getURI());
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenParameterGiven() {
+        Cat cat = new Cat.AliasesBuilder().setParameter("v", "true").build();
+        assertEquals("_cat/aliases/_all?v=true", cat.getURI());
+    }
+}
diff --git a/jest-common/src/test/java/io/searchbox/core/CatIndicesBuilderTest.java b/jest-common/src/test/java/io/searchbox/core/CatIndicesBuilderTest.java
new file mode 100644
index 00000000..aba3bff6
--- /dev/null
+++ b/jest-common/src/test/java/io/searchbox/core/CatIndicesBuilderTest.java
@@ -0,0 +1,40 @@
+package io.searchbox.core;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Bartosz Polnik
+ */
+public class CatIndicesBuilderTest {
+    @Test
+    public void shouldSetApplicationJsonHeader() {
+        Cat cat = new Cat.IndicesBuilder().build();
+        assertEquals("application/json", cat.getHeader("content-type"));
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexNotGiven() {
+        Cat cat = new Cat.IndicesBuilder().build();
+        assertEquals("_cat/indices/_all", cat.getURI());
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexGiven() {
+        Cat cat = new Cat.IndicesBuilder().addIndex("testIndex").build();
+        assertEquals("_cat/indices/testIndex", cat.getURI());
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenIndexAndTypeGiven() {
+        Cat cat = new Cat.IndicesBuilder().addIndex("testIndex").addType("testType").build();
+        assertEquals("_cat/indices/testIndex/testType", cat.getURI());
+    }
+
+    @Test
+    public void shouldGenerateValidUriWhenParameterGiven() {
+        Cat cat = new Cat.IndicesBuilder().setParameter("v", "true").build();
+        assertEquals("_cat/indices/_all?v=true", cat.getURI());
+    }
+}
diff --git a/jest-common/src/test/java/io/searchbox/core/CatResultTest.java b/jest-common/src/test/java/io/searchbox/core/CatResultTest.java
new file mode 100644
index 00000000..e7d0538a
--- /dev/null
+++ b/jest-common/src/test/java/io/searchbox/core/CatResultTest.java
@@ -0,0 +1,64 @@
+package io.searchbox.core;
+
+import com.google.gson.Gson;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * @author Bartosz Polnik
+ */
+public class CatResultTest {
+    private final String EXAMPLE_RESPONSE_TWO_ROWS = "[\n" +
+            "    {\n" +
+            "        \"alias\": \"testAlias\",\n" +
+            "        \"index\": \"testIndex\",\n" +
+            "        \"filter\": \"-\"\n" +
+            "    },\n" +
+            "    {\n" +
+            "        \"alias\": \"testAlias2\",\n" +
+            "        \"filter\": \"-\",\n" +
+            "        \"index\": \"testIndex2\"\n" +
+            "    }\n" +
+            "]";
+
+    private final String EXAMPLE_RESPONSE_SINGLE_ROWS = "[\n" +
+            "    {\n" +
+            "        \"alias\": \"testAlias\",\n" +
+            "        \"index\": \"testIndex\",\n" +
+            "        \"filter\": \"-\"\n" +
+            "    }" +
+            "]";
+
+    @Test
+    public void shouldReturnEmptyArrayOnNoJsonObject() {
+        CatResult catResult = new CatResult(new Gson());
+        assertArrayEquals(new String[0][0], catResult.getPlainText());
+    }
+
+    @Test
+      public void shouldReturnArrayWithColumnNamesAndSingleResult() {
+        Cat cat = new Cat.IndicesBuilder().build();
+        String reasonPhase = StringUtils.EMPTY;
+        CatResult catResult = cat.createNewElasticSearchResult(EXAMPLE_RESPONSE_SINGLE_ROWS, 200, reasonPhase, new Gson());
+
+        assertArrayEquals(new String[][]{
+                new String[]{"alias", "index", "filter"},
+                new String[]{"testAlias", "testIndex", "-"}
+        }, catResult.getPlainText());
+    }
+
+    @Test
+    public void shouldReturnArrayWithTwoResultsEventWhenColumnsWereReordered() {
+        Cat cat = new Cat.IndicesBuilder().build();
+        String reasonPhase = StringUtils.EMPTY;
+        CatResult catResult = cat.createNewElasticSearchResult(EXAMPLE_RESPONSE_TWO_ROWS, 200, reasonPhase, new Gson());
+
+        assertArrayEquals(new String[][]{
+                new String[]{"alias", "index", "filter"},
+                new String[]{"testAlias", "testIndex", "-"},
+                new String[]{"testAlias2", "testIndex2", "-"}
+        }, catResult.getPlainText());
+    }
+}
diff --git a/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java b/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java
new file mode 100644
index 00000000..bd106262
--- /dev/null
+++ b/jest/src/test/java/io/searchbox/core/CatIntegrationTest.java
@@ -0,0 +1,76 @@
+package io.searchbox.core;
+
+import com.google.gson.JsonArray;
+import io.searchbox.common.AbstractIntegrationTest;
+import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction;
+import org.elasticsearch.test.ElasticsearchIntegrationTest;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * @author Bartosz Polnik
+ */
+@ElasticsearchIntegrationTest.ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST, numDataNodes = 1)
+public class CatIntegrationTest extends AbstractIntegrationTest {
+    final static String INDEX = "catintegrationindex";
+    final static String ALIAS = "catintegrationslias";
+    final static String INDEX2 = "catintegrationindex2";
+
+    @Test
+    public void shouldReturnEmptyPlainTextForIndices() throws IOException {
+        CatResult result = client.execute(new Cat.IndicesBuilder().build());
+        assertEquals(new JsonArray(), result.getJsonObject().get(result.getPathToResult()));
+        assertArrayEquals(new String[0][0], result.getPlainText());
+    }
+
+    @Test
+    public void shouldProperlyMapSingleResult() throws IOException {
+        createIndex(INDEX);
+        ensureSearchable(INDEX);
+
+        CatResult result = client.execute(new Cat.IndicesBuilder().setParameter("h", "index,docs.count").build());
+        assertArrayEquals(new String[][]{
+                new String[]{"index", "docs.count"},
+                new String[]{INDEX, "0"},
+        }, result.getPlainText());
+    }
+
+    @Test
+    public void shouldFilterResultsToASingleIndex() throws IOException {
+        createIndex(INDEX, INDEX2);
+        ensureSearchable(INDEX, INDEX2);
+
+        CatResult result = client.execute(new Cat.IndicesBuilder().setParameter("h", "index,docs.count").addIndex(INDEX2).build());
+        assertArrayEquals(new String[][]{
+                new String[]{"index", "docs.count"},
+                new String[]{INDEX2, "0"},
+        }, result.getPlainText());
+    }
+
+    @Test
+    public void shouldDisplayAliasForSingleResult() throws IOException {
+        createIndex(INDEX);
+        ensureSearchable(INDEX);
+        IndicesAliasesAction.INSTANCE.newRequestBuilder(client().admin().indices()).addAlias(INDEX, ALIAS).get();
+
+        CatResult result = client.execute(new Cat.AliasesBuilder().setParameter("h", "alias,index").build());
+        assertArrayEquals(new String[][]{
+                new String[]{"alias", "index"},
+                new String[]{ALIAS, INDEX},
+        }, result.getPlainText());
+    }
+
+    @Test
+    public void shouldChangeOrderOfColumnsByspecifyingParameters() throws IOException {
+        createIndex(INDEX);
+        ensureSearchable(INDEX);
+        IndicesAliasesAction.INSTANCE.newRequestBuilder(client().admin().indices()).addAlias(INDEX, ALIAS).get();
+
+        CatResult result = client.execute(new Cat.AliasesBuilder().setParameter("h", "index,alias").build());
+        assertArrayEquals(new String[][]{
+                new String[]{"index", "alias"},
+                new String[]{INDEX, ALIAS},
+        }, result.getPlainText());
+    }
+}
diff --git a/jest/src/test/java/io/searchbox/indices/type/TypeExistIntegrationTest.java b/jest/src/test/java/io/searchbox/indices/type/TypeExistIntegrationTest.java
index bcd0150c..25eb00f5 100644
--- a/jest/src/test/java/io/searchbox/indices/type/TypeExistIntegrationTest.java
+++ b/jest/src/test/java/io/searchbox/indices/type/TypeExistIntegrationTest.java
@@ -18,24 +18,27 @@ import java.io.IOException;
 public class TypeExistIntegrationTest extends AbstractIntegrationTest {
 
     static final String INDEX_NAME = "it_typexst_0";
-    static final String INDEX_TYPE = "ittyp";
+    static final String EXISTING_INDEX_TYPE = "ittypex";
+    static final String NON_EXISTING_INDEX_TYPE = "ittypnonex";
 
     @Before
     public void setup() {
-        createIndex(INDEX_NAME);
+        prepareCreate(INDEX_NAME)
+                .addMapping(EXISTING_INDEX_TYPE)
+                .execute();
         ensureSearchable(INDEX_NAME);
     }
 
     @Test
     public void indexTypeExists() throws IOException, InterruptedException {
         IndexResponse indexResponse = client().index(
-                new IndexRequest(INDEX_NAME, INDEX_TYPE)
+                new IndexRequest(INDEX_NAME, EXISTING_INDEX_TYPE)
                         .source("{\"user\":\"tweety\"}")
                         .refresh(true)
         ).actionGet();
         assertTrue(indexResponse.isCreated());
 
-        Action typeExist = new TypeExist.Builder(INDEX_NAME).addType(INDEX_TYPE).build();
+        Action typeExist = new TypeExist.Builder(INDEX_NAME).addType(EXISTING_INDEX_TYPE).build();
         JestResult result = client.execute(typeExist);
 
         assertTrue(result.getErrorMessage(), result.isSucceeded());
@@ -43,7 +46,7 @@ public class TypeExistIntegrationTest extends AbstractIntegrationTest {
 
     @Test
     public void indexTypeNotExists() throws IOException {
-        Action typeExist = new TypeExist.Builder(INDEX_NAME).addType(INDEX_TYPE).build();
+        Action typeExist = new TypeExist.Builder(INDEX_NAME).addType(NON_EXISTING_INDEX_TYPE).build();
 
         JestResult result = client.execute(typeExist);
         assertFalse(result.isSucceeded());