This is an automated email from the ASF dual-hosted git repository.

pdallig pushed a commit to branch branch-0.12
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/branch-0.12 by this push:
     new f632ca27b8 [ZEPPELIN-6192] Enhance getHit() safety in ActionResponse 
and improve interface documentation
f632ca27b8 is described below

commit f632ca27b88eab52d91e150bf7d5a10bff99f132
Author: Gyeongtae Park <67095975+parkgyeong...@users.noreply.github.com>
AuthorDate: Fri Jun 27 05:05:51 2025 +0900

    [ZEPPELIN-6192] Enhance getHit() safety in ActionResponse and improve 
interface documentation
    
    ### What is this PR for?
    This PR improves the robustness and clarity of the Elasticsearch 
interpreter module in Zeppelin.
    - Reimplemented `ActionResponse#getHit()` to throw `NoSuchElementException` 
instead of relying on unchecked access to the first hit.
    - Introduced a new method `getFirstHit()` which returns an 
`Optional<HitWrapper>` for safer optional access.
    - Added and refined Javadoc comments in:
      - `ActionResponse.java` for both `getHit()` and `getFirstHit()`
      - `ElasticsearchClient.java` to improve clarity on interface usage
    
    ### What type of PR is it?
    Documentation
    Refactoring
    
    ### Todos
    * [x] Refactor `getHit()` to throw a safe exception
    * [x] Add `getFirstHit()` method using `Optional`
    
    ### What is the Jira issue?
    * https://issues.apache.org/jira/browse/ZEPPELIN/ZEPPELIN-6192
    
    ### How should this be tested?
    * Build Test
    * Elasticsearch Interpreter Test
    
    ### Screenshots (if appropriate)
    
    ### Questions:
    * Does the license files need to update? No.
    * Is there breaking changes for older versions? No.
    * Does this needs documentation? No.
    
    Closes #4940 from ParkGyeongTae/enhance-getHit-safety.
    
    Signed-off-by: Philipp Dallig <philipp.dal...@gmail.com>
    (cherry picked from commit fd7631e4f276e175df6d04bb1513059808751c7d)
    Signed-off-by: Philipp Dallig <philipp.dal...@gmail.com>
---
 .../elasticsearch/action/ActionResponse.java       | 36 +++++++++++++-
 .../elasticsearch/client/ElasticsearchClient.java  | 55 +++++++++++++++++++++-
 2 files changed, 88 insertions(+), 3 deletions(-)

diff --git 
a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/action/ActionResponse.java
 
b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/action/ActionResponse.java
index 4141bce661..6ede07fde1 100644
--- 
a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/action/ActionResponse.java
+++ 
b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/action/ActionResponse.java
@@ -19,9 +19,22 @@ package org.apache.zeppelin.elasticsearch.action;
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
 
 /**
- * Contains the result of an action (hits, aggregations, ...).
+ * A response object representing the result of an Elasticsearch action
+ * (such as document retrieval, search, or aggregation).
+ *
+ * <p>
+ * This class is used internally by the Zeppelin Elasticsearch interpreter
+ * to store the result of interactions with Elasticsearch.
+ * It holds basic metadata like success status, total number of hits,
+ * a list of search hits, and a list of aggregations.
+ * </p>
+ *
+ * @see HitWrapper
+ * @see AggWrapper
  */
 public class ActionResponse {
 
@@ -72,7 +85,26 @@ public class ActionResponse {
     return this;
   }
 
+  /**
+   * Returns the first hit in the search result.
+   *
+   * @return the first {@link HitWrapper} in the list
+   * @throws NoSuchElementException if there are no hits in the response
+   */
   public HitWrapper getHit() {
-    return this.hits.get(0);
+    return getFirstHit()
+        .orElseThrow(() -> new NoSuchElementException("No hit found in 
ActionResponse"));
+  }
+
+  /**
+   * Returns the first hit in the search result, if it exists.
+   *
+   * <p>If there are no hits, returns {@code Optional.empty()}.</p>
+   *
+   * @return an {@code Optional} containing the first {@link HitWrapper}, or 
empty if the hit
+   * list is empty
+   */
+  public Optional<HitWrapper> getFirstHit() {
+    return hits.isEmpty() ? Optional.empty() : Optional.of(hits.get(0));
   }
 }
diff --git 
a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClient.java
 
b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClient.java
index 48e1980610..e503773573 100644
--- 
a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClient.java
+++ 
b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClient.java
@@ -20,17 +20,70 @@ package org.apache.zeppelin.elasticsearch.client;
 import org.apache.zeppelin.elasticsearch.action.ActionResponse;
 
 /**
- * Interface that must be implemented by any kind of Elasticsearch client 
(transport, ...).
+ * Interface defining a contract for Elasticsearch client implementations.
+ * <p>
+ * Implementations may use Transport Client (deprecated), High Level REST 
Client,
+ * or the new Elasticsearch Java API Client.
+ * </p>
+ *
+ * <p>
+ * This interface is intended to abstract the underlying Elasticsearch 
connection
+ * mechanism, allowing Zeppelin interpreters to interact with different 
versions
+ * of Elasticsearch transparently.
+ * </p>
+ *
+ * @see org.apache.zeppelin.elasticsearch.action.ActionResponse
  */
 public interface ElasticsearchClient {
 
+  /**
+   * Retrieves a document by its ID.
+   *
+   * @param index The index name.
+   * @param type  The document type. (Note: deprecated in Elasticsearch 7+, 
use "_doc")
+   * @param id    The unique document ID.
+   * @return The response containing the document if found, or an error 
response.
+   */
   ActionResponse get(String index, String type, String id);
 
+  /**
+   * Indexes a document (insert or update).
+   *
+   * @param index The index name.
+   * @param type  The document type.
+   * @param id    The document ID. If null, a random ID may be generated 
depending on
+   *              implementation.
+   * @param data  The JSON string of the document to index.
+   * @return The response indicating success or failure.
+   */
   ActionResponse index(String index, String type, String id, String data);
 
+  /**
+   * Deletes a document by its ID.
+   *
+   * @param index The index name.
+   * @param type  The document type.
+   * @param id    The document ID to delete.
+   * @return The response indicating result of the deletion.
+   */
   ActionResponse delete(String index, String type, String id);
 
+  /**
+   * Executes a search query on one or more indices and types.
+   *
+   * @param indices Array of index names to search.
+   * @param types   Array of document types to search (can be null or ["_doc"] 
in ES 7+).
+   * @param query   The raw JSON query string.
+   * @param size    Maximum number of documents to return.
+   * @return The response containing the search hits.
+   */
   ActionResponse search(String[] indices, String[] types, String query, int 
size);
 
+  /**
+   * Closes any open connections and cleans up resources.
+   * <p>
+   * Must be called when the client is no longer needed.
+   * </p>
+   */
   void close();
 }

Reply via email to