Skip to content

Conversation

@Swiddis
Copy link
Collaborator

@Swiddis Swiddis commented Dec 9, 2025

Description

Removes all uses of AccessController, which is deprecated since version 3.0. Finishing what #4900 started.

Related Issues

N/A

Check List

  • New functionality includes testing.
  • New functionality has been documented.
  • New functionality has javadoc added.
  • New functionality has a user manual doc added.
  • New PPL command checklist all confirmed.
  • API changes companion pull request created.
  • Commits are signed per the DCO using --signoff or -s.
  • Public documentation issue/PR created.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Signed-off-by: Simeon Widdis <[email protected]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Simplified internal code structure across multiple components for improved maintainability. No changes to public APIs or user-facing functionality. All error handling and behavior remain equivalent to previous versions.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Removed java.security AccessController.doPrivileged / PrivilegedAction wrappers across many modules, replacing them with direct method calls and standard try-catch error handling while keeping public signatures, logging, metrics, and exception mapping intact.

Changes

Cohort / File(s) Summary
EMR Serverless client management
async-query-core/.../EMRServerlessClientFactoryImpl.java, async-query-core/.../EmrServerlessClientImpl.java
Remove privileged wrappers for client construction and job operations; use direct builders/calls and try-catch blocks; preserve logging, metrics, and exception mapping.
Spark & async config
async-query/.../SparkExecutionEngineConfigClusterSettingLoader.java
Call cluster-setting conversion directly instead of via privileged action.
Core query execution
core/.../QueryService.java
Remove doPrivileged around executeWithCalcite and explainWithCalcite; build/analyze/execute plans directly while retaining fallback and exception paths.
Direct-query & Prometheus client/utils
direct-query-core/.../PrometheusQueryHandler.java, direct-query-core/.../PrometheusClientUtils.java, direct-query/.../ExecuteDirectQueryActionResponse.java
Eliminate privileged blocks for Prometheus operations, OkHttpClient construction, and (de)serialization; use direct client/ObjectMapper calls with try-catch.
Prometheus scanning & storage
prometheus/.../QueryExemplarsFunctionTableScanOperator.java, prometheus/.../QueryRangeFunctionTableScanOperator.java, prometheus/.../PrometheusDescribeMetricRequest.java, prometheus/.../PrometheusListMetricsRequest.java, prometheus/.../PrometheusMetricScan.java, prometheus/.../PrometheusStorageFactory.java
Replace privileged execution for various Prometheus queries and storage creation with direct invocations and equivalent error handling.
OpenSearch execution & security
opensearch/.../OpenSearchExecutionEngine.java, opensearch/.../security/SecurityAccess.java, opensearch/.../storage/script/core/ExpressionScript.java
Remove privileged wrappers around OpenSearch execution and script evaluation; delete SecurityAccess helper class; call operations directly.
Response formatting / protocol
protocol/.../ErrorFormatter.java, protocol/.../JsonResponseFormatter.java, protocol/.../YamlResponseFormatter.java
Initialize and invoke Gson/YAML formatters directly (no privileged actions) and call toJson/format methods without security-wrapper.
Legacy serialization & cursors
legacy/.../DefaultCursor.java
Replace privileged JSON (de)serialization of sortFields with direct ObjectMapper try-catch usage.
Plugin / PPL / tests
legacy/.../RestSQLQueryAction.java, plugin/.../TransportPPLQueryAction.java, integ-test/.../CalcitePPLIntegTestCase.java, integ-test/.../StandaloneIT.java
Remove SecurityAccess.doPrivileged wrappers when obtaining services from injector; use direct injector.getInstance calls.
Tests update
prometheus/src/test/.../PrometheusStorageFactoryTest.java
Adjusted two test URIs from https://test.com to https://opensearch.org.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Pay attention to consistent exception mapping (e.g., ValidationException → IllegalArgumentException, IOException → RuntimeException).
  • Verify logging and metrics increments (EMR/Prometheus) remained identical after removal of privileged blocks.
  • Check for removed imports or compilation warnings caused by deletion of SecurityAccess and security-related imports.

Possibly related PRs

Suggested reviewers

  • ps48
  • kavithacm
  • penghuo
  • derek-ho
  • joshuali925
  • anirudha
  • GumpacG
  • noCharger
  • yuancu
  • dai-chen
  • YANG-DB

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.32% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Remove all AccessController refs' is concise and accurately reflects the main change across the pull request—removing all uses of the deprecated AccessController.
Description check ✅ Passed The description is clearly related to the changeset, explaining that the PR removes all uses of AccessController (deprecated since version 3.0) and completes work started by PR #4900.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 574f33b and 2d35c85.

📒 Files selected for processing (5)
  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java (1 hunks)
  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java (1 hunks)
  • legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSQLQueryAction.java (1 hunks)
  • opensearch/src/main/java/org/opensearch/sql/opensearch/security/SecurityAccess.java (0 hunks)
  • plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java (1 hunks)
💤 Files with no reviewable changes (1)
  • opensearch/src/main/java/org/opensearch/sql/opensearch/security/SecurityAccess.java
🧰 Additional context used
📓 Path-based instructions (6)
**/*.java

📄 CodeRabbit inference engine (.rules/REVIEW_GUIDELINES.md)

**/*.java: Use PascalCase for class names (e.g., QueryExecutor)
Use camelCase for method and variable names (e.g., executeQuery)
Use UPPER_SNAKE_CASE for constants (e.g., MAX_RETRY_COUNT)
Keep methods under 20 lines with single responsibility
All public classes and methods must have proper JavaDoc
Use specific exception types with meaningful messages for error handling
Prefer Optional<T> for nullable returns in Java
Avoid unnecessary object creation in loops
Use StringBuilder for string concatenation in loops
Validate all user inputs, especially queries
Sanitize data before logging to prevent injection attacks
Use try-with-resources for proper resource cleanup in Java
Maintain Java 11 compatibility when possible for OpenSearch 2.x
Document Calcite-specific workarounds in code

