This is an automated email from the ASF dual-hosted git repository.
jmclean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 0372c01df9 [#10125] fix(server): prevent NPE when statistics update
request body is null (#10190)
0372c01df9 is described below
commit 0372c01df95b3a271235a7a048db5920a547f8f2
Author: ChangJun Rho <[email protected]>
AuthorDate: Wed Apr 8 14:02:42 2026 +0900
[#10125] fix(server): prevent NPE when statistics update request body is
null (#10190)
Summary
- Added an explicit null check for `StatisticsUpdateRequest` in
`StatisticOperations.updateStatistics(...)`
- Returned a proper client error (`IllegalArgumentException` -> `400
BAD_REQUEST`) for null request bodies
- Made error handling null-safe to avoid a secondary NPE in the catch
path
- Refactored request validation/statistic-name extraction into helper
methods for readability
- Added a regression test for `PUT /statistics` with JSON `null` body
Verification
- Ran:
`export JAVA_HOME=$(/usr/libexec/java_home -v 17); ./gradlew
:server:test --tests
org.apache.gravitino.server.web.rest.TestStatisticOperations -PskipITs`
- `TestStatisticOperations` passed locally
Fix: #10125
Feedback and suggestions are very welcome. Thank you!
---
.../server/web/rest/StatisticOperations.java | 6 +++++
.../server/web/rest/TestStatisticOperations.java | 29 ++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/StatisticOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/StatisticOperations.java
index 1f4999dfcf..420869c020 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/StatisticOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/StatisticOperations.java
@@ -81,6 +81,9 @@ public class StatisticOperations {
private static final Logger LOG =
LoggerFactory.getLogger(StatisticOperations.class);
+ private static final String NULL_STATS_UPDATE_REQUEST_BODY_ERROR =
+ "Statistics update request body cannot be null";
+
@Context private HttpServletRequest httpRequest;
private final StatisticDispatcher statisticDispatcher;
@@ -160,6 +163,9 @@ public class StatisticOperations {
return Utils.doAs(
httpRequest,
() -> {
+ if (request == null) {
+ throw new
IllegalArgumentException(NULL_STATS_UPDATE_REQUEST_BODY_ERROR);
+ }
request.validate();
MetadataObject object =
MetadataObjects.parse(
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/TestStatisticOperations.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/TestStatisticOperations.java
index dc3055a550..992dd73ebe 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/TestStatisticOperations.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/TestStatisticOperations.java
@@ -371,6 +371,35 @@ public class TestStatisticOperations extends JerseyTest {
UnmodifiableStatisticException.class.getSimpleName(),
errorResp4.getType());
}
+ @Test
+ public void testUpdateTableStatisticsWithNullRequestBody() {
+ when(tableDispatcher.tableExists(any())).thenReturn(true);
+
+ MetadataObject tableObject =
+ MetadataObjects.parse(
+ String.format("%s.%s.%s", catalog, schema, table),
MetadataObject.Type.TABLE);
+
+ Response resp =
+ target(
+ "/metalakes/"
+ + metalake
+ + "/objects/"
+ + tableObject.type()
+ + "/"
+ + tableObject.fullName()
+ + "/statistics")
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .accept("application/vnd.gravitino.v1+json")
+ .put(entity("null", MediaType.APPLICATION_JSON_TYPE));
+
+ Assertions.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(),
resp.getStatus());
+ Assertions.assertEquals(MediaType.APPLICATION_JSON_TYPE,
resp.getMediaType());
+
+ ErrorResponse errorResp = resp.readEntity(ErrorResponse.class);
+ Assertions.assertEquals(ErrorConstants.ILLEGAL_ARGUMENTS_CODE,
errorResp.getCode());
+ Assertions.assertEquals(IllegalArgumentException.class.getSimpleName(),
errorResp.getType());
+ }
+
@Test
public void testDropTableStatistics() {
StatisticsDropRequest req = new StatisticsDropRequest(new String[]
{"test1", "test2"});