Repository: searchbox-io/Jest
Pull request #630 (2018-11-30 16:01:08)

Bucket aggregation getBuckets() should be public.
Otherwise, if you're desigining APIs that work with any BucketAggregation subclass, you don't have a way without using things like reflection to get the buckets, keys, and counts regardless of specific aggregation type.

Signed-off-by: John Dimeo <dimeo@elderresearch.com>

coveralls: 
[![Coverage Status](https://coveralls.io/builds/20386257/badge)](https://coveralls.io/builds/20386257)

Coverage remained the same at 58.041% when pulling **495cc1fc8c16b4ebe400d4d81e3b0a8a7813b2b5 on ElderResearch:master** into **42f0a97acc45582baf5e8ecd7ccbbc5ac0c111fc on searchbox-io:master**.


Patch:
diff --git a/README.md b/README.md
index 1ca59b03..332e63ee 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Jest is a Java HTTP Rest client for [ElasticSearch][es].
 
 ElasticSearch is an Open Source (Apache 2), Distributed, RESTful, Search Engine built on top of Apache Lucene.
 
-ElasticSearch already has a Java API which is also used by ElasticSearch internally, [but Jest fills a gap, it is the missing client for ElasticSearch Http Rest interface](#comparison-to-native-api).
+ElasticSearch already has a Java API which is also used by ElasticSearch internally, [but Jest fills a gap, it is the missing client for ElasticSearch Http Rest interface](jest/README.md#comparison-to-native-api).
 
 >Read great [introduction][ibm] to ElasticSearch and Jest from IBM Developer works.
 
diff --git a/jest-common/src/main/java/io/searchbox/client/JestResult.java b/jest-common/src/main/java/io/searchbox/client/JestResult.java
index 0f7307f6..00e28db8 100644
--- a/jest-common/src/main/java/io/searchbox/client/JestResult.java
+++ b/jest-common/src/main/java/io/searchbox/client/JestResult.java
@@ -267,8 +267,7 @@ public class JestResult {
         T obj = null;
         try {
 
-            String json = source.toString();
-            obj = gson.fromJson(json, type);
+            obj = gson.fromJson(source, type);
 
             // Check if JestId is visible
             Class clazz = type;
diff --git a/jest-common/src/main/java/io/searchbox/core/Bulk.java b/jest-common/src/main/java/io/searchbox/core/Bulk.java
index ee6b2498..cb28f704 100644
--- a/jest-common/src/main/java/io/searchbox/core/Bulk.java
+++ b/jest-common/src/main/java/io/searchbox/core/Bulk.java
@@ -155,6 +155,16 @@ public class Bulk extends AbstractAction<BulkResult> {
         return result;
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj) && Objects.equals(bulkableActions, ((Bulk) obj).bulkableActions);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), this.bulkableActions);
+    }
+
     public static class Builder extends GenericResultAbstractAction.Builder<Bulk, Builder> {
         private List<BulkableAction> actions = new LinkedList<BulkableAction>();
         private String defaultIndex;
diff --git a/jest-common/src/main/java/io/searchbox/core/Update.java b/jest-common/src/main/java/io/searchbox/core/Update.java
index 5bcdb1c8..d44888ff 100644
--- a/jest-common/src/main/java/io/searchbox/core/Update.java
+++ b/jest-common/src/main/java/io/searchbox/core/Update.java
@@ -1,5 +1,6 @@
 package io.searchbox.core;
 
+import com.google.gson.Gson;
 import io.searchbox.action.BulkableAction;
 import io.searchbox.action.SingleResultAbstractDocumentTargetedAction;
 import io.searchbox.client.config.ElasticsearchVersion;
@@ -11,9 +12,15 @@ import io.searchbox.params.Parameters;
  */
 public class Update extends SingleResultAbstractDocumentTargetedAction implements BulkableAction<DocumentResult> {
 
+    private enum Method {doc, script}
+
+    private static final String DOC_UPDATE_TEMPLATE = "{\"%s\": %s}";
+    private final Method method;
+
     protected Update(Builder builder) {
         super(builder);
         this.payload = builder.payload;
+        this.method = builder.method;
     }
 
     @Override
@@ -36,11 +43,28 @@ public class Update extends SingleResultAbstractDocumentTargetedAction implement
         return "ok";
     }
 
+    @Override
+    public String getData(Gson gson) {
+        String data = super.getData(gson);
+        if (method == null) {
+            return data;
+        } else {
+            return String.format(DOC_UPDATE_TEMPLATE, method.name(), data);
+        }
+    }
+
     public static class Builder extends SingleResultAbstractDocumentTargetedAction.Builder<Update, Builder> {
+
         private final Object payload;
+        private final Method method;
 
         public Builder(Object payload) {
+            this(payload, null);
+        }
+
+        private Builder(Object payload, Method method) {
             this.payload = payload;
+            this.method = method;
         }
 
         public Update build() {
@@ -49,9 +73,24 @@ public class Update extends SingleResultAbstractDocumentTargetedAction implement
     }
 
     public static class VersionBuilder extends Builder {
+
         public VersionBuilder(Object payload, Long version) {
             super(payload);
             this.setParameter(Parameters.VERSION, version);
         }
     }
+
+    public static class DocBuilder extends Builder {
+
+        public DocBuilder(Object payload) {
+            super(payload, Method.doc);
+        }
+    }
+
+    public static class ScriptBuilder extends Builder {
+
+        public ScriptBuilder(Object payload) {
+            super(payload, Method.script);
+        }
+    }
 }
diff --git a/jest-common/src/main/java/io/searchbox/core/search/aggregation/BucketAggregation.java b/jest-common/src/main/java/io/searchbox/core/search/aggregation/BucketAggregation.java
index 35ebb3d8..2739d32c 100644
--- a/jest-common/src/main/java/io/searchbox/core/search/aggregation/BucketAggregation.java
+++ b/jest-common/src/main/java/io/searchbox/core/search/aggregation/BucketAggregation.java
@@ -13,5 +13,5 @@ public abstract class BucketAggregation extends Aggregation {
         super(name, root);
     }
 
-    abstract List<? extends Bucket> getBuckets();
+    public abstract List<? extends Bucket> getBuckets();
 }


Test patch:
diff --git a/jest-common/src/test/java/io/searchbox/core/BulkTest.java b/jest-common/src/test/java/io/searchbox/core/BulkTest.java
index c4a8f98a..e64ce365 100644
--- a/jest-common/src/test/java/io/searchbox/core/BulkTest.java
+++ b/jest-common/src/test/java/io/searchbox/core/BulkTest.java
@@ -1,7 +1,9 @@
 package io.searchbox.core;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -109,6 +111,42 @@ public class BulkTest {
         assertEquals("twitter/tweet/_bulk", bulkWitIndexAndType.getURI(ElasticsearchVersion.UNKNOWN));
     }
 
+    @Test
+    public void testEqualsWithUnequalActions() {
+        final String index = "twitter";
+        final String type = "tweet";
+
+        final Object leftPayload = Collections.singletonMap("field", "value");
+        final Update leftAction = new Update.Builder(leftPayload).build();
+        final Bulk left = new Bulk.Builder()
+                .addAction(leftAction).defaultIndex(index).defaultType(type)
+                .build();
+
+        final Bulk right = new Bulk.Builder()
+                .defaultIndex(index).defaultType(type)
+                .build();
+
+        assertNotEquals(left, right);
+    }
+
+    @Test
+    public void testHashCodeWithUnequalActions() {
+        final String index = "twitter";
+        final String type = "tweet";
+
+        final Object leftPayload = Collections.singletonMap("field", "value");
+        final Update leftAction = new Update.Builder(leftPayload).build();
+        final Bulk left = new Bulk.Builder()
+                .addAction(leftAction).defaultIndex(index).defaultType(type)
+                .build();
+
+        final Bulk right = new Bulk.Builder()
+                .defaultIndex(index).defaultType(type)
+                .build();
+
+        assertNotEquals(left.hashCode(), right.hashCode());
+    }
+
     private void executeAsserts(Bulk bulk) {
         assertEquals("POST", bulk.getRestMethodName());
         assertEquals("/_bulk", bulk.getURI(ElasticsearchVersion.UNKNOWN));
diff --git a/jest/src/test/java/io/searchbox/core/UpdateIntegrationTest.java b/jest/src/test/java/io/searchbox/core/UpdateIntegrationTest.java
index 16bce1b0..04c83a0c 100644
--- a/jest/src/test/java/io/searchbox/core/UpdateIntegrationTest.java
+++ b/jest/src/test/java/io/searchbox/core/UpdateIntegrationTest.java
@@ -51,6 +51,35 @@ public class UpdateIntegrationTest extends AbstractIntegrationTest {
         assertEquals("That is testblue", getResult.getSource().get("tags"));
     }
 
+    @Test
+    public void scriptedUpdateWithValidParametersUsingScriptBuilder() throws Exception {
+        String id = "1";
+        String script = "{\n" +
+                "  \"lang\": \"painless\",\n" +
+                "  \"inline\": \"ctx._source.tags += params.tag\",\n" +
+                "  \"params\": {\n" +
+                "    \"tag\": \"blue\"\n" +
+                "  }\n" +
+                "}";
+
+        client().index(
+                new IndexRequest(INDEX, TYPE, id)
+                        .source("{\"user\":\"kimchy\", \"tags\":\"That is test\"}", XContentType.JSON)
+                        .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
+        ).actionGet();
+
+        DocumentResult result = client.execute(new Update.ScriptBuilder(script).index(INDEX).type(TYPE).id(id).build());
+        assertTrue(result.getErrorMessage(), result.isSucceeded());
+        assertEquals(INDEX, result.getIndex());
+        assertEquals(TYPE, result.getType());
+        assertEquals(id, result.getId());
+
+        GetResponse getResult = get(INDEX, TYPE, id);
+        assertTrue(getResult.isExists());
+        assertFalse(getResult.isSourceEmpty());
+        assertEquals("That is testblue", getResult.getSource().get("tags"));
+    }
+
     @Test
     public void partialDocUpdateWithValidParameters() throws Exception {
         String id = "2";
@@ -78,6 +107,31 @@ public class UpdateIntegrationTest extends AbstractIntegrationTest {
         assertEquals("blue", getResult.getSource().get("tags"));
     }
 
+    @Test
+    public void partialDocUpdateWithValidParametersUsingDocBuilder() throws Exception {
+        String id = "2";
+        String partialDoc = "{\n" +
+                "  \"tags\" : \"blue\"\n" +
+                "}";
+
+        client().index(
+                new IndexRequest(INDEX, TYPE, id)
+                        .source("{\"user\":\"kimchy\", \"tags\":\"That is test\"}", XContentType.JSON)
+                        .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
+        ).actionGet();
+
+        DocumentResult result = client.execute(new Update.DocBuilder(partialDoc).index(INDEX).type(TYPE).id(id).build());
+        assertTrue(result.getErrorMessage(), result.isSucceeded());
+        assertEquals(INDEX, result.getIndex());
+        assertEquals(TYPE, result.getType());
+        assertEquals(id, result.getId());
+
+        GetResponse getResult = get(INDEX, TYPE, id);
+        assertTrue(getResult.isExists());
+        assertFalse(getResult.isSourceEmpty());
+        assertEquals("blue", getResult.getSource().get("tags"));
+    }
+
     @Test
     public void partialDocUpdateWithValidVersion() throws Exception {
         String id = "2";