Files:

  • legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSQLQueryAction.java
  • plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java
  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java

⚙️ CodeRabbit configuration file

**/*.java: - Verify Java naming conventions (PascalCase for classes, camelCase for methods/variables)

  • Check for proper JavaDoc on public classes and methods
  • Flag redundant comments that restate obvious code
  • Ensure methods are under 20 lines with single responsibility
  • Verify proper error handling with specific exception types
  • Check for Optional usage instead of null returns
  • Validate proper use of try-with-resources for resource management

Files:

  • legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSQLQueryAction.java
  • plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java
  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
**/test/**/*.java

⚙️ CodeRabbit configuration file

**/test/**/*.java: - Verify test coverage for new business logic

  • Check test naming follows conventions (*Test.java for unit, *IT.java for integration)
  • Ensure tests are independent and don't rely on execution order
  • Validate meaningful test data that reflects real-world scenarios
  • Check for proper cleanup of test resources

Files:

  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
**/calcite/**/*.java

⚙️ CodeRabbit configuration file

**/calcite/**/*.java: - Follow existing patterns in CalciteRelNodeVisitor and CalciteRexNodeVisitor

  • Verify SQL generation and optimization paths
  • Document any Calcite-specific workarounds
  • Test compatibility with Calcite version constraints

Files:

  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
integ-test/**/*IT.java

📄 CodeRabbit inference engine (.rules/REVIEW_GUIDELINES.md)

End-to-end scenarios need integration tests in integ-test/ module

Files:

  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java

⚙️ CodeRabbit configuration file

integ-test/**/*IT.java: - Verify integration tests are in correct module (integ-test/)

  • Check tests can be run with ./gradlew :integ-test:integTest
  • Ensure proper test data setup and teardown
  • Validate end-to-end scenario coverage

Files:

  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
**/*IT.java

📄 CodeRabbit inference engine (.rules/REVIEW_GUIDELINES.md)

Name integration tests with *IT.java suffix in OpenSearch SQL

Files:

  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
**/ppl/**/*.java

⚙️ CodeRabbit configuration file

**/ppl/**/*.java: - For PPL parser changes, verify grammar tests with positive/negative cases

  • Check AST generation for new syntax
  • Ensure corresponding AST builder classes are updated
  • Validate edge cases and boundary conditions

Files:

  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
🧠 Learnings (4)
📚 Learning: 2025-12-02T17:27:55.938Z
Learnt from: CR
Repo: opensearch-project/sql PR: 0
File: .rules/REVIEW_GUIDELINES.md:0-0
Timestamp: 2025-12-02T17:27:55.938Z
Learning: Development requires JDK 21 for the OpenSearch SQL project

Applied to files:

  • plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java
  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
📚 Learning: 2025-12-02T17:27:55.938Z
Learnt from: CR
Repo: opensearch-project/sql PR: 0
File: .rules/REVIEW_GUIDELINES.md:0-0
Timestamp: 2025-12-02T17:27:55.938Z
Learning: Test SQL generation and optimization paths for Calcite integration changes

Applied to files:

  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
📚 Learning: 2025-12-02T17:27:55.938Z
Learnt from: CR
Repo: opensearch-project/sql PR: 0
File: .rules/REVIEW_GUIDELINES.md:0-0
Timestamp: 2025-12-02T17:27:55.938Z
Learning: Applies to **/*.java : Document Calcite-specific workarounds in code

Applied to files:

  • integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java
📚 Learning: 2025-12-02T17:27:55.938Z
Learnt from: CR
Repo: opensearch-project/sql PR: 0
File: .rules/REVIEW_GUIDELINES.md:0-0
Timestamp: 2025-12-02T17:27:55.938Z
Learning: Applies to **/*IT.java : Name integration tests with `*IT.java` suffix in OpenSearch SQL

Applied to files:

  • integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (29)
  • GitHub Check: security-it-linux (25)
  • GitHub Check: security-it-linux (21)
  • GitHub Check: build-linux (25, integration)
  • GitHub Check: bwc-tests-full-restart (21)
  • GitHub Check: build-linux (25, doc)
  • GitHub Check: bwc-tests-full-restart (25)
  • GitHub Check: build-linux (25, unit)
  • GitHub Check: build-linux (21, integration)
  • GitHub Check: build-linux (21, doc)
  • GitHub Check: build-linux (21, unit)
  • GitHub Check: bwc-tests-rolling-upgrade (25)
  • GitHub Check: bwc-tests-rolling-upgrade (21)
  • GitHub Check: build-windows-macos (macos-14, 25, unit)
  • GitHub Check: build-windows-macos (macos-14, 25, doc)
  • GitHub Check: build-windows-macos (macos-14, 25, integration)
  • GitHub Check: build-windows-macos (windows-latest, 25, -PbuildPlatform=windows, unit)
  • GitHub Check: build-windows-macos (windows-latest, 21, -PbuildPlatform=windows, unit)
  • GitHub Check: build-windows-macos (windows-latest, 25, -PbuildPlatform=windows, integration)
  • GitHub Check: build-windows-macos (macos-14, 21, integration)
  • GitHub Check: build-windows-macos (windows-latest, 21, -PbuildPlatform=windows, integration)
  • GitHub Check: build-windows-macos (macos-14, 21, unit)
  • GitHub Check: build-windows-macos (macos-14, 21, doc)
  • GitHub Check: security-it-windows-macos (macos-14, 21)
  • GitHub Check: security-it-windows-macos (macos-14, 25)
  • GitHub Check: security-it-windows-macos (windows-latest, 25)
  • GitHub Check: security-it-windows-macos (windows-latest, 21)
  • GitHub Check: test-sql-cli-integration (21)
  • GitHub Check: CodeQL-Scan (java)
  • GitHub Check: WhiteSource Security Check
