diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerMetadataInspector.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerMetadataInspector.java index 2678d04dfe86..51418abb4e98 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerMetadataInspector.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerMetadataInspector.java @@ -17,12 +17,14 @@ */ package org.apache.hadoop.ozone.container.keyvalue; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.BooleanNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.io.FileUtils; import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; import org.apache.hadoop.hdds.utils.db.Table; @@ -165,7 +167,7 @@ public void process(ContainerData containerData, DatanodeStore store) { } public String process(ContainerData containerData, DatanodeStore store, - Logger log) { + Logger log) { // If the system property to process container metadata was not // specified, or the inspector is unloaded, this method is a no-op. if (mode == Mode.OFF) { @@ -181,55 +183,62 @@ public String process(ContainerData containerData, DatanodeStore store, return null; } - JsonObject containerJson = inspectContainer(kvData, store); + ObjectNode containerJson = inspectContainer(kvData, store); boolean correct = checkAndRepair(containerJson, kvData, store); - Gson gson = new GsonBuilder() - .setPrettyPrinting() - .serializeNulls() - .create(); - String jsonReport = gson.toJson(containerJson); - if (log != null) { - if (correct) { - log.trace(jsonReport); - } else { - log.error(jsonReport); + try { + ObjectMapper mapper = new ObjectMapper(); + // For pretty-printing + mapper.enable(SerializationFeature.INDENT_OUTPUT); + // To serialize null values + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + String jsonReport = mapper.writeValueAsString(containerJson); + if (log != null) { + if (correct) { + log.trace(jsonReport); + } else { + log.error(jsonReport); + } } + return jsonReport; + } catch (JsonProcessingException e) { + LOG.error("Error processing JSON", e); + return null; } - return jsonReport; } - static JsonObject inspectContainer(KeyValueContainerData containerData, - DatanodeStore store) { + static ObjectNode inspectContainer(KeyValueContainerData containerData, + DatanodeStore store) { - JsonObject containerJson = new JsonObject(); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode containerJson = mapper.createObjectNode(); // Create ObjectNode try { // Build top level container properties. - containerJson.addProperty("containerID", containerData.getContainerID()); + containerJson.put("containerID", containerData.getContainerID()); String schemaVersion = containerData.getSchemaVersion(); - containerJson.addProperty("schemaVersion", schemaVersion); - containerJson.addProperty("containerState", + containerJson.put("schemaVersion", schemaVersion); + containerJson.put("containerState", containerData.getState().toString()); - containerJson.addProperty("currentDatanodeID", + containerJson.put("currentDatanodeID", containerData.getVolume().getDatanodeUuid()); - containerJson.addProperty("originDatanodeID", + containerJson.put("originDatanodeID", containerData.getOriginNodeId()); // Build DB metadata values. Table metadataTable = store.getMetadataTable(); - JsonObject dBMetadata = getDBMetadataJson(metadataTable, containerData); - containerJson.add("dBMetadata", dBMetadata); + ObjectNode dBMetadata = getDBMetadataJson(metadataTable, containerData); + containerJson.set("dBMetadata", dBMetadata); // Build aggregate values. - JsonObject aggregates = getAggregateValues(store, + ObjectNode aggregates = getAggregateValues(store, containerData, schemaVersion); - containerJson.add("aggregates", aggregates); + containerJson.set("aggregates", aggregates); // Build info about chunks directory. - JsonObject chunksDirectory = + ObjectNode chunksDirectory = getChunksDirectoryJson(new File(containerData.getChunksPath())); - containerJson.add("chunksDirectory", chunksDirectory); + containerJson.set("chunksDirectory", chunksDirectory); } catch (IOException ex) { LOG.error("Inspecting container {} failed", containerData.getContainerID(), ex); @@ -238,28 +247,32 @@ static JsonObject inspectContainer(KeyValueContainerData containerData, return containerJson; } - static JsonObject getDBMetadataJson(Table metadataTable, - KeyValueContainerData containerData) throws IOException { - JsonObject dBMetadata = new JsonObject(); + static ObjectNode getDBMetadataJson(Table metadataTable, + KeyValueContainerData containerData) + throws IOException { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode dBMetadata = mapper.createObjectNode(); // Create ObjectNode - dBMetadata.addProperty(OzoneConsts.BLOCK_COUNT, + dBMetadata.put(OzoneConsts.BLOCK_COUNT, metadataTable.get(containerData.getBlockCountKey())); - dBMetadata.addProperty(OzoneConsts.CONTAINER_BYTES_USED, + dBMetadata.put(OzoneConsts.CONTAINER_BYTES_USED, metadataTable.get(containerData.getBytesUsedKey())); - dBMetadata.addProperty(OzoneConsts.PENDING_DELETE_BLOCK_COUNT, + dBMetadata.put(OzoneConsts.PENDING_DELETE_BLOCK_COUNT, metadataTable.get(containerData.getPendingDeleteBlockCountKey())); - dBMetadata.addProperty(OzoneConsts.DELETE_TRANSACTION_KEY, + dBMetadata.put(OzoneConsts.DELETE_TRANSACTION_KEY, metadataTable.get(containerData.getLatestDeleteTxnKey())); - dBMetadata.addProperty(OzoneConsts.BLOCK_COMMIT_SEQUENCE_ID, + dBMetadata.put(OzoneConsts.BLOCK_COMMIT_SEQUENCE_ID, metadataTable.get(containerData.getBcsIdKey())); return dBMetadata; } - static JsonObject getAggregateValues(DatanodeStore store, - KeyValueContainerData containerData, String schemaVersion) + static ObjectNode getAggregateValues(DatanodeStore store, + KeyValueContainerData containerData, + String schemaVersion) throws IOException { - JsonObject aggregates = new JsonObject(); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode aggregates = mapper.createObjectNode(); // Create ObjectNode long usedBytesTotal = 0; long blockCountTotal = 0; @@ -305,22 +318,23 @@ static JsonObject getAggregateValues(DatanodeStore store, countPendingDeletesSchemaV3(schemaThreeStore, containerData); } else { throw new IOException("Failed to process deleted blocks for unknown " + - "container schema " + schemaVersion); + "container schema " + schemaVersion); } - aggregates.addProperty("blockCount", blockCountTotal); - aggregates.addProperty("usedBytes", usedBytesTotal); + aggregates.put("blockCount", blockCountTotal); + aggregates.put("usedBytes", usedBytesTotal); pendingDelete.addToJson(aggregates); return aggregates; } - static JsonObject getChunksDirectoryJson(File chunksDir) throws IOException { - JsonObject chunksDirectory = new JsonObject(); + static ObjectNode getChunksDirectoryJson(File chunksDir) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode chunksDirectory = mapper.createObjectNode(); - chunksDirectory.addProperty("path", chunksDir.getAbsolutePath()); + chunksDirectory.put("path", chunksDir.getAbsolutePath()); boolean chunksDirPresent = FileUtils.isDirectory(chunksDir); - chunksDirectory.addProperty("present", chunksDirPresent); + chunksDirectory.put("present", chunksDirPresent); long fileCount = 0; if (chunksDirPresent) { @@ -328,43 +342,44 @@ static JsonObject getChunksDirectoryJson(File chunksDir) throws IOException { fileCount = stream.count(); } } - chunksDirectory.addProperty("fileCount", fileCount); + chunksDirectory.put("fileCount", fileCount); return chunksDirectory; } - private boolean checkAndRepair(JsonObject parent, - KeyValueContainerData containerData, DatanodeStore store) { - JsonArray errors = new JsonArray(); + private boolean checkAndRepair(JsonNode parent, + KeyValueContainerData containerData, + DatanodeStore store) { + ObjectMapper objectMapper = new ObjectMapper(); + ArrayNode errors = objectMapper.createArrayNode(); boolean passed = true; Table metadataTable = store.getMetadataTable(); - final JsonObject dBMetadata = parent.getAsJsonObject("dBMetadata"); - final JsonObject aggregates = parent.getAsJsonObject("aggregates"); + final JsonNode dBMetadata = parent.get("dBMetadata"); + final JsonNode aggregates = parent.get("aggregates"); // Check and repair block count. - JsonElement blockCountDB = parent.getAsJsonObject("dBMetadata") - .get(OzoneConsts.BLOCK_COUNT); + JsonNode blockCountDB = dBMetadata.get(OzoneConsts.BLOCK_COUNT); + + JsonNode blockCountAggregate = aggregates.get("blockCount"); - JsonElement blockCountAggregate = parent.getAsJsonObject("aggregates") - .get("blockCount"); // If block count is absent from the DB, it is only an error if there are // a non-zero amount of block keys in the DB. long blockCountDBLong = 0; - if (!blockCountDB.isJsonNull()) { - blockCountDBLong = blockCountDB.getAsLong(); + if (blockCountDB != null && !blockCountDB.isNull()) { + blockCountDBLong = blockCountDB.asLong(); } - if (blockCountDBLong != blockCountAggregate.getAsLong()) { + if (blockCountDBLong != blockCountAggregate.asLong()) { passed = false; BooleanSupplier keyRepairAction = () -> { boolean repaired = false; try { metadataTable.put(containerData.getBlockCountKey(), - blockCountAggregate.getAsLong()); + blockCountAggregate.asLong()); repaired = true; } catch (IOException ex) { LOG.error("Error repairing block count for container {}.", @@ -373,33 +388,33 @@ private boolean checkAndRepair(JsonObject parent, return repaired; }; - JsonObject blockCountError = buildErrorAndRepair("dBMetadata." + + ObjectNode blockCountError = buildErrorAndRepair("dBMetadata." + OzoneConsts.BLOCK_COUNT, blockCountAggregate, blockCountDB, keyRepairAction); errors.add(blockCountError); } // Check and repair used bytes. - JsonElement usedBytesDB = parent.getAsJsonObject("dBMetadata") - .get(OzoneConsts.CONTAINER_BYTES_USED); - JsonElement usedBytesAggregate = parent.getAsJsonObject("aggregates") - .get("usedBytes"); + JsonNode usedBytesDB = + dBMetadata.get(OzoneConsts.CONTAINER_BYTES_USED); + JsonNode usedBytesAggregate = + aggregates.get("usedBytes"); // If used bytes is absent from the DB, it is only an error if there is // a non-zero aggregate of used bytes among the block keys. long usedBytesDBLong = 0; - if (!usedBytesDB.isJsonNull()) { - usedBytesDBLong = usedBytesDB.getAsLong(); + if (usedBytesDB != null && !usedBytesDB.isNull()) { + usedBytesDBLong = usedBytesDB.asLong(); } - if (usedBytesDBLong != usedBytesAggregate.getAsLong()) { + if (usedBytesDBLong != usedBytesAggregate.asLong()) { passed = false; BooleanSupplier keyRepairAction = () -> { boolean repaired = false; try { metadataTable.put(containerData.getBytesUsedKey(), - usedBytesAggregate.getAsLong()); + usedBytesAggregate.asLong()); repaired = true; } catch (IOException ex) { LOG.error("Error repairing used bytes for container {}.", @@ -408,17 +423,17 @@ private boolean checkAndRepair(JsonObject parent, return repaired; }; - JsonObject usedBytesError = buildErrorAndRepair("dBMetadata." + + ObjectNode usedBytesError = buildErrorAndRepair("dBMetadata." + OzoneConsts.CONTAINER_BYTES_USED, usedBytesAggregate, usedBytesDB, keyRepairAction); errors.add(usedBytesError); } // check and repair if db delete count mismatches delete transaction count. - final JsonElement pendingDeleteCountDB = dBMetadata.get( + final JsonNode pendingDeleteCountDB = dBMetadata.get( OzoneConsts.PENDING_DELETE_BLOCK_COUNT); final long dbDeleteCount = jsonToLong(pendingDeleteCountDB); - final JsonElement pendingDeleteCountAggregate + final JsonNode pendingDeleteCountAggregate = aggregates.get(PendingDelete.COUNT); final long deleteTransactionCount = jsonToLong(pendingDeleteCountAggregate); if (dbDeleteCount != deleteTransactionCount) { @@ -437,7 +452,7 @@ private boolean checkAndRepair(JsonObject parent, return false; }; - final JsonObject deleteCountError = buildErrorAndRepair( + final JsonNode deleteCountError = buildErrorAndRepair( "dBMetadata." + OzoneConsts.PENDING_DELETE_BLOCK_COUNT, pendingDeleteCountAggregate, pendingDeleteCountDB, deleteCountRepairAction); @@ -445,9 +460,8 @@ private boolean checkAndRepair(JsonObject parent, } // check and repair chunks dir. - JsonElement chunksDirPresent = parent.getAsJsonObject("chunksDirectory") - .get("present"); - if (!chunksDirPresent.getAsBoolean()) { + JsonNode chunksDirPresent = parent.get("chunksDirectory").get("present"); + if (!chunksDirPresent.asBoolean()) { passed = false; BooleanSupplier dirRepairAction = () -> { @@ -463,32 +477,34 @@ private boolean checkAndRepair(JsonObject parent, return repaired; }; - JsonObject chunksDirError = buildErrorAndRepair("chunksDirectory.present", - new JsonPrimitive(true), chunksDirPresent, dirRepairAction); + ObjectNode chunksDirError = buildErrorAndRepair("chunksDirectory.present", + BooleanNode.getTrue(), chunksDirPresent, dirRepairAction); errors.add(chunksDirError); } - parent.addProperty("correct", passed); - parent.add("errors", errors); + ((ObjectNode) parent).put("correct", passed); + ((ObjectNode) parent).set("errors", errors); return passed; } - static long jsonToLong(JsonElement e) { - return e == null || e.isJsonNull() ? 0 : e.getAsLong(); + static long jsonToLong(JsonNode node) { + return (node == null || node.isNull()) ? 0 : node.asLong(); } - private JsonObject buildErrorAndRepair(String property, JsonElement expected, - JsonElement actual, BooleanSupplier repairAction) { - JsonObject error = new JsonObject(); - error.addProperty("property", property); - error.add("expected", expected); - error.add("actual", actual); + private ObjectNode buildErrorAndRepair(String property, JsonNode expected, + JsonNode actual, BooleanSupplier repairAction) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode error = mapper.createObjectNode(); + + error.put("property", property); + error.set("expected", expected); + error.set("actual", actual); boolean repaired = false; if (mode == Mode.REPAIR) { repaired = repairAction.getAsBoolean(); } - error.addProperty("repaired", repaired); + error.put("repaired", repaired); return error; } @@ -505,9 +521,9 @@ static class PendingDelete { this.bytes = bytes; } - void addToJson(JsonObject json) { - json.addProperty(COUNT, count); - json.addProperty(BYTES, bytes); + void addToJson(ObjectNode json) { + json.put(COUNT, count); // Use Jackson's put method to add properties + json.put(BYTES, bytes); } } diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMetadataInspector.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMetadataInspector.java index 16060a4c387a..5c85c061fc9e 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMetadataInspector.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainerMetadataInspector.java @@ -17,11 +17,11 @@ */ package org.apache.hadoop.ozone.container.keyvalue; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.LongNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.DeletedBlocksTransaction; import org.apache.hadoop.hdds.utils.db.BatchOperation; import org.apache.hadoop.hdds.utils.db.Table; @@ -47,7 +47,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.fail; /** @@ -69,17 +68,17 @@ public void testRunDisabled(ContainerTestVersionInfo versionInfo) // No system property set. Should not run. System.clearProperty(KeyValueContainerMetadataInspector.SYSTEM_PROPERTY); ContainerInspectorUtil.load(); - assertNull(runInspectorAndGetReport(containerData)); + assertTrue(runInspectorAndGetReport(containerData).isEmpty()); ContainerInspectorUtil.unload(); // Unloaded. Should not run even with system property. System.setProperty(KeyValueContainerMetadataInspector.SYSTEM_PROPERTY, KeyValueContainerMetadataInspector.Mode.INSPECT.toString()); - assertNull(runInspectorAndGetReport(containerData)); + assertTrue(runInspectorAndGetReport(containerData).isEmpty()); // Unloaded and no system property. Should not run. System.clearProperty(KeyValueContainerMetadataInspector.SYSTEM_PROPERTY); - assertNull(runInspectorAndGetReport(containerData)); + assertTrue(runInspectorAndGetReport(containerData).isEmpty()); } @ContainerTestVersionInfo.ContainerTest @@ -273,11 +272,11 @@ public void testIncorrectDeleteWithoutTransaction( public void inspectThenRepairOnCorrectContainer( KeyValueContainerData containerData) throws Exception { // No output for correct containers. - assertNull(runInspectorAndGetReport(containerData, - KeyValueContainerMetadataInspector.Mode.INSPECT)); + assertTrue(runInspectorAndGetReport(containerData, + KeyValueContainerMetadataInspector.Mode.INSPECT).isEmpty()); - assertNull(runInspectorAndGetReport(containerData, - KeyValueContainerMetadataInspector.Mode.REPAIR)); + assertTrue(runInspectorAndGetReport(containerData, + KeyValueContainerMetadataInspector.Mode.REPAIR).isEmpty()); } /** @@ -312,8 +311,9 @@ public void inspectThenRepairOnIncorrectContainer( String containerState = containerData.getState().toString(); // First inspect the container. - JsonObject inspectJson = runInspectorAndGetReport(containerData, - KeyValueContainerMetadataInspector.Mode.INSPECT); + ObjectNode inspectJson = + (ObjectNode) runInspectorAndGetReport(containerData, + KeyValueContainerMetadataInspector.Mode.INSPECT); checkJsonReportForIncorrectContainer(inspectJson, containerState, createdBlocks, setBlocks, createdBytes, setBytes, @@ -322,7 +322,7 @@ public void inspectThenRepairOnIncorrectContainer( checkDbCounts(containerData, setBlocks, setBytes, deleteCount); // Now repair the container. - JsonObject repairJson = runInspectorAndGetReport(containerData, + ObjectNode repairJson = (ObjectNode) runInspectorAndGetReport(containerData, KeyValueContainerMetadataInspector.Mode.REPAIR); checkJsonReportForIncorrectContainer(repairJson, containerState, createdBlocks, setBlocks, createdBytes, setBytes, @@ -333,38 +333,38 @@ public void inspectThenRepairOnIncorrectContainer( } @SuppressWarnings("checkstyle:ParameterNumber") - private void checkJsonReportForIncorrectContainer(JsonObject inspectJson, + private void checkJsonReportForIncorrectContainer(ObjectNode inspectJson, String expectedContainerState, long createdBlocks, long setBlocks, long createdBytes, long setBytes, long createdFiles, long setPendingDeleteCount, long createdPendingDeleteCount, boolean shouldRepair) { // Check main container properties. - assertEquals(inspectJson.get("containerID").getAsLong(), + assertEquals(inspectJson.get("containerID").asLong(), CONTAINER_ID); - assertEquals(inspectJson.get("containerState").getAsString(), + assertEquals(inspectJson.get("containerState").asText(), expectedContainerState); // Check DB metadata. - JsonObject jsonDbMetadata = inspectJson.getAsJsonObject("dBMetadata"); + ObjectNode jsonDbMetadata = (ObjectNode) inspectJson.get("dBMetadata"); assertEquals(setBlocks, - jsonDbMetadata.get(OzoneConsts.BLOCK_COUNT).getAsLong()); + jsonDbMetadata.get(OzoneConsts.BLOCK_COUNT).asLong()); assertEquals(setBytes, - jsonDbMetadata.get(OzoneConsts.CONTAINER_BYTES_USED).getAsLong()); + jsonDbMetadata.get(OzoneConsts.CONTAINER_BYTES_USED).asLong()); // Check aggregate metadata values. - JsonObject jsonAggregates = inspectJson.getAsJsonObject("aggregates"); + ObjectNode jsonAggregates = (ObjectNode) inspectJson.get("aggregates"); assertEquals(createdBlocks, - jsonAggregates.get("blockCount").getAsLong()); + jsonAggregates.get("blockCount").asLong()); assertEquals(createdBytes, - jsonAggregates.get("usedBytes").getAsLong()); + jsonAggregates.get("usedBytes").asLong()); assertEquals(createdPendingDeleteCount, - jsonAggregates.get("pendingDeleteBlocks").getAsLong()); + jsonAggregates.get("pendingDeleteBlocks").asLong()); // Check chunks directory. - JsonObject jsonChunksDir = inspectJson.getAsJsonObject("chunksDirectory"); - assertTrue(jsonChunksDir.get("present").getAsBoolean()); + ObjectNode jsonChunksDir = (ObjectNode) inspectJson.get("chunksDirectory"); + assertTrue(jsonChunksDir.get("present").asBoolean()); assertEquals(createdFiles, - jsonChunksDir.get("fileCount").getAsLong()); + jsonChunksDir.get("fileCount").asLong()); // Check errors. checkJsonErrorsReport(inspectJson, "dBMetadata.#BLOCKCOUNT", @@ -376,15 +376,15 @@ private void checkJsonReportForIncorrectContainer(JsonObject inspectJson, } private void checkJsonErrorsReport( - JsonObject jsonReport, String propertyValue, + ObjectNode jsonReport, String propertyValue, long correctExpected, long correctActual, boolean correctRepair) { if (correctExpected == correctActual) { return; } checkJsonErrorsReport(jsonReport, propertyValue, - new JsonPrimitive(correctExpected), - new JsonPrimitive(correctActual), + LongNode.valueOf(correctExpected), + LongNode.valueOf(correctActual), correctRepair); } @@ -392,32 +392,31 @@ private void checkJsonErrorsReport( * Checks the erorr list in the provided JsonReport for an error matching * the template passed in with the parameters. */ - private void checkJsonErrorsReport(JsonObject jsonReport, - String propertyValue, JsonPrimitive correctExpected, - JsonPrimitive correctActual, boolean correctRepair) { + private void checkJsonErrorsReport(ObjectNode jsonReport, + String propertyValue, + JsonNode correctExpected, + JsonNode correctActual, + boolean correctRepair) { - assertFalse(jsonReport.get("correct").getAsBoolean()); + assertFalse(jsonReport.get("correct").asBoolean()); - JsonArray jsonErrors = jsonReport.getAsJsonArray("errors"); + ArrayNode jsonErrors = (ArrayNode) jsonReport.get("errors"); boolean matchFound = false; - for (JsonElement jsonErrorElem: jsonErrors) { - JsonObject jsonErrorObject = jsonErrorElem.getAsJsonObject(); + for (JsonNode jsonErrorElem: jsonErrors) { + ObjectNode jsonErrorObject = (ObjectNode) jsonErrorElem; String thisProperty = - jsonErrorObject.get("property").getAsString(); + jsonErrorObject.get("property").asText(); if (thisProperty.equals(propertyValue)) { matchFound = true; - JsonPrimitive expectedJsonPrim = - jsonErrorObject.get("expected").getAsJsonPrimitive(); - assertEquals(correctExpected, expectedJsonPrim); + JsonNode expectedJsonPrim = jsonErrorObject.get("expected"); + assertEquals(correctExpected.longValue(), expectedJsonPrim.longValue()); - JsonPrimitive actualJsonPrim = - jsonErrorObject.get("actual").getAsJsonPrimitive(); - assertEquals(correctActual, actualJsonPrim); + JsonNode actualJsonPrim = jsonErrorObject.get("actual"); + assertEquals(correctActual.longValue(), actualJsonPrim.longValue()); - boolean repaired = - jsonErrorObject.get("repaired").getAsBoolean(); + boolean repaired = jsonErrorObject.get("repaired").asBoolean(); assertEquals(correctRepair, repaired); break; } @@ -496,20 +495,20 @@ void checkDbCounts(KeyValueContainerData containerData, } } - private JsonObject runInspectorAndGetReport( + private JsonNode runInspectorAndGetReport( KeyValueContainerData containerData, KeyValueContainerMetadataInspector.Mode mode) throws Exception { System.setProperty(KeyValueContainerMetadataInspector.SYSTEM_PROPERTY, mode.toString()); ContainerInspectorUtil.load(); - JsonObject json = runInspectorAndGetReport(containerData); + JsonNode json = runInspectorAndGetReport(containerData); ContainerInspectorUtil.unload(); System.clearProperty(KeyValueContainerMetadataInspector.SYSTEM_PROPERTY); return json; } - private JsonObject runInspectorAndGetReport( + private JsonNode runInspectorAndGetReport( KeyValueContainerData containerData) throws Exception { // Use an empty layout so the captured log has no prefix and can be // parsed as json. @@ -522,7 +521,9 @@ private JsonObject runInspectorAndGetReport( String output = capturer.getOutput(); capturer.clearOutput(); - return new Gson().fromJson(output, JsonObject.class); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readTree(output); + return node; } private KeyValueContainer createClosedContainer(int normalBlocks) diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java index ae74bc048af0..589f83ac091c 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java @@ -28,13 +28,13 @@ import java.util.Map; import java.util.Properties; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import org.apache.hadoop.hdds.annotation.InterfaceAudience; import org.apache.hadoop.hdds.annotation.InterfaceStability; import org.apache.hadoop.hdds.server.http.HttpServer2; import com.google.common.annotations.VisibleForTesting; -import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -145,12 +145,12 @@ public BadFormatException(String msg) { private void processConfigTagRequest(HttpServletRequest request, String cmd, Writer out) throws IOException { - Gson gson = new Gson(); + ObjectMapper objectMapper = new ObjectMapper(); OzoneConfiguration config = getOzoneConfig(); switch (cmd) { case "getOzoneTags": - out.write(gson.toJson(OzoneConfiguration.TAGS)); + out.write(objectMapper.writeValueAsString(OzoneConfiguration.TAGS)); break; case "getPropertyByTag": String tags = request.getParameter("tags"); @@ -170,7 +170,7 @@ private void processConfigTagRequest(HttpServletRequest request, String cmd, } } } - out.write(gson.toJsonTree(propMap).toString()); + out.write(objectMapper.writeValueAsString(propMap)); break; default: throw new IllegalArgumentException(cmd + " is not a valid command."); diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/container/common/helpers/DeletedBlocksTransactionInfoWrapper.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/container/common/helpers/DeletedBlocksTransactionInfoWrapper.java index 64ced8dce4e2..5106528a026f 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/container/common/helpers/DeletedBlocksTransactionInfoWrapper.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/container/common/helpers/DeletedBlocksTransactionInfoWrapper.java @@ -17,6 +17,8 @@ */ package org.apache.hadoop.hdds.scm.container.common.helpers; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DeletedBlocksTransactionInfo; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.DeletedBlocksTransaction; import java.util.List; @@ -31,8 +33,14 @@ public class DeletedBlocksTransactionInfoWrapper { private final List localIdList; private final int count; - public DeletedBlocksTransactionInfoWrapper(long txID, long containerID, - List localIdList, int count) { + // Used @JsonCreator to indicate that Jackson should use this constructor for + // deserialization + @JsonCreator + public DeletedBlocksTransactionInfoWrapper( + @JsonProperty("txID") long txID, + @JsonProperty("containerID") long containerID, + @JsonProperty("localIdList") List localIdList, + @JsonProperty("count") int count) { this.txID = txID; this.containerID = containerID; this.localIdList = localIdList; diff --git a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java index defeec2533ae..3823170d5f57 100644 --- a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java +++ b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java @@ -26,8 +26,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; -import com.google.gson.Gson; import org.apache.hadoop.hdds.server.http.HttpServer2; import org.apache.hadoop.util.XMLUtils; import org.eclipse.jetty.util.ajax.JSON; @@ -109,8 +109,10 @@ public void testGetPropertyWithCmd() throws Exception { conf.getObject(OzoneTestConfig.class); // test cmd is getOzoneTags String result = getResultWithCmd(conf, "getOzoneTags"); - Gson gson = new Gson(); - String tags = gson.toJson(OzoneConfiguration.TAGS); + + ObjectMapper objectMapper = new ObjectMapper(); + String tags = objectMapper.writeValueAsString(OzoneConfiguration.TAGS); + assertEquals(result, tags); // cmd is getPropertyByTag result = getResultWithCmd(conf, "getPropertyByTag"); diff --git a/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot b/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot index 6ac38ccc321c..789d43dc66b3 100644 --- a/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot +++ b/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot @@ -30,7 +30,7 @@ ${S3G_ENDPOINT_URL} http://s3g:9878 Create Tenant Success with Cluster Admin Run Keyword Kinit test user testuser testuser.keytab ${output} = Execute ozone tenant --verbose create tenantone - Should contain ${output} "tenantId": "tenantone" + Should contain ${output} "tenantId" : "tenantone" Assign User Success with Cluster Admin ${output} = Execute ozone tenant --verbose user assign testuser --tenant=tenantone diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/RangerUserRequest.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/RangerUserRequest.java index 07bb3cf96270..adb76ed93e94 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/RangerUserRequest.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/RangerUserRequest.java @@ -17,10 +17,9 @@ */ package org.apache.hadoop.ozone.om.multitenant; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.kerby.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -215,14 +214,16 @@ public String getUserId(String userPrincipal) throws IOException { String response = getResponseData(conn); String userIDCreated = null; try { - JsonObject jResonse = JsonParser.parseString(response).getAsJsonObject(); - JsonArray userinfo = jResonse.get("vXUsers").getAsJsonArray(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jResponse = objectMapper.readTree(response); + JsonNode userinfo = jResponse.path("vXUsers"); int numIndex = userinfo.size(); + for (int i = 0; i < numIndex; ++i) { - if (userinfo.get(i).getAsJsonObject().get("name").getAsString() - .equals(userPrincipal)) { - userIDCreated = - userinfo.get(i).getAsJsonObject().get("id").getAsString(); + JsonNode userNode = userinfo.get(i); + String name = userNode.path("name").asText(); + if (name.equals(userPrincipal)) { + userIDCreated = userNode.path("id").asText(); break; } } @@ -231,6 +232,7 @@ public String getUserId(String userPrincipal) throws IOException { e.printStackTrace(); throw e; } + return userIDCreated; } @@ -253,8 +255,9 @@ public String createUser(String userName, String password) String userId; try { assert userInfo != null; - JsonObject jObject = JsonParser.parseString(userInfo).getAsJsonObject(); - userId = jObject.get("id").getAsString(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jNode = objectMapper.readTree(userInfo); + userId = jNode.get("id").asText(); LOG.debug("Ranger returned userId: {}", userId); } catch (JsonParseException e) { e.printStackTrace(); diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/recon/TestReconWithOzoneManager.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/recon/TestReconWithOzoneManager.java index 9589b1c40056..39f043ee22c1 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/recon/TestReconWithOzoneManager.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/recon/TestReconWithOzoneManager.java @@ -40,6 +40,7 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; +import com.google.gson.internal.LinkedTreeMap; import org.apache.hadoop.hdds.client.BlockID; import org.apache.hadoop.hdds.client.StandaloneReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -64,9 +65,9 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; -import com.google.gson.Gson; -import com.google.gson.internal.LinkedTreeMap; import org.apache.ozone.test.GenericTestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -381,16 +382,21 @@ private static OmKeyLocationInfoGroup getOmKeyLocationInfoGroup() { private long getReconTaskAttributeFromJson(String taskStatusResponse, String taskName, - String entityAttribute) { - ArrayList taskStatusList = new Gson() - .fromJson(taskStatusResponse, ArrayList.class); + String entityAttribute) + throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + ArrayList taskStatusList = objectMapper.readValue( + taskStatusResponse, new TypeReference>() { + }); + Optional taskEntity = taskStatusList .stream() .filter(task -> task.get("taskName").equals(taskName)) .findFirst(); assertTrue(taskEntity.isPresent()); - return (long) (double) taskEntity.get().get(entityAttribute); + Number number = (Number) taskEntity.get().get(entityAttribute); + return number.longValue(); } /** diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneDebugShell.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneDebugShell.java index 05e26200aa0d..15d9746fcb6a 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneDebugShell.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneDebugShell.java @@ -77,8 +77,6 @@ public class TestOzoneDebugShell { private static String omServiceId; - private static String clusterId; - private static String scmId; private static MiniOzoneCluster cluster = null; private static OzoneClient client; @@ -88,13 +86,8 @@ public class TestOzoneDebugShell { protected static void startCluster() throws Exception { // Init HA cluster omServiceId = "om-service-test1"; - clusterId = UUID.randomUUID().toString(); - scmId = UUID.randomUUID().toString(); final int numDNs = 3; cluster = MiniOzoneCluster.newBuilder(conf) - .setClusterId(clusterId) - .setScmId(scmId) - .setOMServiceId(omServiceId) .setNumDatanodes(numDNs) .build(); cluster.waitForClusterToBeReady(); diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java index 6bd3f5f22f49..1a45fa521e33 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java @@ -28,7 +28,11 @@ import java.util.HashSet; import java.util.List; import java.util.UUID; +import java.util.LinkedHashMap; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.hadoop.crypto.key.KeyProvider; import org.apache.hadoop.crypto.key.kms.KMSClientProvider; import org.apache.hadoop.crypto.key.kms.server.MiniKMS; @@ -68,8 +72,6 @@ import org.apache.hadoop.ozone.om.TrashPolicyOzone; import com.google.common.base.Strings; -import com.google.gson.Gson; -import com.google.gson.internal.LinkedTreeMap; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY; @@ -416,9 +418,17 @@ private int getNumOfBuckets(String bucketPrefix) * Parse output into ArrayList with Gson. * @return ArrayList */ - private ArrayList> parseOutputIntoArrayList() + private ArrayList> parseOutputIntoArrayList() throws UnsupportedEncodingException { - return new Gson().fromJson(out.toString(DEFAULT_ENCODING), ArrayList.class); + ObjectMapper objectMapper = new ObjectMapper(); + String jsonOutput = out.toString(DEFAULT_ENCODING); + try { + return objectMapper.readValue(jsonOutput, + new TypeReference>>() { + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } } @Test @@ -1672,8 +1682,9 @@ public void testListVolumeBucketKeyShouldPrintValidJsonArray() execute(ozoneShell, new String[] {"volume", "list"}); // Expect valid JSON array - final ArrayList> volumeListOut = + final ArrayList> volumeListOut = parseOutputIntoArrayList(); + // Can include s3v and volumes from other test cases that aren't cleaned up, // hence >= instead of equals. assertThat(volumeListOut.size()).isGreaterThanOrEqualTo(testVolumes.size()); @@ -1687,7 +1698,7 @@ public void testListVolumeBucketKeyShouldPrintValidJsonArray() execute(ozoneShell, new String[] {"bucket", "list", firstVolumePrefix}); // Expect valid JSON array as well - final ArrayList> bucketListOut = + final ArrayList> bucketListOut = parseOutputIntoArrayList(); assertEquals(testBuckets.size(), bucketListOut.size()); final HashSet bucketSet = new HashSet<>(testBuckets); @@ -1700,7 +1711,7 @@ public void testListVolumeBucketKeyShouldPrintValidJsonArray() execute(ozoneShell, new String[] {"key", "list", keyPathPrefix}); // Expect valid JSON array as well - final ArrayList> keyListOut = + final ArrayList> keyListOut = parseOutputIntoArrayList(); assertEquals(testKeys.size(), keyListOut.size()); final HashSet keySet = new HashSet<>(testKeys); @@ -1952,7 +1963,7 @@ public void testLinkedAndNonLinkedBucketMetaData() execute(ozoneShell, new String[] {"bucket", "list", "/volume1"}); // Expect valid JSON array - final ArrayList> bucketListOut = + final ArrayList> bucketListOut = parseOutputIntoArrayList(); assertEquals(1, bucketListOut.size()); @@ -1971,7 +1982,7 @@ public void testLinkedAndNonLinkedBucketMetaData() execute(ozoneShell, new String[] {"bucket", "list", "/volume1"}); // Expect valid JSON array - final ArrayList> bucketListLinked = + final ArrayList> bucketListLinked = parseOutputIntoArrayList(); assertEquals(2, bucketListLinked.size()); diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java index 8b9866aef459..0db54de76b1f 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneTenantShell.java @@ -339,7 +339,7 @@ private void checkOutput(ByteArrayOutputStream stream, String stringToMatch, } private void checkOutput(ByteArrayOutputStream stream, String stringToMatch, - boolean exactMatch, boolean expectValidJSON) throws IOException { + boolean exactMatch, boolean expectValidJSON) throws IOException { stream.flush(); final String str = stream.toString(DEFAULT_ENCODING); if (expectValidJSON) { @@ -353,6 +353,8 @@ private void checkOutput(ByteArrayOutputStream stream, String stringToMatch, private void checkOutput(String str, String stringToMatch, boolean exactMatch) { + LOG.error("str = \n" + str); + LOG.error("stringToMatch = \n" + stringToMatch); if (exactMatch) { assertEquals(stringToMatch, str); } else { @@ -388,17 +390,17 @@ public void testAssignAdmin() throws IOException { executeHA(tenantShell, new String[] {"--verbose", "user", "assign-admin", tenantName + "$" + userName, "--tenant=" + tenantName, "--delegated=true"}); - checkOutput(out, "{\n" + " \"accessId\": \"devaa$alice\",\n" - + " \"tenantId\": \"devaa\",\n" + " \"isAdmin\": true,\n" - + " \"isDelegatedAdmin\": true\n" + "}\n", true, true); + checkOutput(out, "{\n" + " \"accessId\" : \"devaa$alice\",\n" + + " \"tenantId\" : \"devaa\",\n" + " \"isAdmin\" : true,\n" + + " \"isDelegatedAdmin\" : true\n" + "}\n", true, true); checkOutput(err, "", true); // Clean up executeHA(tenantShell, new String[] {"--verbose", "user", "revoke-admin", tenantName + "$" + userName, "--tenant=" + tenantName}); - checkOutput(out, "{\n" + " \"accessId\": \"devaa$alice\",\n" - + " \"tenantId\": \"devaa\",\n" + " \"isAdmin\": false,\n" - + " \"isDelegatedAdmin\": false\n" + "}\n", true, true); + checkOutput(out, "{\n" + " \"accessId\" : \"devaa$alice\",\n" + + " \"tenantId\" : \"devaa\",\n" + " \"isAdmin\" : false,\n" + + " \"isDelegatedAdmin\" : false\n" + "}\n", true, true); checkOutput(err, "", true); executeHA(tenantShell, new String[] { @@ -471,7 +473,7 @@ public void testOzoneTenantBasicOperations() throws IOException { executeHA(tenantShell, new String[] {"list", "--json"}); // Not checking the full output here - checkOutput(out, "\"tenantId\": \"dev\",", false); + checkOutput(out, "\"tenantId\" : \"dev\",", false); checkOutput(err, "", true); // Attempt user getsecret before assignment, should fail @@ -540,17 +542,28 @@ public void testOzoneTenantBasicOperations() throws IOException { executeHA(tenantShell, new String[] { "user", "info", "--json", "bob"}); - checkOutput(out, "{\n" + " \"user\": \"bob\",\n" + " \"tenants\": [\n" - + " {\n" + " \"accessId\": \"research$bob\",\n" - + " \"tenantId\": \"research\",\n" + " \"isAdmin\": false,\n" - + " \"isDelegatedAdmin\": false\n" + " },\n" + " {\n" - + " \"accessId\": \"finance$bob\",\n" - + " \"tenantId\": \"finance\",\n" + " \"isAdmin\": false,\n" - + " \"isDelegatedAdmin\": false\n" + " },\n" + " {\n" - + " \"accessId\": \"dev$bob\",\n" - + " \"tenantId\": \"dev\",\n" + " \"isAdmin\": true,\n" - + " \"isDelegatedAdmin\": true\n" + " }\n" + " ]\n" + "}\n", + checkOutput(out, + "{\n" + + " \"user\" : \"bob\",\n" + + " \"tenants\" : [ {\n" + + " \"accessId\" : \"research$bob\",\n" + + " \"tenantId\" : \"research\",\n" + + " \"isAdmin\" : false,\n" + + " \"isDelegatedAdmin\" : false\n" + + " }, {\n" + + " \"accessId\" : \"finance$bob\",\n" + + " \"tenantId\" : \"finance\",\n" + + " \"isAdmin\" : false,\n" + + " \"isDelegatedAdmin\" : false\n" + + " }, {\n" + + " \"accessId\" : \"dev$bob\",\n" + + " \"tenantId\" : \"dev\",\n" + + " \"isAdmin\" : true,\n" + + " \"isDelegatedAdmin\" : true\n" + + " } ]\n" + + "}\n", true, true); + checkOutput(err, "", true); // Revoke admin @@ -675,8 +688,8 @@ public void testOzoneTenantBasicOperations() throws IOException { // Then delete tenant, should succeed executeHA(tenantShell, new String[] {"--verbose", "delete", "dev"}); - checkOutput(out, "{\n" + " \"tenantId\": \"dev\",\n" - + " \"volumeName\": \"dev\",\n" + " \"volumeRefCount\": 0\n" + "}\n", + checkOutput(out, "{\n" + " \"tenantId\" : \"dev\",\n" + + " \"volumeName\" : \"dev\",\n" + " \"volumeRefCount\" : 0\n" + "}\n", true, true); checkOutput(err, "Deleted tenant 'dev'.\n", false); deleteVolume("dev"); @@ -691,7 +704,7 @@ public void testOzoneTenantBasicOperations() throws IOException { public void testListTenantUsers() throws IOException { executeHA(tenantShell, new String[] {"--verbose", "create", "tenant1"}); checkOutput(out, "{\n" + - " \"tenantId\": \"tenant1\"\n" + "}\n", true, true); + " \"tenantId\" : \"tenant1\"\n" + "}\n", true, true); checkOutput(err, "", true); executeHA(tenantShell, new String[] { @@ -715,10 +728,14 @@ public void testListTenantUsers() throws IOException { executeHA(tenantShell, new String[] { "user", "list", "tenant1", "--json"}); - checkOutput(out, "[\n" + " {\n" + " \"user\": \"bob\",\n" - + " \"accessId\": \"tenant1$bob\"\n" + " },\n" + " {\n" - + " \"user\": \"alice\",\n" + " \"accessId\": \"tenant1$alice\"\n" - + " }\n" + "]\n", true); + checkOutput(out, + "[ {\n" + + " \"user\" : \"bob\",\n" + + " \"accessId\" : \"tenant1$bob\"\n" + + "}, {\n" + + " \"user\" : \"alice\",\n" + + " \"accessId\" : \"tenant1$alice\"\n" + + "} ]\n", true); checkOutput(err, "", true); executeHA(tenantShell, new String[] { @@ -729,8 +746,10 @@ public void testListTenantUsers() throws IOException { executeHA(tenantShell, new String[] { "user", "list", "tenant1", "--prefix=b", "--json"}); - checkOutput(out, "[\n" + " {\n" + " \"user\": \"bob\",\n" - + " \"accessId\": \"tenant1$bob\"\n" + " }\n" + "]\n", true); + checkOutput(out, "[ {\n" + + " \"user\" : \"bob\",\n" + + " \"accessId\" : \"tenant1$bob\"\n" + + "} ]\n", true); checkOutput(err, "", true); int exitCode = executeHA(tenantShell, new String[] { diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/heatmap/TestHeatMapInfo.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/heatmap/TestHeatMapInfo.java index 856b556e8af2..ebea8673439d 100644 --- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/heatmap/TestHeatMapInfo.java +++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/heatmap/TestHeatMapInfo.java @@ -18,10 +18,8 @@ package org.apache.hadoop.ozone.recon.heatmap; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import org.apache.hadoop.hdds.scm.server.OzoneStorageContainerManager; import org.apache.hadoop.ozone.recon.ReconTestInjector; import org.apache.hadoop.ozone.recon.api.types.EntityMetaData; @@ -744,23 +742,26 @@ public void setUp() throws Exception { @Test public void testHeatMapGeneratedInfo() throws IOException { // Setup - // Run the test - JsonElement jsonElement = JsonParser.parseString(auditRespStr); - JsonObject jsonObject = jsonElement.getAsJsonObject(); - JsonElement facets = jsonObject.get("facets"); - JsonObject facetsBucketsObject = - facets.getAsJsonObject().get("resources") - .getAsJsonObject(); + // Initialize ObjectMapper ObjectMapper objectMapper = new ObjectMapper(); + // Parse the JSON string to a JsonNode + JsonNode rootNode = objectMapper.readTree(auditRespStr); + JsonNode facets = rootNode.path("facets"); + JsonNode facetsBucketsObject = facets.path("resources"); + + // Directly deserialize the specific part of the JSON structure to your Java object HeatMapProviderDataResource auditLogFacetsResources = - objectMapper.readValue( - facetsBucketsObject.toString(), HeatMapProviderDataResource.class); + objectMapper.treeToValue(facetsBucketsObject, HeatMapProviderDataResource.class); + EntityMetaData[] entities = auditLogFacetsResources.getMetaDataList(); List entityMetaDataList = Arrays.stream(entities).collect(Collectors.toList()); + EntityReadAccessHeatMapResponse entityReadAccessHeatMapResponse = heatMapUtil.generateHeatMap(entityMetaDataList); + + // Assertions remain unchanged assertThat(entityReadAccessHeatMapResponse.getChildren().size()).isGreaterThan(0); assertEquals(12, entityReadAccessHeatMapResponse.getChildren().size()); assertEquals(25600, entityReadAccessHeatMapResponse.getSize()); @@ -831,20 +832,22 @@ public void testHeatMapInfoResponseWithEntityTypeVolume() throws IOException { " }\n" + " }\n" + "}"; - JsonElement jsonElement = - JsonParser.parseString(auditRespStrWithVolumeEntityType); - JsonObject jsonObject = jsonElement.getAsJsonObject(); - JsonElement facets = jsonObject.get("facets"); - JsonElement resources = facets.getAsJsonObject().get("resources"); - JsonObject facetsBucketsObject = new JsonObject(); - if (null != resources) { - facetsBucketsObject = resources.getAsJsonObject(); - } ObjectMapper objectMapper = new ObjectMapper(); + // Parse the JSON string to a JsonNode + JsonNode rootNode = objectMapper.readTree(auditRespStrWithVolumeEntityType); + JsonNode facets = rootNode.path("facets"); + JsonNode resources = facets.path("resources"); + JsonNode facetsBucketsObject = resources; + + // Check if resources is not null or missing + if (!resources.isMissingNode()) { + facetsBucketsObject = resources; + } + HeatMapProviderDataResource auditLogFacetsResources = - objectMapper.readValue( - facetsBucketsObject.toString(), HeatMapProviderDataResource.class); + objectMapper.treeToValue( + facetsBucketsObject, HeatMapProviderDataResource.class); EntityMetaData[] entities = auditLogFacetsResources.getMetaDataList(); if (null != entities && entities.length > 0) { List entityMetaDataList = @@ -965,20 +968,22 @@ public void testHeatMapInfoResponseWithEntityTypeBucket() throws IOException { " }\n" + " }\n" + "}"; - JsonElement jsonElement = - JsonParser.parseString(auditRespStrWithPathAndBucketEntityType); - JsonObject jsonObject = jsonElement.getAsJsonObject(); - JsonElement facets = jsonObject.get("facets"); - JsonElement resources = facets.getAsJsonObject().get("resources"); - JsonObject facetsBucketsObject = new JsonObject(); - if (null != resources) { - facetsBucketsObject = resources.getAsJsonObject(); - } ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = + objectMapper.readTree(auditRespStrWithPathAndBucketEntityType); + JsonNode facets = rootNode.path("facets"); + JsonNode resources = facets.path("resources"); + JsonNode facetsBucketsObject = + objectMapper.createObjectNode(); // Create an empty node as default + + if (!resources.isMissingNode()) { + facetsBucketsObject = resources; + } + HeatMapProviderDataResource auditLogFacetsResources = - objectMapper.readValue( - facetsBucketsObject.toString(), HeatMapProviderDataResource.class); + objectMapper.treeToValue( + facetsBucketsObject, HeatMapProviderDataResource.class); EntityMetaData[] entities = auditLogFacetsResources.getMetaDataList(); if (null != entities && entities.length > 0) { List entityMetaDataList = diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/DiskUsageSubCommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/DiskUsageSubCommand.java index 0585fea000c9..45295fb5b4e4 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/DiskUsageSubCommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/DiskUsageSubCommand.java @@ -110,7 +110,7 @@ public Void call() throws Exception { printBucketReminder(); } - long totalSize = (long)(double)duResponse.get("size"); + long totalSize = ((Number) duResponse.get("size")).longValue(); if (!noHeader) { printWithUnderline("Path", false); @@ -124,11 +124,12 @@ public Void call() throws Exception { if (withReplica) { printWithUnderline("Total Disk Usage", false); printKVSeparator(); - long du = (long)(double)duResponse.get("sizeWithReplica"); + long du = ((Number) duResponse.get("sizeWithReplica")).longValue(); System.out.println(FileUtils.byteCountToDisplaySize(du)); } - long sizeDirectKey = (long)(double)duResponse.get("sizeDirectKey"); + long sizeDirectKey = + ((Number) duResponse.get("sizeDirectKey")).longValue(); if (!listFiles && sizeDirectKey != -1) { printWithUnderline("Size of Direct Keys", false); printKVSeparator(); @@ -137,7 +138,7 @@ public Void call() throws Exception { printNewLines(1); } - if ((double)duResponse.get("subPathCount") == 0) { + if (((Number) duResponse.get("subPathCount")).doubleValue() == 0) { if (totalSize == 0) { // the object is empty System.out.println("The object is empty.\n" + @@ -160,20 +161,20 @@ public Void call() throws Exception { seekStr = ""; } - ArrayList duData = (ArrayList)duResponse.get("subPaths"); + ArrayList duData = (ArrayList) duResponse.get("subPaths"); int cnt = 0; - for (int i = 0; i < duData.size(); ++i) { + for (Object o : duData) { if (cnt >= limit) { break; } - LinkedTreeMap subPathDU = (LinkedTreeMap) duData.get(i); - String subPath = subPathDU.get("path").toString(); - // differentiate key from other types - if (!(boolean)subPathDU.get("isKey")) { + LinkedTreeMap subPathDU = (LinkedTreeMap) o; + String subPath = (String) subPathDU.get("path"); + if (!(Boolean) subPathDU.get("isKey")) { subPath += OM_KEY_PREFIX; } - long size = (long)(double)subPathDU.get("size"); - long sizeWithReplica = (long)(double)subPathDU.get("sizeWithReplica"); + long size = ((Number) subPathDU.get("size")).longValue(); + long sizeWithReplica = + ((Number) subPathDU.get("sizeWithReplica")).longValue(); if (subPath.startsWith(seekStr)) { printDURow(subPath, size, sizeWithReplica); ++cnt; diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/FileSizeDistSubCommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/FileSizeDistSubCommand.java index f74ee109504c..2c76ca82dcde 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/FileSizeDistSubCommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/FileSizeDistSubCommand.java @@ -85,11 +85,11 @@ public Void call() throws Exception { } printWithUnderline("File Size Distribution", true); - ArrayList fileSizeDist = (ArrayList) distResponse.get("dist"); + ArrayList fileSizeDist = (ArrayList) distResponse.get("dist"); double sum = 0; - for (int i = 0; i < fileSizeDist.size(); ++i) { - sum += (double) fileSizeDist.get(i); + for (Object obj : fileSizeDist) { + sum += ((Number) obj).doubleValue(); } if (sum == 0) { printSpaces(2); @@ -100,11 +100,12 @@ public Void call() throws Exception { } for (int i = 0; i < fileSizeDist.size(); ++i) { - if ((double)fileSizeDist.get(i) == 0) { + double count = ((Number) fileSizeDist.get(i)).doubleValue(); + if (count == 0) { continue; } String label = convertBinIndexToReadableRange(i); - printDistRow(label, (double) fileSizeDist.get(i), sum); + printDistRow(label, count, sum); } } printNewLines(1); diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/NSSummaryCLIUtils.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/NSSummaryCLIUtils.java index 729aa20c5ce3..f1d154bcde57 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/NSSummaryCLIUtils.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/NSSummaryCLIUtils.java @@ -18,7 +18,8 @@ package org.apache.hadoop.ozone.admin.nssummary; -import com.google.gson.Gson; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.IOUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdds.conf.ConfigurationSource; @@ -26,6 +27,7 @@ import picocli.CommandLine.Help.Ansi; import javax.security.sasl.AuthenticationException; +import java.io.IOException; import java.io.InputStream; import java.net.ConnectException; import java.net.HttpURLConnection; @@ -107,8 +109,12 @@ public static String makeHttpCall(StringBuffer url, String path, } } - public static HashMap getResponseMap(String response) { - return new Gson().fromJson(response, HashMap.class); + public static HashMap getResponseMap(String response) + throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(response, + new TypeReference>() { + }); } public static void printNewLines(int cnt) { diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/QuotaUsageSubCommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/QuotaUsageSubCommand.java index 113193c929b4..58ed0a027af4 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/QuotaUsageSubCommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/QuotaUsageSubCommand.java @@ -85,8 +85,10 @@ public Void call() throws Exception { } printWithUnderline("Quota", true); - long quotaAllowed = (long)(double)quotaResponse.get("allowed"); - long quotaUsed = (long)(double)quotaResponse.get("used"); + + long quotaAllowed = ((Number) quotaResponse.get("allowed")).longValue(); + long quotaUsed = ((Number) quotaResponse.get("used")).longValue(); + printSpaces(2); System.out.print("Allowed"); printKVSeparator(); diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/SummarySubCommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/SummarySubCommand.java index 9180274b9c70..aba4cdf76ca0 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/SummarySubCommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/nssummary/SummarySubCommand.java @@ -83,10 +83,11 @@ public Void call() throws Exception { printWithUnderline("Entity Type", false); printKVSeparator(); System.out.println(summaryResponse.get("type")); - int numVol = ((Double) summaryResponse.get("numVolume")).intValue(); - int numBucket = ((Double) summaryResponse.get("numBucket")).intValue(); - int numDir = ((Double) summaryResponse.get("numDir")).intValue(); - int numKey = ((Double) summaryResponse.get("numKey")).intValue(); + + int numVol = ((Number) summaryResponse.get("numVolume")).intValue(); + int numBucket = ((Number) summaryResponse.get("numBucket")).intValue(); + int numDir = ((Number) summaryResponse.get("numDir")).intValue(); + int numKey = ((Number) summaryResponse.get("numKey")).intValue(); if (numVol != -1) { printWithUnderline("Volumes", false); diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ResetDeletedBlockRetryCountSubcommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ResetDeletedBlockRetryCountSubcommand.java index 47a0ec2299c2..306711870643 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ResetDeletedBlockRetryCountSubcommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ResetDeletedBlockRetryCountSubcommand.java @@ -16,9 +16,8 @@ */ package org.apache.hadoop.ozone.admin.scm; -import com.google.gson.Gson; -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; import org.apache.hadoop.hdds.cli.HddsVersionProvider; import org.apache.hadoop.hdds.scm.cli.ScmSubcommand; import org.apache.hadoop.hdds.scm.client.ScmClient; @@ -27,12 +26,7 @@ import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -74,14 +68,14 @@ public void execute(ScmClient client) throws IOException { if (group.resetAll) { count = client.resetDeletedBlockRetryCount(new ArrayList<>()); } else if (group.fileName != null) { - Gson gson = new Gson(); + ObjectMapper objectMapper = new ObjectMapper(); List txIDs; - try (InputStream in = new FileInputStream(group.fileName); - Reader fileReader = new InputStreamReader(in, - StandardCharsets.UTF_8)) { - DeletedBlocksTransactionInfoWrapper[] txns = gson.fromJson(fileReader, - DeletedBlocksTransactionInfoWrapper[].class); - txIDs = Arrays.stream(txns) + try (FileInputStream in = new FileInputStream(group.fileName)) { + List txns = + objectMapper.readValue(in, + new TypeReference>() { + }); + txIDs = txns.stream() .map(DeletedBlocksTransactionInfoWrapper::getTxID) .sorted() .distinct() @@ -92,9 +86,6 @@ public void execute(ScmClient client) throws IOException { System.out.println("The last loaded txID: " + txIDs.get(txIDs.size() - 1)); } - } catch (JsonIOException | JsonSyntaxException | IOException ex) { - System.out.println("Cannot parse the file " + group.fileName); - throw new IOException(ex); } count = client.resetDeletedBlockRetryCount(txIDs); } else { diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java index b71dd1c01566..76d2a4fc3d91 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java @@ -24,11 +24,10 @@ import java.util.List; import java.util.Map; import java.util.HashSet; -import com.google.gson.GsonBuilder; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.hdds.cli.SubcommandWithParent; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.StandaloneReplicationConfig; @@ -74,37 +73,33 @@ private String getChunkLocationPath(String containerLocation) { return containerLocation + File.separator + OzoneConsts.STORAGE_DIR_CHUNKS; } - @Override protected void execute(OzoneClient client, OzoneAddress address) throws IOException, OzoneClientException { try (ContainerOperationClient containerOperationClient = new ContainerOperationClient(parent.getOzoneConf()); XceiverClientManager xceiverClientManager = containerOperationClient.getXceiverClientManager()) { OzoneManagerProtocol ozoneManagerClient = client.getObjectStore().getClientProxy().getOzoneManagerClient(); address.ensureKeyAddress(); - JsonElement element; - JsonObject result = new JsonObject(); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode result = objectMapper.createObjectNode(); String volumeName = address.getVolumeName(); String bucketName = address.getBucketName(); String keyName = address.getKeyName(); - List tempchunks = null; - List chunkDetailsList = new ArrayList(); + List tempchunks; + List chunkDetailsList = new ArrayList<>(); HashSet chunkPaths = new HashSet<>(); OmKeyArgs keyArgs = new OmKeyArgs.Builder().setVolumeName(volumeName) .setBucketName(bucketName).setKeyName(keyName).build(); OmKeyInfo keyInfo = ozoneManagerClient.lookupKey(keyArgs); - // querying the keyLocations.The OM is queried to get containerID and - // localID pertaining to a given key - List locationInfos = - keyInfo.getLatestVersionLocations().getBlocksLatestVersionOnly(); - // for zero-sized key - if (locationInfos.isEmpty()) { + if (keyInfo.getLatestVersionLocations().getBlocksLatestVersionOnly() + .isEmpty()) { System.out.println("No Key Locations Found"); return; } ContainerLayoutVersion containerLayoutVersion = ContainerLayoutVersion .getConfiguredVersion(getConf()); - JsonArray responseArrayList = new JsonArray(); - for (OmKeyLocationInfo keyLocation : locationInfos) { + ArrayNode responseArrayList = objectMapper.createArrayNode(); + for (OmKeyLocationInfo keyLocation : keyInfo.getLatestVersionLocations() + .getBlocksLatestVersionOnly()) { ContainerChunkInfo containerChunkInfoVerbose = new ContainerChunkInfo(); ContainerChunkInfo containerChunkInfo = new ContainerChunkInfo(); long containerId = keyLocation.getContainerID(); @@ -129,24 +124,17 @@ protected void execute(OzoneClient client, OzoneAddress address) keyLocation.getBlockID().getDatanodeBlockIDProtobuf(); // doing a getBlock on all nodes Map - responses = null; - Map - readContainerResponses = null; - try { - responses = ContainerProtocolCalls.getBlockFromAllNodes(xceiverClient, - datanodeBlockID, keyLocation.getToken()); - readContainerResponses = + responses = + ContainerProtocolCalls.getBlockFromAllNodes(xceiverClient, + keyLocation.getBlockID().getDatanodeBlockIDProtobuf(), + keyLocation.getToken()); + Map readContainerResponses = containerOperationClient.readContainerFromAllNodes( keyLocation.getContainerID(), pipeline); - } catch (InterruptedException e) { - LOG.error("Execution interrupted due to " + e); - Thread.currentThread().interrupt(); - } - JsonArray responseFromAllNodes = new JsonArray(); - for (Map.Entry - entry : responses.entrySet()) { + ArrayNode responseFromAllNodes = objectMapper.createArrayNode(); + for (Map.Entry entry : responses.entrySet()) { chunkPaths.clear(); - JsonObject jsonObj = new JsonObject(); + ObjectNode jsonObj = objectMapper.createObjectNode(); if (entry.getValue() == null) { LOG.error("Cant execute getBlock on this node"); continue; @@ -165,8 +153,8 @@ protected void execute(OzoneClient client, OzoneAddress address) chunkDetails.setChunkOffset(chunkInfo.getOffset()); chunkDetailsList.add(chunkDetails); } - containerChunkInfoVerbose.setContainerPath(containerData - .getContainerPath()); + containerChunkInfoVerbose.setContainerPath( + containerData.getContainerPath()); containerChunkInfoVerbose.setPipeline(keyPipeline); containerChunkInfoVerbose.setChunkInfos(chunkDetailsList); containerChunkInfo.setFiles(chunkPaths); @@ -178,29 +166,30 @@ protected void execute(OzoneClient client, OzoneAddress address) containerChunkInfoVerbose.setChunkType(blockChunksType); containerChunkInfo.setChunkType(blockChunksType); } - Gson gson = new GsonBuilder().create(); + if (isVerbose()) { - element = gson.toJsonTree(containerChunkInfoVerbose); + jsonObj.set("Locations", + objectMapper.valueToTree(containerChunkInfoVerbose)); } else { - element = gson.toJsonTree(containerChunkInfo); + jsonObj.set("Locations", + objectMapper.valueToTree(containerChunkInfo)); } - jsonObj.addProperty("Datanode-HostName", entry.getKey() - .getHostName()); - jsonObj.addProperty("Datanode-IP", entry.getKey() - .getIpAddress()); - jsonObj.addProperty("Container-ID", containerId); - jsonObj.addProperty("Block-ID", keyLocation.getLocalID()); - jsonObj.add("Locations", element); + jsonObj.put("Datanode-HostName", entry.getKey().getHostName()); + jsonObj.put("Datanode-IP", entry.getKey().getIpAddress()); + jsonObj.put("Container-ID", containerId); + jsonObj.put("Block-ID", keyLocation.getLocalID()); responseFromAllNodes.add(jsonObj); } responseArrayList.add(responseFromAllNodes); + } catch (InterruptedException e) { + throw new RuntimeException(e); } finally { xceiverClientManager.releaseClientForReadData(xceiverClient, false); } } - result.add("KeyLocations", responseArrayList); - Gson gson2 = new GsonBuilder().setPrettyPrinting().create(); - String prettyJson = gson2.toJson(result); + result.set("KeyLocations", responseArrayList); + String prettyJson = objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(result); System.out.println(prettyJson); } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java index f88e08413d4b..130c1bca0fc8 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java @@ -32,6 +32,7 @@ public class ContainerChunkInfo { private String containerPath; private List chunkInfos; + private HashSet files; private UUID pipelineID; private Pipeline pipeline; @@ -65,6 +66,27 @@ public void setChunkType(ChunkType chunkType) { this.chunkType = chunkType; } + public String getContainerPath() { + return containerPath; + } + + public List getChunkInfos() { + return chunkInfos; + } + + public HashSet getFiles() { + return files; + } + + public UUID getPipelineID() { + return pipelineID; + } + + public ChunkType getChunkType() { + return chunkType; + } + + @Override public String toString() { return "Container{" diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ReadReplicas.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ReadReplicas.java index 30f2b4eca1fd..0e886a21866c 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ReadReplicas.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ReadReplicas.java @@ -17,10 +17,6 @@ package org.apache.hadoop.ozone.debug; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; import org.apache.hadoop.hdds.cli.SubcommandWithParent; import org.apache.hadoop.hdds.client.BlockID; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -36,6 +32,9 @@ import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo; import org.apache.hadoop.ozone.shell.OzoneAddress; import org.apache.hadoop.ozone.shell.keys.KeyHandler; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import jakarta.annotation.Nonnull; import org.kohsuke.MetaInfServices; import picocli.CommandLine; @@ -129,18 +128,20 @@ protected void execute(OzoneClient client, OzoneAddress address) replicasWithoutChecksum = noChecksumClient .getKeysEveryReplicas(volumeName, bucketName, keyName); - JsonObject result = new JsonObject(); - result.addProperty(JSON_PROPERTY_FILE_NAME, + ObjectMapper objectMapper = new ObjectMapper(); // Jackson's ObjectMapper + ObjectNode result = objectMapper.createObjectNode(); + result.put(JSON_PROPERTY_FILE_NAME, volumeName + "/" + bucketName + "/" + keyName); - result.addProperty(JSON_PROPERTY_FILE_SIZE, keyInfoDetails.getDataSize()); + result.put(JSON_PROPERTY_FILE_SIZE, keyInfoDetails.getDataSize()); - JsonArray blocks = new JsonArray(); + ArrayNode blocks = objectMapper.createArrayNode(); downloadReplicasAndCreateManifest(keyName, replicas, replicasWithoutChecksum, dir, blocks); - result.add(JSON_PROPERTY_FILE_BLOCKS, blocks); + result.set(JSON_PROPERTY_FILE_BLOCKS, blocks); - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String prettyJson = gson.toJson(result); + // For pretty printing JSON output with Jackson + String prettyJson = objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(result); String manifestFileName = keyName + "_manifest"; System.out.println("Writing manifest file : " + manifestFileName); @@ -158,25 +159,23 @@ private void downloadReplicasAndCreateManifest( Map> replicas, Map> replicasWithoutChecksum, - File dir, JsonArray blocks) throws IOException { + File dir, ArrayNode blocks) throws IOException { int blockIndex = 0; + ObjectMapper objectMapper = new ObjectMapper(); for (Map.Entry> block : replicas.entrySet()) { - JsonObject blockJson = new JsonObject(); - JsonArray replicasJson = new JsonArray(); + ObjectNode blockJson = objectMapper.createObjectNode(); + ArrayNode replicasJson = objectMapper.createArrayNode(); blockIndex += 1; - blockJson.addProperty(JSON_PROPERTY_BLOCK_INDEX, blockIndex); + blockJson.put(JSON_PROPERTY_BLOCK_INDEX, blockIndex); OmKeyLocationInfo locationInfo = block.getKey(); - blockJson.addProperty(JSON_PROPERTY_BLOCK_CONTAINERID, + blockJson.put(JSON_PROPERTY_BLOCK_CONTAINERID, locationInfo.getContainerID()); - blockJson.addProperty(JSON_PROPERTY_BLOCK_LOCALID, - locationInfo.getLocalID()); - blockJson.addProperty(JSON_PROPERTY_BLOCK_LENGTH, - locationInfo.getLength()); - blockJson.addProperty(JSON_PROPERTY_BLOCK_OFFSET, - locationInfo.getOffset()); + blockJson.put(JSON_PROPERTY_BLOCK_LOCALID, locationInfo.getLocalID()); + blockJson.put(JSON_PROPERTY_BLOCK_LENGTH, locationInfo.getLength()); + blockJson.put(JSON_PROPERTY_BLOCK_OFFSET, locationInfo.getOffset()); BlockID blockID = locationInfo.getBlockID(); Map blockReplicasWithoutChecksum = @@ -186,12 +185,10 @@ private void downloadReplicasAndCreateManifest( replica : block.getValue().entrySet()) { DatanodeDetails datanode = replica.getKey(); - JsonObject replicaJson = new JsonObject(); + ObjectNode replicaJson = objectMapper.createObjectNode(); - replicaJson.addProperty(JSON_PROPERTY_REPLICA_HOSTNAME, - datanode.getHostName()); - replicaJson.addProperty(JSON_PROPERTY_REPLICA_UUID, - datanode.getUuidString()); + replicaJson.put(JSON_PROPERTY_REPLICA_HOSTNAME, datanode.getHostName()); + replicaJson.put(JSON_PROPERTY_REPLICA_UUID, datanode.getUuidString()); String fileName = keyName + "_block" + blockIndex + "_" + datanode.getHostName(); @@ -202,8 +199,7 @@ private void downloadReplicasAndCreateManifest( Files.copy(is, path, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { Throwable cause = e.getCause(); - replicaJson.addProperty(JSON_PROPERTY_REPLICA_EXCEPTION, - e.getMessage()); + replicaJson.put(JSON_PROPERTY_REPLICA_EXCEPTION, e.getMessage()); if (cause instanceof OzoneChecksumException) { try (InputStream is = getReplica( blockReplicasWithoutChecksum, datanode)) { @@ -213,7 +209,7 @@ private void downloadReplicasAndCreateManifest( } replicasJson.add(replicaJson); } - blockJson.add(JSON_PROPERTY_BLOCK_REPLICAS, replicasJson); + blockJson.set(JSON_PROPERTY_BLOCK_REPLICAS, replicasJson); blocks.add(blockJson); blockReplicasWithoutChecksum.values() diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java index c9b58064fb56..13c19488c0c3 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/GetUserInfoHandler.java @@ -17,10 +17,9 @@ */ package org.apache.hadoop.ozone.shell.tenant; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.hdds.cli.GenericCli; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue; @@ -71,39 +70,34 @@ protected void execute(OzoneClient client, OzoneAddress address) if (!printJson) { out().println("User '" + userPrincipal + "' is assigned to:"); accessIdInfoList.forEach(accessIdInfo -> { - // Get admin info - final String adminInfoString; - if (accessIdInfo.getIsAdmin()) { - adminInfoString = accessIdInfo.getIsDelegatedAdmin() ? - " delegated admin" : " admin"; - } else { - adminInfoString = ""; - } + final String adminInfoString = accessIdInfo.getIsAdmin() ? + (accessIdInfo.getIsDelegatedAdmin() ? " delegated admin" : + " admin") : ""; out().format("- Tenant '%s'%s with accessId '%s'%n", accessIdInfo.getTenantId(), adminInfoString, accessIdInfo.getAccessId()); }); } else { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode resObj = objectMapper.createObjectNode(); + resObj.put("user", userPrincipal); - final JsonObject resObj = new JsonObject(); - resObj.addProperty("user", userPrincipal); - - final JsonArray arr = new JsonArray(); + ArrayNode arr = objectMapper.createArrayNode(); accessIdInfoList.forEach(accessIdInfo -> { - final JsonObject tenantObj = new JsonObject(); - tenantObj.addProperty("accessId", accessIdInfo.getAccessId()); - tenantObj.addProperty("tenantId", accessIdInfo.getTenantId()); - tenantObj.addProperty("isAdmin", accessIdInfo.getIsAdmin()); - tenantObj.addProperty("isDelegatedAdmin", - accessIdInfo.getIsDelegatedAdmin()); + ObjectNode tenantObj = objectMapper.createObjectNode(); + tenantObj.put("accessId", accessIdInfo.getAccessId()); + tenantObj.put("tenantId", accessIdInfo.getTenantId()); + tenantObj.put("isAdmin", accessIdInfo.getIsAdmin()); + tenantObj.put("isDelegatedAdmin", accessIdInfo.getIsDelegatedAdmin()); arr.add(tenantObj); }); - resObj.add("tenants", arr); + resObj.set("tenants", arr); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - out().println(gson.toJson(resObj)); + String prettyJson = objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(resObj); + out().println(prettyJson); } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java index 364fd21233b0..7c0e14dd450b 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java @@ -17,9 +17,9 @@ */ package org.apache.hadoop.ozone.shell.tenant; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.shell.OzoneAddress; import picocli.CommandLine; @@ -55,14 +55,17 @@ protected void execute(OzoneClient client, OzoneAddress address) client.getObjectStore().tenantAssignAdmin(accessId, tenantId, delegated); if (isVerbose()) { - final JsonObject obj = new JsonObject(); - obj.addProperty("accessId", accessId); - obj.addProperty("tenantId", tenantId); - obj.addProperty("isAdmin", true); - obj.addProperty("isDelegatedAdmin", delegated); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - out().println(gson.toJson(obj)); - } + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode obj = objectMapper.createObjectNode(); + obj.put("accessId", accessId); + obj.put("tenantId", tenantId); + obj.put("isAdmin", true); + obj.put("isDelegatedAdmin", delegated); + // Enable pretty printing + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + String jsonString = objectMapper.writeValueAsString(obj); + out().println(jsonString); + } } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantCreateHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantCreateHandler.java index fd6c4109604c..518da6a08aa7 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantCreateHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantCreateHandler.java @@ -17,9 +17,9 @@ */ package org.apache.hadoop.ozone.shell.tenant; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.client.TenantArgs; import org.apache.hadoop.ozone.shell.OzoneAddress; @@ -58,11 +58,14 @@ protected void execute(OzoneClient client, OzoneAddress address) // RpcClient#createTenant prints INFO level log of tenant and volume name if (isVerbose()) { - final JsonObject obj = new JsonObject(); - obj.addProperty("tenantId", tenantId); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - out().println(gson.toJson(obj)); - } + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode obj = objectMapper.createObjectNode(); + obj.put("tenantId", tenantId); + // Enable pretty printing + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + String jsonString = objectMapper.writeValueAsString(obj); + out().println(jsonString); + } } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java index 9924ac827ae2..fa1268dfe1c8 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java @@ -17,9 +17,9 @@ */ package org.apache.hadoop.ozone.shell.tenant; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.om.helpers.DeleteTenantState; import org.apache.hadoop.ozone.shell.OzoneAddress; @@ -60,13 +60,14 @@ protected void execute(OzoneClient client, OzoneAddress address) } if (isVerbose()) { - final JsonObject obj = new JsonObject(); - obj.addProperty("tenantId", tenantId); - obj.addProperty("volumeName", resp.getVolumeName()); - obj.addProperty("volumeRefCount", resp.getVolRefCount()); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + ObjectNode obj = objectMapper.createObjectNode(); + obj.put("tenantId", tenantId); + obj.put("volumeName", resp.getVolumeName()); + obj.put("volumeRefCount", resp.getVolRefCount()); // Print raw response to stderr if verbose - out().println(gson.toJson(obj)); + out().println(objectMapper.writeValueAsString(obj)); } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java index 6f0428bd7b8c..d0f767c05824 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListHandler.java @@ -17,10 +17,10 @@ */ package org.apache.hadoop.ozone.shell.tenant; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.om.helpers.TenantStateList; import org.apache.hadoop.ozone.shell.OzoneAddress; @@ -50,23 +50,24 @@ protected void execute(OzoneClient client, OzoneAddress address) tenantStateList.getTenantStateList().forEach(tenantState -> out().println(tenantState.getTenantId())); } else { - final JsonArray resArray = new JsonArray(); + ObjectMapper objectMapper = new ObjectMapper(); + ArrayNode resArray = objectMapper.createArrayNode(); tenantStateList.getTenantStateList().forEach(tenantState -> { - final JsonObject obj = new JsonObject(); - obj.addProperty("tenantId", tenantState.getTenantId()); - obj.addProperty("bucketNamespaceName", - tenantState.getBucketNamespaceName()); - obj.addProperty("userRoleName", tenantState.getUserRoleName()); - obj.addProperty("adminRoleName", tenantState.getAdminRoleName()); - obj.addProperty("bucketNamespacePolicyName", + ObjectNode obj = objectMapper.createObjectNode(); + obj.put("tenantId", tenantState.getTenantId()); + obj.put("bucketNamespaceName", tenantState.getBucketNamespaceName()); + obj.put("userRoleName", tenantState.getUserRoleName()); + obj.put("adminRoleName", tenantState.getAdminRoleName()); + obj.put("bucketNamespacePolicyName", tenantState.getBucketNamespacePolicyName()); - obj.addProperty("bucketPolicyName", - tenantState.getBucketPolicyName()); + obj.put("bucketPolicyName", tenantState.getBucketPolicyName()); resArray.add(obj); }); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - out().println(gson.toJson(resArray)); + if (printJson) { + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + } + String jsonString = objectMapper.writeValueAsString(resArray); + out().println(jsonString); } - } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java index e27a8cecd861..39a16312727c 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantListUsersHandler.java @@ -20,10 +20,9 @@ import java.io.IOException; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.om.helpers.TenantUserList; import org.apache.hadoop.ozone.shell.OzoneAddress; @@ -66,16 +65,15 @@ protected void execute(OzoneClient client, OzoneAddress address) "' with accessId '" + accessIdInfo.getAccessId() + "'"); }); } else { - final JsonArray resArray = new JsonArray(); + final ArrayNode resArray = new ObjectMapper().createArrayNode(); usersInTenant.getUserAccessIds().forEach(accessIdInfo -> { - final JsonObject obj = new JsonObject(); - obj.addProperty("user", accessIdInfo.getUserPrincipal()); - obj.addProperty("accessId", accessIdInfo.getAccessId()); + final ObjectNode obj = new ObjectMapper().createObjectNode(); + obj.put("user", accessIdInfo.getUserPrincipal()); + obj.put("accessId", accessIdInfo.getAccessId()); resArray.add(obj); }); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - out().println(gson.toJson(resArray)); + out().println(new ObjectMapper().writerWithDefaultPrettyPrinter() + .writeValueAsString(resArray)); } - } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantRevokeAdminHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantRevokeAdminHandler.java index 419628246fe6..efa170a60207 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantRevokeAdminHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantRevokeAdminHandler.java @@ -17,9 +17,9 @@ */ package org.apache.hadoop.ozone.shell.tenant; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.shell.OzoneAddress; import picocli.CommandLine; @@ -48,14 +48,17 @@ protected void execute(OzoneClient client, OzoneAddress address) client.getObjectStore().tenantRevokeAdmin(accessId, tenantId); if (isVerbose()) { - final JsonObject obj = new JsonObject(); - obj.addProperty("accessId", accessId); - obj.addProperty("tenantId", tenantId); - obj.addProperty("isAdmin", false); - obj.addProperty("isDelegatedAdmin", false); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - out().println(gson.toJson(obj)); - } + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode obj = objectMapper.createObjectNode(); + obj.put("accessId", accessId); + obj.put("tenantId", tenantId); + obj.put("isAdmin", false); + obj.put("isDelegatedAdmin", false); + // Enable pretty printing + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + String jsonString = objectMapper.writeValueAsString(obj); + out().println(jsonString); + } } }