Skip to content

Commit

Permalink
Make instantiating Gson singletons easier (#3531)
Browse files Browse the repository at this point in the history
* Create LazySingletons class to host singleton suppliers
* Add lazy GSON singleton supplier
* Replace GsonSingleton class from #3516 with this
  • Loading branch information
ctubbsii committed Jun 23, 2023
1 parent e1320df commit 838e6f4
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -37,7 +38,6 @@
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;

Expand Down Expand Up @@ -98,7 +98,7 @@ public static void writeRenameMap(Map<String,String> oldToNewNameMap, String bul
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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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;
Expand All @@ -29,7 +30,6 @@
import java.util.UUID;

import org.apache.accumulo.core.util.AddressUtil;
import org.apache.accumulo.core.util.GsonSingleton;

import com.google.common.net.HostAndPort;

Expand Down Expand Up @@ -117,7 +117,7 @@ public boolean equals(Object obj) {

@Override
public String toString() {
return GsonSingleton.getInstance().toJson(this);
return GSON.get().toJson(this);
}

}
Expand Down Expand Up @@ -193,7 +193,7 @@ public UUID getServerUUID(ThriftService service) {
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
Expand Down Expand Up @@ -227,8 +227,7 @@ public static Optional<ServiceLockData> parse(byte[] lockData) {
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)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -121,11 +122,11 @@ public String toJson() {
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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;
Expand All @@ -29,7 +30,6 @@
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;

Expand Down Expand Up @@ -137,11 +137,11 @@ public String toJson() {
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()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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;
Expand All @@ -37,7 +38,6 @@
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;
Expand Down Expand Up @@ -96,7 +96,7 @@ private static String bytesToUtf8(byte[] byteSequence) {

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) -> {
Expand Down Expand Up @@ -162,7 +162,7 @@ public TabletMetadata toTabletMetadata() {
* @return a JSON representation of the root tablet's data.
*/
public String toJson() {
return GsonSingleton.getInstance().toJson(data);
return GSON.get().toJson(data);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,7 +33,6 @@

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;
Expand Down Expand Up @@ -145,8 +146,8 @@ public String toString() {
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<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -35,7 +36,6 @@

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;
Expand Down Expand Up @@ -263,8 +263,8 @@ public String getSalt(int attempts) {

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,7 +28,6 @@
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 {
Expand Down Expand Up @@ -61,7 +61,7 @@ public 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) -> {
Expand Down Expand Up @@ -93,7 +93,7 @@ public Stream<String> sortedStream() {
}

public String toJson() {
return GsonSingleton.getInstance().toJson(data);
return GSON.get().toJson(data);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -105,6 +106,6 @@ public static String toLogString(Repo<Manager> repo) {

// 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -33,7 +34,6 @@
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;
Expand Down Expand Up @@ -116,7 +116,7 @@ public void append(final LogEvent event) {
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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;
Expand All @@ -46,7 +47,6 @@
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;
Expand Down Expand Up @@ -78,7 +78,7 @@ private Map<?,?> getStats() throws Exception {
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;
Expand Down

0 comments on commit 838e6f4

Please sign in to comment.