🔇 Additional comments (4)
integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java (1)

95-95: LGTM! Direct injector call is appropriate for test initialization.

The removal of the SecurityAccess.doPrivileged wrapper simplifies the code without impacting test functionality. Exception handling via the method signature is adequate for test setup.

plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java (1)

107-107: Direct service lookup simplifies the code.

The removal of the privileged wrapper aligns with the deprecation of AccessController. Ensure that integration tests validate this change works correctly in security-enabled OpenSearch clusters, as transport actions operate in security-sensitive contexts.

integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLIntegTestCase.java (1)

101-101: LGTM! Consistent with the broader deprecation effort.

The direct injector call simplifies initialization and aligns with the removal of AccessController.doPrivileged across the codebase. Exception handling via the method signature is appropriate for test setup.

legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSQLQueryAction.java (1)

94-94: Verify security implications of removing privileged access wrapper.

The removal of the SecurityAccess.doPrivileged wrapper around injector.getInstance(SQLService.class) affects the REST-layer authorization flow. Since this code enforces Security plugin permissions on incoming SQL requests, verify that:

  1. The SecurityAccess wrapper was intentionally removed as part of a broader security refactoring (not accidentally omitted)
  2. Security plugin authorization is still enforced upstream or through an alternative mechanism
  3. Unit and integration tests confirm SQL request authorization still functions correctly
  4. This change aligns with OpenSearch's security policy for the 2.x release

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
async-query/src/main/java/org/opensearch/sql/spark/config/SparkExecutionEngineConfigClusterSettingLoader.java (1)

15-15: Update the JavaDoc to reflect removal of privilege checks.

The class-level JavaDoc mentions "with privilege check", but the AccessController wrapper has been removed in this PR. Update the documentation to accurately describe the current behavior.

Apply this diff to correct the JavaDoc:

-/** Load SparkExecutionEngineConfigClusterSetting from settings with privilege check. */
+/** Load SparkExecutionEngineConfigClusterSetting from settings. */
🧹 Nitpick comments (11)
protocol/src/main/java/org/opensearch/sql/protocol/response/format/JsonResponseFormatter.java (1)

40-43: Direct dispatch in format(Throwable) looks correct and matches prior behavior

Using the ternary on style to select prettyFormat vs compactFormat is straightforward and keeps behavior aligned with the previous privileged block, just without AccessController. This cleanly supports the PR goal of dropping SecurityManager-related code, with no change to the public API surface.

Optionally, consider adding a brief JavaDoc to this public overload (and the other format method) in a follow-up to align with the project guideline that public methods have JavaDoc, but that’s not blocking here.

prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryRangeFunctionTableScanOperator.java (1)

38-51: Preserve exception cause and log full stack trace for Prometheus query failures

The behavior change (removing AccessController) looks fine, but the current IOException handling loses useful debugging information:

  • LOG.error(e.getMessage()); logs only the message, not the stack trace.
  • The new RuntimeException is created with a formatted message but without the original cause, so upstream handlers can’t see the underlying IOException.

To improve observability and align with the guideline of meaningful error handling, consider preserving the cause and logging the full exception:

-    try {
-      JSONObject responseObject =
-          prometheusClient.queryRange(
-              request.getPromQl(),
-              request.getStartTime(),
-              request.getEndTime(),
-              request.getStep());
-      this.prometheusResponseHandle = new QueryRangeFunctionResponseHandle(responseObject);
-    } catch (IOException e) {
-      LOG.error(e.getMessage());
-      throw new RuntimeException(
-          String.format(
-              "Error fetching data from prometheus server: %s", e.getMessage()));
-    }
+    try {
+      JSONObject responseObject =
+          prometheusClient.queryRange(
+              request.getPromQl(),
+              request.getStartTime(),
+              request.getEndTime(),
+              request.getStep());
+      this.prometheusResponseHandle = new QueryRangeFunctionResponseHandle(responseObject);
+    } catch (IOException e) {
+      LOG.error("Error fetching data from Prometheus server", e);
+      throw new RuntimeException("Error fetching data from Prometheus server", e);
+    }

This keeps the behavior (still a RuntimeException) while making failures much easier to diagnose.

opensearch/src/main/java/org/opensearch/sql/opensearch/storage/script/core/ExpressionScript.java (1)

62-68: LGTM: AccessController removal in execute method.

The direct calls to buildValueEnv and evaluator.apply are correct. Removing the privileged execution wrapper is appropriate for these operations.

Optional: Simplify return statement.

The intermediate result variable can be eliminated:

-    Environment<Expression, ExprValue> valueEnv = buildValueEnv(fields, valueFactory, docProvider);
-    ExprValue result = evaluator.apply(expression, valueEnv);
-    return result;
+    Environment<Expression, ExprValue> valueEnv = buildValueEnv(fields, valueFactory, docProvider);
+    return evaluator.apply(expression, valueEnv);
direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponse.java (1)

142-151: Correct error handling approach, but inconsistent with other methods.

This implementation correctly lets IOException propagate directly from OBJECT_MAPPER.readValue without wrapping, which properly matches the method's throws IOException declaration. This is the preferred approach.

However, note the inconsistency: the constructor (lines 69-73) and writeTo (lines 108-112) wrap IOException in RuntimeException, while this method doesn't. Standardizing on this direct-propagation approach across all three locations would improve consistency.

Also observe that the RuntimeException catch block at lines 154-162 was designed to unwrap IOException from the old AccessController pattern. With the new direct approach, this catch block will only handle unexpected RuntimeExceptions (not from ObjectMapper), making it potentially dead code or at least confusing.

