This is an automated email from the ASF dual-hosted git repository.
davidzollo pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git
The following commit(s) were added to refs/heads/dev by this push:
new 6d3e50c6de [Fix][Zeta] Fix job info REST API fails when floating-point
metric is NaN (#11517)
6d3e50c6de is described below
commit 6d3e50c6debf150a0160c563cd69a695da1d1213
Author: Kareemingit <[email protected]>
AuthorDate: Thu Jul 23 06:08:50 2026 +0300
[Fix][Zeta] Fix job info REST API fails when floating-point metric is NaN
(#11517)
Co-authored-by: David Zollo <[email protected]>
---
.../engine/server/rest/service/BaseService.java | 9 +++--
.../rest/service/BaseServiceNullSafetyTest.java | 41 ++++++++++++++++++++++
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git
a/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/BaseService.java
b/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/BaseService.java
index 49bf017034..9f8cd58bfc 100644
---
a/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/BaseService.java
+++
b/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/BaseService.java
@@ -1175,7 +1175,7 @@ public abstract class BaseService {
.sum()));
}
- private JsonObject metricsToJsonObject(Map<String, Object> jobMetrics) {
+ public JsonObject metricsToJsonObject(Map<String, Object> jobMetrics) {
JsonObject members = new JsonObject();
jobMetrics.forEach(
(key, value) -> {
@@ -1186,7 +1186,12 @@ public abstract class BaseService {
if (value instanceof Float
|| value instanceof Double
|| value instanceof BigDecimal) {
- strValue = new
BigDecimal(value.toString()).toPlainString();
+ if ((value instanceof Double &&
!Double.isFinite((Double) value))
+ || (value instanceof Float &&
!Float.isFinite((Float) value))) {
+ strValue = value.toString();
+ } else {
+ strValue = new
BigDecimal(value.toString()).toPlainString();
+ }
} else {
strValue = value.toString();
}
diff --git
a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/service/BaseServiceNullSafetyTest.java
b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/service/BaseServiceNullSafetyTest.java
index b771157ca4..2ab28648a8 100644
---
a/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/service/BaseServiceNullSafetyTest.java
+++
b/seatunnel-engine/seatunnel-engine-server/src/test/java/org/apache/seatunnel/engine/server/rest/service/BaseServiceNullSafetyTest.java
@@ -30,6 +30,8 @@ import com.hazelcast.internal.json.JsonObject;
import com.hazelcast.spi.impl.NodeEngineImpl;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import static org.mockito.Mockito.mock;
@@ -108,4 +110,43 @@ public class BaseServiceNullSafetyTest {
Assertions.assertEquals("", result.getString(RestConstant.START_TIME,
null));
Assertions.assertEquals("", result.getString(RestConstant.FINISH_TIME,
null));
}
+
+ @Test
+ public void testMetricsToJsonObjectWithNonFiniteFloats() {
+ // 1. We create an anonymous subclass of BaseService if it's abstract,
+ // or just instantiate it if it's concrete.
+ // Passing null for dependencies since metricsToJsonObject doesn't
rely on them.
+ BaseService baseService = new BaseService(null) {
+ // Dummy anonymous class in case BaseService is abstract
in the codebase
+ };
+
+ // 2. Prepare the boundary condition metrics
+ Map<String, Object> jobMetrics = new HashMap<>();
+ jobMetrics.put("normal_double", 123.456d);
+ jobMetrics.put("normal_float", 78.9f);
+ jobMetrics.put("nan_double", Double.NaN);
+ jobMetrics.put("nan_float", Float.NaN);
+ jobMetrics.put("positive_infinity", Double.POSITIVE_INFINITY);
+ jobMetrics.put("negative_infinity", Double.NEGATIVE_INFINITY);
+
+ // 3. Nested map to test the recursive loop in your fix
+ Map<String, Object> nestedMetrics = new HashMap<>();
+ nestedMetrics.put("nested_nan", Double.NaN);
+ jobMetrics.put("nested_map", nestedMetrics);
+
+ // 4. Execute your fixed method
+ JsonObject result = baseService.metricsToJsonObject(jobMetrics);
+
+ // 5. Assert the values were parsed to strings safely without throwing
an exception
+ Assertions.assertEquals("123.456", result.getString("normal_double",
""));
+ Assertions.assertEquals("78.9", result.getString("normal_float", ""));
+ Assertions.assertEquals("NaN", result.getString("nan_double", ""));
+ Assertions.assertEquals("NaN", result.getString("nan_float", ""));
+ Assertions.assertEquals("Infinity",
result.getString("positive_infinity", ""));
+ Assertions.assertEquals("-Infinity",
result.getString("negative_infinity", ""));
+
+ // Check the nested map
+ JsonObject nestedResult = result.get("nested_map").asObject();
+ Assertions.assertEquals("NaN",
nestedResult.get("nested_nan").asString());
+ }
}