From ec4cfbe041b0cbb591584d617896d355a9fec203 Mon Sep 17 00:00:00 2001 From: Dave Marion Date: Thu, 29 Jan 2026 16:19:16 +0000 Subject: [PATCH 1/4] Fixes serviceStatus json output This change removes the StatusSummary.serviceType field from the json serialization. The serviceType field is redundant in the json output as the same information is used as the key in a map that contains the StatusSummary object. This change also removes the StatusSummary.serviceByGroups field from the json serialization using a custom ExclusionStrategy. Closes #6088 --- .../serviceStatus/ServiceStatusReport.java | 31 ++++++++++++++----- .../util/serviceStatus/StatusSummary.java | 3 ++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java index 7b6279404c9..0806e7c7c1a 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java @@ -26,19 +26,38 @@ import java.time.format.DateTimeFormatter; import java.util.Map; import java.util.Set; -import java.util.TreeMap; -import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; /** * Wrapper for JSON formatted report. */ public class ServiceStatusReport { + private static class HostExclusionStrategy implements ExclusionStrategy { + + @Override + public boolean shouldSkipField(FieldAttributes f) { + if (f.getDeclaringClass().equals(StatusSummary.class) + && f.getName().equals("serviceByGroups")) { + return true; + } + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + return false; + } + + } + private static final Logger LOG = LoggerFactory.getLogger(ServiceStatusReport.class); private static final Gson gson = GSON.get(); @@ -89,11 +108,9 @@ public String toJson() { if (showHosts) { return gson.toJson(this, ServiceStatusReport.class); } else { - Map noHostSummaries = - summaries.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, - e -> e.getValue().withoutHosts(), (a, b) -> b, TreeMap::new)); - ServiceStatusReport noHostReport = new ServiceStatusReport(noHostSummaries, false); - return gson.toJson(noHostReport, ServiceStatusReport.class); + return new GsonBuilder().disableJdkUnsafe() + .setExclusionStrategies(new HostExclusionStrategy()).create() + .toJson(this, ServiceStatusReport.class); } } diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java index f27268a9639..4d7ae03a256 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java @@ -22,8 +22,11 @@ import java.util.Objects; import java.util.Set; +import com.google.gson.annotations.Expose; + public class StatusSummary { + @Expose(serialize = false, deserialize = false) private final ServiceStatusReport.ReportKey serviceType; private final Map resourceGroups; private final Map> serviceByGroups; From a2d5338cefb79eab5782a88898b3d4e66244eabf Mon Sep 17 00:00:00 2001 From: Dave Marion Date: Thu, 29 Jan 2026 16:42:32 +0000 Subject: [PATCH 2/4] Changes from testing --- .../server/util/serviceStatus/StatusSummary.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java index 4d7ae03a256..25ecfee0256 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/StatusSummary.java @@ -22,12 +22,10 @@ import java.util.Objects; import java.util.Set; -import com.google.gson.annotations.Expose; - public class StatusSummary { - @Expose(serialize = false, deserialize = false) - private final ServiceStatusReport.ReportKey serviceType; + // marked transient to exclude from json serialization + private final transient ServiceStatusReport.ReportKey serviceType; private final Map resourceGroups; private final Map> serviceByGroups; private final int serviceCount; @@ -78,10 +76,6 @@ public int getErrorCount() { return errorCount; } - public StatusSummary withoutHosts() { - return new StatusSummary(serviceType, resourceGroups, Map.of(), errorCount); - } - @Override public boolean equals(Object o) { if (this == o) { From 8320589558b0574109a8d9dfb9c0adb9649dc6bb Mon Sep 17 00:00:00 2001 From: Dave Marion Date: Thu, 29 Jan 2026 15:02:35 -0500 Subject: [PATCH 3/4] Update server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java Co-authored-by: Keith Turner --- .../server/util/serviceStatus/ServiceStatusReport.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java index 0806e7c7c1a..373ddb8048f 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java @@ -41,7 +41,13 @@ public class ServiceStatusReport { private static class HostExclusionStrategy implements ExclusionStrategy { - + public HostExclusionStrategy(){ + try { + StatusSummary.class.getField("serviceByGroups"); + } catch (NoSuchFieldException e) { + throw new IllegalStateException(e); + } + } @Override public boolean shouldSkipField(FieldAttributes f) { if (f.getDeclaringClass().equals(StatusSummary.class) From 8c048bb0ef257c7e0a38feced49756415edc7e1b Mon Sep 17 00:00:00 2001 From: Dave Marion Date: Thu, 29 Jan 2026 20:22:18 +0000 Subject: [PATCH 4/4] Fixup PR suggestion --- .../serviceStatus/ServiceStatusReport.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java index 373ddb8048f..0c628cd6046 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/serviceStatus/ServiceStatusReport.java @@ -21,6 +21,7 @@ import static org.apache.accumulo.core.Constants.DEFAULT_RESOURCE_GROUP_NAME; import static org.apache.accumulo.core.util.LazySingletons.GSON; +import java.lang.reflect.Field; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -41,17 +42,22 @@ public class ServiceStatusReport { private static class HostExclusionStrategy implements ExclusionStrategy { - public HostExclusionStrategy(){ - try { - StatusSummary.class.getField("serviceByGroups"); - } catch (NoSuchFieldException e) { - throw new IllegalStateException(e); - } + + private final static String field = "serviceByGroups"; + private final Field fieldToIgnore; + + public HostExclusionStrategy() { + try { + fieldToIgnore = StatusSummary.class.getDeclaredField(field); + } catch (NoSuchFieldException e) { + throw new IllegalStateException(e); + } } + @Override public boolean shouldSkipField(FieldAttributes f) { if (f.getDeclaringClass().equals(StatusSummary.class) - && f.getName().equals("serviceByGroups")) { + && f.getName().equals(fieldToIgnore.getName())) { return true; } return false;