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 <[email protected]>
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 <[email protected]>
(cherry picked from commit fd7631e4f276e175df6d04bb1513059808751c7d)
Signed-off-by: Philipp Dallig <[email protected]>
---
.../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();
}