core/src/main/java/org/opensearch/sql/executor/QueryService.java (1)

140-151: Avoid redundant nested CalcitePlanContext.run in explainWithCalcite

You’re already inside an outer CalcitePlanContext.run(…, settings) at Line 137; the inner context.run(…, settings) re-applies the same thread-local setting and then removes it, which is redundant and slightly obscures the flow.

You can simplify by dropping the inner run and mirroring the structure used in executeWithCalcite:

-            CalcitePlanContext context =
-                CalcitePlanContext.create(
-                    buildFrameworkConfig(), SysLimit.fromSettings(settings), queryType);
-            context.run(
-                () -> {
-                  RelNode relNode = analyze(plan, context);
-                  relNode = mergeAdjacentFilters(relNode);
-                  RelNode optimized = optimize(relNode, context);
-                  RelNode calcitePlan = convertToCalcitePlan(optimized);
-                  executionEngine.explain(calcitePlan, format, context, listener);
-                },
-                settings);
+            CalcitePlanContext context =
+                CalcitePlanContext.create(
+                    buildFrameworkConfig(), SysLimit.fromSettings(settings), queryType);
+            RelNode relNode = analyze(plan, context);
+            relNode = mergeAdjacentFilters(relNode);
+            RelNode optimized = optimize(relNode, context);
+            RelNode calcitePlan = convertToCalcitePlan(optimized);
+            executionEngine.explain(calcitePlan, format, context, listener);

This keeps the legacyPreferred handling in the outer run and removes an unnecessary nesting level.

prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusMetricScan.java (1)

54-67: Improve logging to include stack trace when Prometheus query fails

Core logic of calling queryRange and wrapping the response is fine, but logging only e.getMessage() loses stack information.

Consider logging the exception itself:

-    } catch (IOException e) {
-      LOG.error(e.getMessage());
-      throw new RuntimeException(
-          "Error fetching data from prometheus server. " + e.getMessage());
-    }
+    } catch (IOException e) {
+      LOG.error("Error fetching data from prometheus server", e);
+      throw new RuntimeException(
+          "Error fetching data from prometheus server. " + e.getMessage(), e);
+    }

This keeps the external message but improves diagnostics.

prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusDescribeMetricRequest.java (1)

70-83: Consider preserving the cause when wrapping IOException

Label fetching and mapping into fieldTypes looks correct, and the error message is clear. For easier debugging, you might want to keep the original IOException as a cause and log the full stack trace:

-    } catch (IOException e) {
-      LOG.error(
-          "Error while fetching labels for {} from prometheus: {}",
-          metricName,
-          e.getMessage());
-      throw new PrometheusClientException(
-          String.format(
-              "Error while fetching labels " + "for %s from prometheus: %s",
-              metricName, e.getMessage()));
-    }
+    } catch (IOException e) {
+      LOG.error(
+          "Error while fetching labels for {} from prometheus",
+          metricName,
+          e);
+      throw new PrometheusClientException(
+          String.format(
+              "Error while fetching labels for %s from prometheus: %s",
+              metricName, e.getMessage()),
+          e);
+    }

Assuming PrometheusClientException has an overload accepting a cause, this improves observability without changing behavior.

prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryExemplarsFunctionTableScanOperator.java (1)

38-48: Enhance error logging around queryExemplars failures

Direct call to prometheusClient.queryExemplars and initialization of QueryExemplarsFunctionResponseHandle looks correct. As with the metric scan, only logging e.getMessage() drops stack information.

You can improve diagnostics by logging the exception and optionally chaining it:

-    } catch (IOException e) {
-      LOG.error(e.getMessage());
-      throw new RuntimeException(
-          String.format(
-              "Error fetching data from prometheus server: %s", e.getMessage()));
-    }
+    } catch (IOException e) {
+      LOG.error("Error fetching exemplars from prometheus server", e);
+      throw new RuntimeException(
+          String.format(
+              "Error fetching data from prometheus server: %s", e.getMessage()),
+          e);
+    }
prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusListMetricsRequest.java (1)

37-57: Preserve IOException cause and log full stack when wrapping metric retrieval failures

The behavior after removing AccessController looks equivalent, but the current error handling drops useful context:

  • LOG.error(..., e.getMessage()) only logs the message, not the stack trace.
  • The new RuntimeException is constructed with just the message; the original IOException is not set as the cause.

To ease debugging while keeping the same control flow, consider:

-    } catch (IOException e) {
-      LOG.error(
-          "Error while fetching metric list for from prometheus: {}", e.getMessage());
-      throw new RuntimeException(
-          String.format(
-              "Error while fetching metric list " + "for from prometheus: %s",
-              e.getMessage()));
-    }
+    } catch (IOException e) {
+      LOG.error("Error while fetching metric list from prometheus", e);
+      throw new RuntimeException(
+          String.format("Error while fetching metric list from prometheus: %s", e.getMessage()),
+          e);
+    }

This keeps the same observable behavior while aligning better with the “specific exception types with meaningful messages” and diagnosability goals.

direct-query-core/src/main/java/org/opensearch/sql/prometheus/query/PrometheusQueryHandler.java (2)

50-106: Clarify executeQuery error handling and future-proof enum switch

