This is an automated email from the ASF dual-hosted git repository.
ctubbsii pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push:
new 838e6f477b Make instantiating Gson singletons easier (#3531)
838e6f477b is described below
commit 838e6f477ba0ea1ecd6d4efe5f79267f6ecdb298
Author: Christopher Tubbs <[email protected]>
AuthorDate: Fri Jun 23 17:12:59 2023 -0400
Make instantiating Gson singletons easier (#3531)
* Create LazySingletons class to host singleton suppliers
* Add lazy GSON singleton supplier
* Replace GsonSingleton class from #3516 with this
---
.../core/clientImpl/bulk/BulkSerialize.java | 4 +--
.../apache/accumulo/core/lock/ServiceLockData.java | 9 +++----
.../schema/ExternalCompactionFinalState.java | 7 ++---
.../schema/ExternalCompactionMetadata.java | 6 ++---
.../core/metadata/schema/RootTabletMetadata.java | 6 ++---
.../spi/compaction/DefaultCompactionPlanner.java | 7 ++---
.../spi/scan/ConfigurableScanServerSelector.java | 6 ++---
.../{GsonSingleton.java => LazySingletons.java} | 30 ++++++++++------------
pom.xml | 4 +++
.../accumulo/server/metadata/RootGcCandidates.java | 6 ++---
.../accumulo/manager/tableOps/TraceRepo.java | 5 ++--
.../util/logging/AccumuloMonitorAppender.java | 4 +--
.../accumulo/test/CountNameNodeOpsBulkIT.java | 4 +--
13 files changed, 50 insertions(+), 48 deletions(-)
diff --git
a/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
b/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
index bff210ee80..533a43c237 100644
---
a/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
+++
b/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
@@ -19,6 +19,7 @@
package org.apache.accumulo.core.clientImpl.bulk;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -37,7 +38,6 @@ import org.apache.accumulo.core.clientImpl.bulk.Bulk.Files;
import org.apache.accumulo.core.clientImpl.bulk.Bulk.Mapping;
import org.apache.accumulo.core.data.TableId;
import org.apache.accumulo.core.dataImpl.KeyExtent;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.core.util.json.ByteArrayToBase64TypeAdapter;
import org.apache.hadoop.fs.Path;
@@ -98,7 +98,7 @@ public class BulkSerialize {
final Path renamingFile = new Path(bulkDir, Constants.BULK_RENAME_FILE);
try (OutputStream fsOut = output.create(renamingFile);
BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(fsOut))) {
- GsonSingleton.getInstance().toJson(oldToNewNameMap, writer);
+ GSON.get().toJson(oldToNewNameMap, writer);
}
}
diff --git
a/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
b/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
index ed624be642..736a36f0fe 100644
--- a/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
+++ b/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.lock;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.util.Collections;
import java.util.EnumMap;
@@ -29,7 +30,6 @@ import java.util.Set;
import java.util.UUID;
import org.apache.accumulo.core.util.AddressUtil;
-import org.apache.accumulo.core.util.GsonSingleton;
import com.google.common.net.HostAndPort;
@@ -117,7 +117,7 @@ public class ServiceLockData implements
Comparable<ServiceLockData> {
@Override
public String toString() {
- return GsonSingleton.getInstance().toJson(this);
+ return GSON.get().toJson(this);
}
}
@@ -193,7 +193,7 @@ public class ServiceLockData implements
Comparable<ServiceLockData> {
public byte[] serialize() {
ServiceDescriptors sd = new ServiceDescriptors();
services.values().forEach(s -> sd.addService(s));
- return GsonSingleton.getInstance().toJson(sd).getBytes(UTF_8);
+ return GSON.get().toJson(sd).getBytes(UTF_8);
}
@Override
@@ -227,8 +227,7 @@ public class ServiceLockData implements
Comparable<ServiceLockData> {
if (data.isBlank()) {
return Optional.empty();
}
- return Optional.of(
- new ServiceLockData(GsonSingleton.getInstance().fromJson(data,
ServiceDescriptors.class)));
+ return Optional.of(new ServiceLockData(GSON.get().fromJson(data,
ServiceDescriptors.class)));
}
}
diff --git
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
index 1ebf5c400c..421a707d75 100644
---
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
+++
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
@@ -18,11 +18,12 @@
*/
package org.apache.accumulo.core.metadata.schema;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
+
import java.util.Base64;
import org.apache.accumulo.core.data.TableId;
import org.apache.accumulo.core.dataImpl.KeyExtent;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.core.util.TextUtil;
import org.apache.hadoop.io.Text;
@@ -121,11 +122,11 @@ public class ExternalCompactionFinalState {
jd.fileSize = fileSize;
jd.entries = fileEntries;
jd.extent = new Extent(extent);
- return GsonSingleton.getInstance().toJson(jd);
+ return GSON.get().toJson(jd);
}
public static ExternalCompactionFinalState fromJson(ExternalCompactionId
ecid, String json) {
- JsonData jd = GsonSingleton.getInstance().fromJson(json, JsonData.class);
+ JsonData jd = GSON.get().fromJson(json, JsonData.class);
return new ExternalCompactionFinalState(ecid, jd.extent.toKeyExtent(),
FinalState.valueOf(jd.state), jd.fileSize, jd.entries);
}
diff --git
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
index de617e5e03..5eef8c3d5d 100644
---
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
+++
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.metadata.schema;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.util.List;
import java.util.Objects;
@@ -29,7 +30,6 @@ import org.apache.accumulo.core.metadata.ReferencedTabletFile;
import org.apache.accumulo.core.metadata.StoredTabletFile;
import org.apache.accumulo.core.spi.compaction.CompactionExecutorId;
import org.apache.accumulo.core.spi.compaction.CompactionKind;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.core.util.compaction.CompactionExecutorIdImpl;
import org.apache.hadoop.fs.Path;
@@ -137,11 +137,11 @@ public class ExternalCompactionMetadata {
jData.propDels = propagateDeletes;
jData.selectedAll = initiallySelectedAll;
jData.compactionId = compactionId;
- return GsonSingleton.getInstance().toJson(jData);
+ return GSON.get().toJson(jData);
}
public static ExternalCompactionMetadata fromJson(String json) {
- GSonData jData = GsonSingleton.getInstance().fromJson(json,
GSonData.class);
+ GSonData jData = GSON.get().fromJson(json, GSonData.class);
return new ExternalCompactionMetadata(
jData.inputs.stream().map(StoredTabletFile::new).collect(toSet()),
diff --git
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
index e0601f94a7..7ea03a19a4 100644
---
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
+++
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.metadata.schema;
import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
@@ -37,7 +38,6 @@ import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.metadata.RootTable;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CurrentLocationColumnFamily;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.FutureLocationColumnFamily;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -96,7 +96,7 @@ public class RootTabletMetadata {
public RootTabletMetadata(String json) {
log.trace("Creating root tablet metadata from stored JSON: {}", json);
- this.data = GsonSingleton.getInstance().fromJson(json, Data.class);
+ this.data = GSON.get().fromJson(json, Data.class);
checkArgument(data.version == VERSION, "Invalid Root Table Metadata JSON
version %s",
data.version);
data.columnValues.forEach((fam, qualVals) -> {
@@ -162,7 +162,7 @@ public class RootTabletMetadata {
* @return a JSON representation of the root tablet's data.
*/
public String toJson() {
- return GsonSingleton.getInstance().toJson(data);
+ return GSON.get().toJson(data);
}
}
diff --git
a/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
b/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
index f8a0cbd90d..1b5b662957 100644
---
a/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
+++
b/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
@@ -18,6 +18,8 @@
*/
package org.apache.accumulo.core.spi.compaction;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
+
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
@@ -31,7 +33,6 @@ import java.util.Set;
import org.apache.accumulo.core.client.admin.compaction.CompactableFile;
import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.core.util.compaction.CompactionJobPrioritizer;
import com.google.common.base.Preconditions;
@@ -145,8 +146,8 @@ public class DefaultCompactionPlanner implements
CompactionPlanner {
justification = "Field is written by Gson")
@Override
public void init(InitParameters params) {
- ExecutorConfig[] execConfigs = GsonSingleton.getInstance()
- .fromJson(params.getOptions().get("executors"),
ExecutorConfig[].class);
+ ExecutorConfig[] execConfigs =
+ GSON.get().fromJson(params.getOptions().get("executors"),
ExecutorConfig[].class);
List<Executor> tmpExec = new ArrayList<>();
diff --git
a/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
b/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
index cb2848cef2..a90936832c 100644
---
a/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
+++
b/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
@@ -19,6 +19,7 @@
package org.apache.accumulo.core.spi.scan;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.lang.reflect.Type;
import java.security.SecureRandom;
@@ -35,7 +36,6 @@ import java.util.function.Supplier;
import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
import org.apache.accumulo.core.data.TabletId;
-import org.apache.accumulo.core.util.GsonSingleton;
import com.google.common.base.Preconditions;
import com.google.common.base.Suppliers;
@@ -263,8 +263,8 @@ public class ConfigurableScanServerSelector implements
ScanServerSelector {
private void parseProfiles(Map<String,String> options) {
Type listType = new TypeToken<ArrayList<Profile>>() {}.getType();
- List<Profile> profList = GsonSingleton.getInstance()
- .fromJson(options.getOrDefault("profiles", PROFILES_DEFAULT),
listType);
+ List<Profile> profList =
+ GSON.get().fromJson(options.getOrDefault("profiles",
PROFILES_DEFAULT), listType);
profiles = new HashMap<>();
defaultProfile = null;
diff --git
a/core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java
b/core/src/main/java/org/apache/accumulo/core/util/LazySingletons.java
similarity index 56%
rename from core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java
rename to core/src/main/java/org/apache/accumulo/core/util/LazySingletons.java
index 44c7369305..ac476cc687 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/LazySingletons.java
@@ -18,27 +18,23 @@
*/
package org.apache.accumulo.core.util;
+import java.util.function.Supplier;
+
+import com.google.common.base.Suppliers;
import com.google.gson.Gson;
/**
- * This class provides access to a shared instance of Gson that uses its
default configuration. Gson
- * is thread-safe, so it should be safe to create and reuse a single instance.
- * <p>
- * If you need to use a Gson instance that is configured differently, if you
want to configure
- * TypeAdapters for example, then you should not use this. You should
construct your own instance of
- * Gson.
+ * This class provides easy access to global, immutable, lazily-instantiated,
and thread-safe
+ * singleton resources. These should be used with static imports.
*/
-public class GsonSingleton {
- private static Gson gsonInstance = null;
+public class LazySingletons {
+
+ // prevent instantiating this utility class
+ private LazySingletons() {}
- private GsonSingleton() {
- // private to prevent direct instantiation
- }
+ /**
+ * A Gson instance constructed with defaults. Construct your own if you need
custom settings.
+ */
+ public static final Supplier<Gson> GSON = Suppliers.memoize(Gson::new);
- public static Gson getInstance() {
- if (gsonInstance == null) {
- gsonInstance = new Gson();
- }
- return gsonInstance;
- }
}
diff --git a/pom.xml b/pom.xml
index ad11c9e535..6d2275bef7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1144,6 +1144,10 @@
<property name="format" value="junit[.]framework[.]TestCase"
/>
<property name="message" value="Use JUnit4+ @Test annotation
instead of TestCase" />
</module>
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="import
org[.]apache[.]accumulo[.]core[.]util[.]LazySingletons;" />
+ <property name="message" value="Use static imports for
LazySingletons for consistency" />
+ </module>
<module name="RegexpSinglelineJava">
<property name="format" value="import org[.]junit[.]Assert;"
/>
<property name="message" value="Use static imports for
Assert.* methods for consistency" />
diff --git
a/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
b/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
index 3627024b68..e65813fd4c 100644
---
a/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
+++
b/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
@@ -19,6 +19,7 @@
package org.apache.accumulo.server.metadata;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -27,7 +28,6 @@ import java.util.TreeSet;
import java.util.stream.Stream;
import org.apache.accumulo.core.metadata.StoredTabletFile;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.hadoop.fs.Path;
public class RootGcCandidates {
@@ -61,7 +61,7 @@ public class RootGcCandidates {
}
public RootGcCandidates(String jsonString) {
- this.data = GsonSingleton.getInstance().fromJson(jsonString, Data.class);
+ this.data = GSON.get().fromJson(jsonString, Data.class);
checkArgument(data.version == VERSION, "Invalid Root Table GC Candidates
JSON version %s",
data.version);
data.candidates.forEach((parent, files) -> {
@@ -93,7 +93,7 @@ public class RootGcCandidates {
}
public String toJson() {
- return GsonSingleton.getInstance().toJson(data);
+ return GSON.get().toJson(data);
}
}
diff --git
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
index 5c9045a072..752bc90d44 100644
---
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
+++
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
@@ -18,10 +18,11 @@
*/
package org.apache.accumulo.manager.tableOps;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
+
import org.apache.accumulo.core.clientImpl.thrift.TInfo;
import org.apache.accumulo.core.fate.Repo;
import org.apache.accumulo.core.trace.TraceUtil;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.manager.Manager;
import io.opentelemetry.api.trace.Span;
@@ -105,6 +106,6 @@ public class TraceRepo<T> implements Repo<T> {
// Inorder for Gson to work with generic types, the following passes
repo.getClass() to Gson.
// See the Gson javadoc for more info.
- return repo.getClass() + " " + GsonSingleton.getInstance().toJson(repo,
repo.getClass());
+ return repo.getClass() + " " + GSON.get().toJson(repo, repo.getClass());
}
}
diff --git
a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
index ed14bb4f7d..dce3917910 100644
---
a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
+++
b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
@@ -19,6 +19,7 @@
package org.apache.accumulo.monitor.util.logging;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -33,7 +34,6 @@ import java.util.function.Supplier;
import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.conf.SiteConfiguration;
import org.apache.accumulo.core.fate.zookeeper.ZooCache.ZcStat;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.core.util.Pair;
import org.apache.accumulo.monitor.rest.logs.LogResource;
import org.apache.accumulo.monitor.rest.logs.SingleLogEvent;
@@ -116,7 +116,7 @@ public class AccumuloMonitorAppender extends
AbstractAppender {
pojo.message = event.getMessage().getFormattedMessage();
pojo.stacktrace = throwableToStacktrace(event.getThrown());
- String jsonEvent = GsonSingleton.getInstance().toJson(pojo);
+ String jsonEvent = GSON.get().toJson(pojo);
var req =
HttpRequest.newBuilder(uri).POST(BodyPublishers.ofString(jsonEvent, UTF_8))
.setHeader("Content-Type", "application/json").build();
diff --git
a/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
b/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
index 10f01dfc14..ba9bf2edbd 100644
--- a/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.test;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.URL;
@@ -46,7 +47,6 @@ import org.apache.accumulo.core.file.rfile.RFile;
import org.apache.accumulo.core.manager.thrift.ManagerMonitorInfo;
import org.apache.accumulo.core.metadata.UnreferencedTabletFile;
import org.apache.accumulo.core.spi.crypto.NoCryptoServiceFactory;
-import org.apache.accumulo.core.util.GsonSingleton;
import org.apache.accumulo.minicluster.ServerType;
import org.apache.accumulo.miniclusterImpl.MiniAccumuloConfigImpl;
import org.apache.accumulo.test.functional.ConfigurableMacBase;
@@ -78,7 +78,7 @@ public class CountNameNodeOpsBulkIT extends
ConfigurableMacBase {
URL url = new URL(uri + "/jmx");
log.debug("Fetching web page " + url);
String jsonString = FunctionalTestUtils.readWebPage(url).body();
- Map<?,?> jsonObject = GsonSingleton.getInstance().fromJson(jsonString,
Map.class);
+ Map<?,?> jsonObject = GSON.get().fromJson(jsonString, Map.class);
List<?> beans = (List<?>) jsonObject.get("beans");
for (Object bean : beans) {
Map<?,?> map = (Map<?,?>) bean;