The new direct try/catch in executeQuery looks reasonable and removes the privileged wrapper cleanly, but a couple of details are worth tightening:

  • Contract vs throws declaration: The method still declares throws IOException, but all IOExceptions are now caught and converted to JSON error responses. That’s fine if callers only ever inspect the returned JSON, but it means the throws clause is effectively vestigial. Please confirm that nothing upstream relies on catching IOException from this method.

  • Enum default behavior:

    switch (queryType) {
      case RANGE:
        ...
      case INSTANT:
      default:
        ...
    }

    With this pattern, any future PrometheusQueryType value will silently take the INSTANT path (using options.getTime()), which may be null/invalid for a new type. Consider making the switch exhaustive and treating unknown values as an explicit error instead of falling through to INSTANT, e.g.:

  • switch (queryType) {

  •  case RANGE:
    
  •    ...
    
  •  case INSTANT:
    
  •  default:
    
  •    ...
    
  • }

  • switch (queryType) {
  •  case RANGE:
    
  •    ...
    
  •  case INSTANT:
    
  •    ...
    
  •  default:
    
  •    return createErrorJson("Unsupported Prometheus query type: " + queryType);
    
  • }

This keeps the non-privileged behavior while making failures more predictable if the enum expands later.

---

`115-211`: **Improve exception wrapping and error messages in getResources/writeResources**

The removal of privileged blocks in `getResources` and `writeResources` looks good; both now use straightforward switches and a single `IOException` catch. A few small improvements would make error handling clearer and more informative:

1. **Preserve the original cause in PrometheusClientException**

 In both methods you currently have:

 ```java
 } catch (IOException e) {
   LOG.error("Error getting resources", e);
   throw new PrometheusClientException(
       String.format("Error while getting resources for %s: %s",
           request.getResourceType(), e.getMessage()));
 }

This logs the stack trace but discards the cause from the thrown exception. Prefer:

-    } catch (IOException e) {
-      LOG.error("Error getting resources", e);
-      throw new PrometheusClientException(
-          String.format(
-              "Error while getting resources for %s: %s",
-              request.getResourceType(), e.getMessage()));
-    }
+    } catch (IOException e) {
+      LOG.error("Error getting resources", e);
+      throw new PrometheusClientException(
+          String.format(
+              "Error while getting resources for %s: %s",
+              request.getResourceType(), e.getMessage()),
+          e);
+    }

(And analogously for writeResources), so callers can inspect the root cause.

  1. Message wording in writeResources

    In writeResources, the log and exception messages still talk about “getting resources” even though this is a write operation:

    LOG.error("Error getting resources", e);
    throw new PrometheusClientException("Error while getting resources for %s: %s", ...);

    For clarity (and for future debugging), it would be better to use “writing resources” here.

These changes keep semantics the same while improving diagnosability and aligning with the guideline of meaningful exception messages.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a6f2b0 and 13c8988.

📒 Files selected for processing (21)
  • async-query-core/src/main/java/org/opensearch/sql/spark/client/EMRServerlessClientFactoryImpl.java (1 hunks)
  • async-query-core/src/main/java/org/opensearch/sql/spark/client/EmrServerlessClientImpl.java (3 hunks)
  • async-query/src/main/java/org/opensearch/sql/spark/config/SparkExecutionEngineConfigClusterSettingLoader.java (1 hunks)
  • core/src/main/java/org/opensearch/sql/executor/QueryService.java (2 hunks)
  • direct-query-core/src/main/java/org/opensearch/sql/prometheus/query/PrometheusQueryHandler.java (2 hunks)
  • direct-query-core/src/main/java/org/opensearch/sql/prometheus/utils/PrometheusClientUtils.java (1 hunks)
  • direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponse.java (3 hunks)
  • legacy/src/main/java/org/opensearch/sql/legacy/cursor/DefaultCursor.java (2 hunks)
  • opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java (2 hunks)
  • opensearch/src/main/java/org/opensearch/sql/opensearch/security/SecurityAccess.java (1 hunks)
  • opensearch/src/main/java/org/opensearch/sql/opensearch/storage/script/core/ExpressionScript.java (2 hunks)
  • prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryExemplarsFunctionTableScanOperator.java (1 hunks)
  • prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryRangeFunctionTableScanOperator.java (1 hunks)
  • prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusDescribeMetricRequest.java (1 hunks)
  • prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusListMetricsRequest.java (1 hunks)
  • prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusMetricScan.java (1 hunks)
  • prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactory.java (1 hunks)
  • prometheus/src/test/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactoryTest.java (2 hunks)
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/ErrorFormatter.java (2 hunks)
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/JsonResponseFormatter.java (2 hunks)
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/YamlResponseFormatter.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.java

📄 CodeRabbit inference engine (.rules/REVIEW_GUIDELINES.md)

**/*.java: Use PascalCase for class names (e.g., QueryExecutor)
Use camelCase for method and variable names (e.g., executeQuery)
Use UPPER_SNAKE_CASE for constants (e.g., MAX_RETRY_COUNT)
Keep methods under 20 lines with single responsibility
All public classes and methods must have proper JavaDoc
Use specific exception types with meaningful messages for error handling
Prefer Optional<T> for nullable returns in Java
Avoid unnecessary object creation in loops
Use StringBuilder for string concatenation in loops
Validate all user inputs, especially queries
Sanitize data before logging to prevent injection attacks
Use try-with-resources for proper resource cleanup in Java
Maintain Java 11 compatibility when possible for OpenSearch 2.x
Document Calcite-specific workarounds in code

Files:

  • prometheus/src/test/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactoryTest.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusMetricScan.java
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/JsonResponseFormatter.java
  • core/src/main/java/org/opensearch/sql/executor/QueryService.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryExemplarsFunctionTableScanOperator.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusListMetricsRequest.java
  • async-query-core/src/main/java/org/opensearch/sql/spark/client/EMRServerlessClientFactoryImpl.java
  • legacy/src/main/java/org/opensearch/sql/legacy/cursor/DefaultCursor.java
  • opensearch/src/main/java/org/opensearch/sql/opensearch/storage/script/core/ExpressionScript.java
  • direct-query-core/src/main/java/org/opensearch/sql/prometheus/utils/PrometheusClientUtils.java
  • async-query-core/src/main/java/org/opensearch/sql/spark/client/EmrServerlessClientImpl.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusDescribeMetricRequest.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryRangeFunctionTableScanOperator.java
  • direct-query-core/src/main/java/org/opensearch/sql/prometheus/query/PrometheusQueryHandler.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactory.java
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/ErrorFormatter.java
  • opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/YamlResponseFormatter.java
  • direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponse.java
  • async-query/src/main/java/org/opensearch/sql/spark/config/SparkExecutionEngineConfigClusterSettingLoader.java
  • opensearch/src/main/java/org/opensearch/sql/opensearch/security/SecurityAccess.java

⚙️ CodeRabbit configuration file

**/*.java: - Verify Java naming conventions (PascalCase for classes, camelCase for methods/variables)

  • Check for proper JavaDoc on public classes and methods
  • Flag redundant comments that restate obvious code
  • Ensure methods are under 20 lines with single responsibility
  • Verify proper error handling with specific exception types
  • Check for Optional usage instead of null returns
  • Validate proper use of try-with-resources for resource management

Files:

  • prometheus/src/test/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactoryTest.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusMetricScan.java
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/JsonResponseFormatter.java
  • core/src/main/java/org/opensearch/sql/executor/QueryService.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryExemplarsFunctionTableScanOperator.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusListMetricsRequest.java
  • async-query-core/src/main/java/org/opensearch/sql/spark/client/EMRServerlessClientFactoryImpl.java
  • legacy/src/main/java/org/opensearch/sql/legacy/cursor/DefaultCursor.java
  • opensearch/src/main/java/org/opensearch/sql/opensearch/storage/script/core/ExpressionScript.java
  • direct-query-core/src/main/java/org/opensearch/sql/prometheus/utils/PrometheusClientUtils.java
  • async-query-core/src/main/java/org/opensearch/sql/spark/client/EmrServerlessClientImpl.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/request/system/PrometheusDescribeMetricRequest.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/functions/scan/QueryRangeFunctionTableScanOperator.java
  • direct-query-core/src/main/java/org/opensearch/sql/prometheus/query/PrometheusQueryHandler.java
  • prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactory.java
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/ErrorFormatter.java
  • opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java
  • protocol/src/main/java/org/opensearch/sql/protocol/response/format/YamlResponseFormatter.java
  • direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponse.java
  • async-query/src/main/java/org/opensearch/sql/spark/config/SparkExecutionEngineConfigClusterSettingLoader.java
  • opensearch/src/main/java/org/opensearch/sql/opensearch/security/SecurityAccess.java
**/*Test.java

📄 CodeRabbit inference engine (.rules/REVIEW_GUIDELINES.md)

**/*Test.java: All new business logic requires unit tests
Name unit tests with *Test.java suffix in OpenSearch SQL

Files:

  • prometheus/src/test/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactoryTest.java
**/test/**/*.java

⚙️ CodeRabbit configuration file

**/test/**/*.java: - Verify test coverage for new business logic

  • Check test naming follows conventions (*Test.java for unit, *IT.java for integration)
  • Ensure tests are independent and don't rely on execution order
  • Validate meaningful test data that reflects real-world scenarios
  • Check for proper cleanup of test resources

Files:

  • prometheus/src/test/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactoryTest.java
🧠 Learnings (2)
📚 Learning: 2025-12-02T17:27:55.938Z
Learnt from: CR
Repo: opensearch-project/sql PR: 0
File: .rules/REVIEW_GUIDELINES.md:0-0
Timestamp: 2025-12-02T17:27:55.938Z
Learning: Test SQL generation and optimization paths for Calcite integration changes

Applied to files:

  • core/src/main/java/org/opensearch/sql/executor/QueryService.java
📚 Learning: 2025-12-02T17:27:55.938Z
Learnt from: CR
Repo: opensearch-project/sql PR: 0
File: .rules/REVIEW_GUIDELINES.md:0-0
Timestamp: 2025-12-02T17:27:55.938Z
Learning: Development requires JDK 21 for the OpenSearch SQL project

Applied to files:

  • opensearch/src/main/java/org/opensearch/sql/opensearch/storage/script/core/ExpressionScript.java
🧬 Code graph analysis (5)
core/src/main/java/org/opensearch/sql/executor/QueryService.java (1)
core/src/main/java/org/opensearch/sql/calcite/CalcitePlanContext.java (1)
  • CalcitePlanContext (30-137)
direct-query-core/src/main/java/org/opensearch/sql/prometheus/utils/PrometheusClientUtils.java (1)
common/src/main/java/org/opensearch/sql/common/setting/Settings.java (1)
  • Settings (17-105)
prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactory.java (1)
direct-query-core/src/main/java/org/opensearch/sql/prometheus/utils/PrometheusClientUtils.java (1)
  • PrometheusClientUtils (29-166)
opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java (1)
core/src/main/java/org/opensearch/sql/calcite/utils/CalciteToolsHelper.java (1)
  • OpenSearchRelRunners (337-366)
protocol/src/main/java/org/opensearch/sql/protocol/response/format/YamlResponseFormatter.java (1)
core/src/main/java/org/opensearch/sql/utils/YamlFormatter.java (1)
  • YamlFormatter (19-51)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: bwc-tests-rolling-upgrade (25)
  • GitHub Check: build-linux (25, doc)
  • GitHub Check: bwc-tests-full-restart (25)
  • GitHub Check: build-linux (25, unit)
  • GitHub Check: build-linux (25, integration)
  • GitHub Check: build-linux (21, doc)
  • GitHub Check: bwc-tests-rolling-upgrade (21)
  • GitHub Check: build-linux (21, unit)
  • GitHub Check: build-linux (21, integration)
  • GitHub Check: bwc-tests-full-restart (21)
  • GitHub Check: security-it-linux (25)
  • GitHub Check: security-it-linux (21)
  • GitHub Check: build-windows-macos (macos-14, 21, doc)
  • GitHub Check: build-windows-macos (windows-latest, 21, -PbuildPlatform=windows, integration)
  • GitHub Check: build-windows-macos (windows-latest, 25, -PbuildPlatform=windows, integration)
  • GitHub Check: build-windows-macos (windows-latest, 25, -PbuildPlatform=windows, unit)
  • GitHub Check: build-windows-macos (macos-14, 25, integration)
  • GitHub Check: build-windows-macos (windows-latest, 21, -PbuildPlatform=windows, unit)
  • GitHub Check: build-windows-macos (macos-14, 25, unit)
  • GitHub Check: build-windows-macos (macos-14, 25, doc)
  • GitHub Check: build-windows-macos (macos-14, 21, integration)
  • GitHub Check: build-windows-macos (macos-14, 21, unit)
  • GitHub Check: security-it-windows-macos (windows-latest, 25)
  • GitHub Check: security-it-windows-macos (windows-latest, 21)
  • GitHub Check: security-it-windows-macos (macos-14, 21)
  • GitHub Check: security-it-windows-macos (macos-14, 25)
  • GitHub Check: CodeQL-Scan (java)
  • GitHub Check: test-sql-cli-integration (21)
🔇 Additional comments (16)
protocol/src/main/java/org/opensearch/sql/protocol/response/format/JsonResponseFormatter.java (1)

57-59: jsonify style switch is concise and consistent with error formatting

The ternary on style to pick prettyJsonify vs compactJsonify mirrors the throwable formatting path and keeps the behavior clear and deterministic without any privileged wrapper. No issues from a correctness, performance, or style standpoint.

protocol/src/main/java/org/opensearch/sql/protocol/response/format/YamlResponseFormatter.java (1)

43-45: LGTM! Clean removal of AccessController wrapper.

The direct call to YamlFormatter.formatToYaml() maintains equivalent behavior while simplifying the code. Exception handling is preserved in the formatter itself, and this change aligns perfectly with the PR objective to remove deprecated AccessController references.

async-query/src/main/java/org/opensearch/sql/spark/config/SparkExecutionEngineConfigClusterSettingLoader.java (1)

25-26: Verify that removing AccessController.doPrivileged() doesn't affect functionality.

The direct call to toSparkExecutionEngineConfig() previously ran under AccessController.doPrivileged(). Ensure this method and any operations it performs don't require elevated privileges to function correctly. Check the implementation for security-sensitive operations like reflection, classloading, or file I/O that may depend on privilege escalation.

opensearch/src/main/java/org/opensearch/sql/opensearch/storage/script/core/ExpressionScript.java (1)

49-53: LGTM: AccessController removal in constructor.

The direct calls to extractFields and buildValueFactory are correct. These internal initialization operations don't require privileged execution or additional error handling.

async-query-core/src/main/java/org/opensearch/sql/spark/client/EmrServerlessClientImpl.java (3)

62-73: LGTM! Privileged action correctly replaced with direct execution.

The refactoring correctly removes the AccessController.doPrivileged wrapper while preserving all error handling semantics:

  • Exception logging maintained
  • Metrics increment preserved
  • ValidationException to IllegalArgumentException translation intact
  • Generic error handling for other exceptions unchanged

82-89: LGTM! Clean refactoring with preserved error handling.

The privileged action removal is correct, maintaining the original behavior:

  • Direct EMR API call without wrapper
  • Error logging and metrics increment preserved
  • Generic exception handling unchanged

99-114: LGTM! Exception propagation logic correctly preserved.

The refactoring properly maintains the conditional exception handling:

  • The allowExceptionPropagation flag behavior is preserved (early rethrow on line 104)
  • Error logging with jobId context maintained
  • Metrics increment preserved
  • ValidationException to IllegalArgumentException translation intact
async-query-core/src/main/java/org/opensearch/sql/spark/client/EMRServerlessClientFactoryImpl.java (1)

57-62: Client creation correctly preserves logic after privileged action removal.

The code snippet shows proper implementation: the DefaultAWSCredentialsProviderChain is initialized at the correct scope, and the AWS client is properly wrapped in EmrServerlessClientImpl. However, the broader impact of removing the privileged action wrapper cannot be fully verified without access to the complete codebase to check for:

  • Remaining AccessController.doPrivileged() usages in related credential initialization code
  • Integration test results confirming credential provider chain behavior in the target deployment environment
  • Security policy configurations that may affect system property and environment variable access

The code change itself is structurally sound, but security implications require verification in the deployment context.

legacy/src/main/java/org/opensearch/sql/legacy/cursor/DefaultCursor.java (1)

201-206: Deserialization error handling looks correct and consistent.

Catching JsonProcessingException around objectMapper.readValue(json.getString(SORT_FIELDS), Object[].class) and wrapping it in a RuntimeException matches the existing error-handling style in this class and clearly reports JSON parsing issues for sortFields.

Please just confirm that this behavior (failing fast with RuntimeException on malformed cursor JSON) is acceptable for all callers of DefaultCursor.from, since it will turn any corrupted SORT_FIELDS payload into an unrecoverable error rather than a more graceful fallback.

direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponse.java (1)

69-73: Unable to verify error handling inconsistency due to inaccessible repository.

The review comment raises concerns about error handling inconsistency in lines 69-73, specifically that catching IOException and wrapping it in RuntimeException violates the declared throws IOException contract. However, I cannot access the repository to verify:

  • The actual method signature and declared exceptions
  • The implementation details at the specified line numbers
  • The error handling approach in the parseResult method for comparison
  • Conventions used in similar response classes in the codebase

Manual verification is needed to confirm whether:

  1. The method actually declares throws IOException and if wrapping IOException in RuntimeException is truly a contract violation
  2. The inconsistency with parseResult error handling is as described
  3. This pattern is intentional per OpenSearch conventions or a genuine issue
core/src/main/java/org/opensearch/sql/executor/QueryService.java (1)

101-108: Calcite execution path after removing privileged wrapper looks correct

Creating CalcitePlanContext locally and running analyze → mergeAdjacentFilters → optimize → convertToCalcitePlan → executionEngine.execute directly inside the existing CalcitePlanContext.run keeps the control flow and fallback handling unchanged while removing the privileged block. No issues spotted here.

direct-query-core/src/main/java/org/opensearch/sql/prometheus/utils/PrometheusClientUtils.java (1)

53-82: Direct OkHttpClient construction without privileged block looks good

Client configuration (timeouts, redirect handling, URI deny-list interceptor, and auth interceptors for BASIC/AWSSIGV4) is preserved while removing the privileged wrapper. As long as settings is non-null at call sites, this is behaviorally equivalent.

prometheus/src/main/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactory.java (1)

54-62: Storage engine creation flow remains sound after removing privileged block

Validating properties first and then constructing PrometheusClientImpl with PrometheusClientUtils.getHttpClient(requiredConfig, settings) and new URI(requiredConfig.get(URI)) inside a try that catches URISyntaxException | UnknownHostException preserves the prior behavior (wrapping URI issues in IllegalArgumentException) while simplifying control flow. No functional concerns here.

prometheus/src/test/java/org/opensearch/sql/prometheus/storage/PrometheusStorageFactoryTest.java (1)

133-133: Updated test URIs to https://opensearch.org are fine

Switching the Prometheus URI in these tests to https://opensearch.org keeps the assertions intact and avoids depending on a placeholder domain. No behavioral change to the tests beyond the literal value.

Also applies to: 153-154

protocol/src/main/java/org/opensearch/sql/protocol/response/format/ErrorFormatter.java (1)

18-19: Direct Gson usage without privileged wrappers appears behaviorally equivalent

Initializing PRETTY_PRINT_GSON and GSON via SerializeUtils.getGsonBuilder() (with pretty-printing + disabled HTML escaping vs. compact + disabled HTML escaping) and using toJson directly in compactJsonify / prettyJsonify keeps the JSON output semantics the same while removing the security-manager-related indirection. No issues spotted with the change itself; just ensure SerializeUtils.getGsonBuilder() remains configured as expected for error payloads.

Also applies to: 34-39

opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java (1)

160-212: Verify connection lifecycle in OpenSearchRelRunners.run() and async error handling in execute(RelNode, ...)

The review raises two concerns that require verification against the actual implementation:

  1. Potential PreparedStatement/Connection lifecycle issue: If OpenSearchRelRunners.run() closes the Connection via try-with-resources before returning the PreparedStatement, then statement.executeQuery() at line 207 would operate on a closed connection. Confirm whether:

    • The connection is managed within run() and closed before return, or
    • Connection lifecycle is managed at the call site, or
    • The query is fully executed within run() before closing.
  2. Error handling inconsistency: The execute(RelNode, ...) method catches SQLException and rethrows RuntimeException without notifying the listener, unlike the execute(PhysicalPlan, ...) overload which calls listener.onFailure(e). Verify whether client.schedule() automatically translates thrown exceptions into listener callbacks, or if missing listener.onFailure() causes silent failures.

Comment on lines +108 to +112
try {
serializedResult = OBJECT_MAPPER.writeValueAsString(result);
} catch (IOException e) {
throw new RuntimeException("Failed to serialize result", e);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same error handling issue: RuntimeException bypasses IOException contract.

This has the same problem as the constructor (lines 69-73): catching IOException and wrapping it in RuntimeException violates the throws IOException declaration at line 87. Since writeTo overrides ActionResponse.writeTo(StreamOutput), maintaining the IOException contract is especially important for polymorphic behavior.

Apply the same fix as suggested for the constructor - either let IOException propagate directly or document why RuntimeException is necessary.

-      // Serialize the data source result to JSON
-      final String serializedResult;
-      try {
-        serializedResult = OBJECT_MAPPER.writeValueAsString(result);
-      } catch (IOException e) {
-        throw new RuntimeException("Failed to serialize result", e);
-      }
+      // Serialize the data source result to JSON
+      String serializedResult = OBJECT_MAPPER.writeValueAsString(result);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
serializedResult = OBJECT_MAPPER.writeValueAsString(result);
} catch (IOException e) {
throw new RuntimeException("Failed to serialize result", e);
}
// Serialize the data source result to JSON
String serializedResult = OBJECT_MAPPER.writeValueAsString(result);
🤖 Prompt for AI Agents
In
direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponse.java
around lines 108-112 (same issue as constructor at lines 69-73): the code
catches IOException from OBJECT_MAPPER.writeValueAsString and wraps it in a
RuntimeException which violates the declared throws IOException for writeTo;
remove the try/catch and let the IOException propagate (or rethrow it as an
IOException) so the method adheres to the IOException contract expected by
ActionResponse.writeTo.

Copy link
Collaborator Author

@Swiddis Swiddis Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will skip this, it's pre-existing behavior and I'm not sure what the impact would be to change it

Long-term: use a report wrapper #4919

…ursor.java

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Simeon Widdis <[email protected]>
Signed-off-by: Simeon Widdis <[email protected]>
@Swiddis Swiddis force-pushed the maintenance/remove-access-controller branch from 2dc01fe to 574f33b Compare December 9, 2025 21:51
@Swiddis Swiddis merged commit 71813bf into opensearch-project:main Dec 10, 2025
37 of 40 checks passed
@Swiddis Swiddis deleted the maintenance/remove-access-controller branch December 10, 2025 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Improves code quality, but not the product

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants