mirror of https://github.com/hyperledger/besu
[PIE-1809] Clean up genesis parsing (#1809)
Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>pull/2/head
parent
75b754e36b
commit
63ffdb5f02
@ -1,45 +0,0 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.config; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.Optional; |
||||
import java.util.OptionalLong; |
||||
|
||||
import io.vertx.core.json.JsonObject; |
||||
|
||||
public class ConfigUtil { |
||||
public static OptionalLong getOptionalLong(final JsonObject jsonObject, final String key) { |
||||
return jsonObject.containsKey(key) |
||||
? OptionalLong.of(jsonObject.getLong(key)) |
||||
: OptionalLong.empty(); |
||||
} |
||||
|
||||
public static Optional<BigInteger> getOptionalBigInteger( |
||||
final JsonObject jsonObject, final String key) { |
||||
return jsonObject.containsKey(key) |
||||
? Optional.ofNullable(getBigInteger(jsonObject, key)) |
||||
: Optional.empty(); |
||||
} |
||||
|
||||
private static BigInteger getBigInteger(final JsonObject jsonObject, final String key) { |
||||
final Number value = (Number) jsonObject.getMap().get(key); |
||||
if (value == null) { |
||||
return null; |
||||
} else if (value instanceof BigInteger) { |
||||
return (BigInteger) value; |
||||
} else { |
||||
return BigInteger.valueOf(value.longValue()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,243 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.config; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
import java.util.OptionalInt; |
||||
import java.util.OptionalLong; |
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature; |
||||
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import com.fasterxml.jackson.databind.node.ArrayNode; |
||||
import com.fasterxml.jackson.databind.node.JsonNodeType; |
||||
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||
|
||||
public class JsonUtil { |
||||
|
||||
/** |
||||
* Get the string representation of the value at {@code key}. For example, a numeric value like 5 |
||||
* will be returned as "5". |
||||
* |
||||
* @param node The {@code ObjectNode} from which the value will be extracted. |
||||
* @param key The key corresponding to the value to extract. |
||||
* @return The value at the given key as a string if it exists. |
||||
*/ |
||||
public static Optional<String> getValueAsString(final ObjectNode node, final String key) { |
||||
return getValue(node, key).map(JsonNode::asText); |
||||
} |
||||
|
||||
/** |
||||
* Get the string representation of the value at {@code key}. For example, a numeric value like 5 |
||||
* will be returned as "5". |
||||
* |
||||
* @param node The {@code ObjectNode} from which the value will be extracted. |
||||
* @param key The key corresponding to the value to extract. |
||||
* @param defaultValue The value to return if no value is found at {@code key}. |
||||
* @return The value at the given key as a string if it exists, otherwise {@code defaultValue} |
||||
*/ |
||||
public static String getValueAsString( |
||||
final ObjectNode node, final String key, final String defaultValue) { |
||||
return getValueAsString(node, key).orElse(defaultValue); |
||||
} |
||||
|
||||
/** |
||||
* Returns textual (string) value at {@code key}. See {@link #getValueAsString} for retrieving |
||||
* non-textual values in string form. |
||||
* |
||||
* @param node The {@code ObjectNode} from which the value will be extracted. |
||||
* @param key The key corresponding to the value to extract. |
||||
* @return The textual value at {@code key} if it exists. |
||||
*/ |
||||
public static Optional<String> getString(final ObjectNode node, final String key) { |
||||
return getValue(node, key) |
||||
.filter(jsonNode -> validateType(jsonNode, JsonNodeType.STRING)) |
||||
.map(JsonNode::asText); |
||||
} |
||||
|
||||
/** |
||||
* Returns textual (string) value at {@code key}. See {@link #getValueAsString} for retrieving |
||||
* non-textual values in string form. |
||||
* |
||||
* @param node The {@code ObjectNode} from which the value will be extracted. |
||||
* @param key The key corresponding to the value to extract. |
||||
* @param defaultValue The value to return if no value is found at {@code key}. |
||||
* @return The textual value at {@code key} if it exists, otherwise {@code defaultValue} |
||||
*/ |
||||
public static String getString( |
||||
final ObjectNode node, final String key, final String defaultValue) { |
||||
return getString(node, key).orElse(defaultValue); |
||||
} |
||||
|
||||
public static OptionalInt getInt(final ObjectNode node, final String key) { |
||||
return getValue(node, key) |
||||
.filter(jsonNode -> validateType(jsonNode, JsonNodeType.NUMBER)) |
||||
.filter(JsonUtil::validateInt) |
||||
.map(JsonNode::asInt) |
||||
.map(OptionalInt::of) |
||||
.orElse(OptionalInt.empty()); |
||||
} |
||||
|
||||
public static int getInt(final ObjectNode node, final String key, final int defaultValue) { |
||||
return getInt(node, key).orElse(defaultValue); |
||||
} |
||||
|
||||
public static OptionalLong getLong(final ObjectNode json, final String key) { |
||||
return getValue(json, key) |
||||
.filter(jsonNode -> validateType(jsonNode, JsonNodeType.NUMBER)) |
||||
.filter(JsonUtil::validateLong) |
||||
.map(JsonNode::asLong) |
||||
.map(OptionalLong::of) |
||||
.orElse(OptionalLong.empty()); |
||||
} |
||||
|
||||
public static long getLong(final ObjectNode json, final String key, final long defaultValue) { |
||||
return getLong(json, key).orElse(defaultValue); |
||||
} |
||||
|
||||
public static Optional<Boolean> getBoolean(final ObjectNode node, final String key) { |
||||
return getValue(node, key) |
||||
.filter(jsonNode -> validateType(jsonNode, JsonNodeType.BOOLEAN)) |
||||
.map(JsonNode::asBoolean); |
||||
} |
||||
|
||||
public static boolean getBoolean( |
||||
final ObjectNode node, final String key, final boolean defaultValue) { |
||||
return getBoolean(node, key).orElse(defaultValue); |
||||
} |
||||
|
||||
public static ObjectNode createEmptyObjectNode() { |
||||
ObjectMapper mapper = getObjectMapper(); |
||||
return mapper.createObjectNode(); |
||||
} |
||||
|
||||
public static ObjectNode objectNodeFromMap(final Map<String, Object> map) { |
||||
return (ObjectNode) getObjectMapper().valueToTree(map); |
||||
} |
||||
|
||||
public static ObjectNode objectNodeFromString(final String jsonData) { |
||||
return objectNodeFromString(jsonData, false); |
||||
} |
||||
|
||||
public static ObjectNode objectNodeFromString( |
||||
final String jsonData, final boolean allowComments) { |
||||
final ObjectMapper objectMapper = new ObjectMapper(); |
||||
objectMapper.configure(Feature.ALLOW_COMMENTS, allowComments); |
||||
try { |
||||
final JsonNode jsonNode = objectMapper.readTree(jsonData); |
||||
validateType(jsonNode, JsonNodeType.OBJECT); |
||||
return (ObjectNode) jsonNode; |
||||
} catch (IOException e) { |
||||
// Reading directly from a string should not raise an IOException, just catch and rethrow
|
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
public static String getJson(final Object objectNode) throws JsonProcessingException { |
||||
return getJson(objectNode, true); |
||||
} |
||||
|
||||
public static String getJson(final Object objectNode, final boolean prettyPrint) |
||||
throws JsonProcessingException { |
||||
ObjectMapper mapper = getObjectMapper(); |
||||
if (prettyPrint) { |
||||
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectNode); |
||||
} else { |
||||
return mapper.writeValueAsString(objectNode); |
||||
} |
||||
} |
||||
|
||||
public static ObjectMapper getObjectMapper() { |
||||
return new ObjectMapper(); |
||||
} |
||||
|
||||
public static Optional<ObjectNode> getObjectNode(final ObjectNode json, final String fieldKey) { |
||||
return getObjectNode(json, fieldKey, true); |
||||
} |
||||
|
||||
public static Optional<ObjectNode> getObjectNode( |
||||
final ObjectNode json, final String fieldKey, final boolean strict) { |
||||
final JsonNode obj = json.get(fieldKey); |
||||
if (obj == null || obj.isNull()) { |
||||
return Optional.empty(); |
||||
} |
||||
|
||||
if (!obj.isObject()) { |
||||
if (strict) { |
||||
validateType(obj, JsonNodeType.OBJECT); |
||||
} else { |
||||
return Optional.empty(); |
||||
} |
||||
} |
||||
|
||||
return Optional.of((ObjectNode) obj); |
||||
} |
||||
|
||||
public static Optional<ArrayNode> getArrayNode(final ObjectNode json, final String fieldKey) { |
||||
return getArrayNode(json, fieldKey, true); |
||||
} |
||||
|
||||
public static Optional<ArrayNode> getArrayNode( |
||||
final ObjectNode json, final String fieldKey, final boolean strict) { |
||||
final JsonNode obj = json.get(fieldKey); |
||||
if (obj == null || obj.isNull()) { |
||||
return Optional.empty(); |
||||
} |
||||
|
||||
if (!obj.isArray()) { |
||||
if (strict) { |
||||
validateType(obj, JsonNodeType.ARRAY); |
||||
} else { |
||||
return Optional.empty(); |
||||
} |
||||
} |
||||
|
||||
return Optional.of((ArrayNode) obj); |
||||
} |
||||
|
||||
private static Optional<JsonNode> getValue(final ObjectNode node, final String key) { |
||||
JsonNode jsonNode = node.get(key); |
||||
if (jsonNode == null || jsonNode.isNull()) { |
||||
return Optional.empty(); |
||||
} |
||||
return Optional.of(jsonNode); |
||||
} |
||||
|
||||
private static boolean validateType(final JsonNode node, final JsonNodeType expectedType) { |
||||
if (node.getNodeType() != expectedType) { |
||||
final String errorMessage = |
||||
String.format( |
||||
"Expected %s value but got %s", |
||||
expectedType.toString().toLowerCase(), node.getNodeType().toString().toLowerCase()); |
||||
throw new IllegalArgumentException(errorMessage); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
private static boolean validateLong(final JsonNode node) { |
||||
if (!node.canConvertToLong()) { |
||||
throw new IllegalArgumentException("Cannot convert value to long: " + node.toString()); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
private static boolean validateInt(final JsonNode node) { |
||||
if (!node.canConvertToInt()) { |
||||
throw new IllegalArgumentException("Cannot convert value to integer: " + node.toString()); |
||||
} |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,545 @@ |
||||
/* |
||||
* Copyright 2019 ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package tech.pegasys.pantheon.config; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
import java.util.Map; |
||||
import java.util.Optional; |
||||
import java.util.OptionalInt; |
||||
import java.util.OptionalLong; |
||||
import java.util.TreeMap; |
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException; |
||||
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import com.fasterxml.jackson.databind.node.ArrayNode; |
||||
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||
import org.junit.Test; |
||||
|
||||
public class JsonUtilTest { |
||||
private ObjectMapper mapper = new ObjectMapper(); |
||||
|
||||
@Test |
||||
public void getLong_nonExistentKey() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final OptionalLong result = JsonUtil.getLong(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_nullValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final OptionalLong result = JsonUtil.getLong(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_validValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", Long.MAX_VALUE); |
||||
final OptionalLong result = JsonUtil.getLong(node, "test"); |
||||
assertThat(result).hasValue(Long.MAX_VALUE); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_overflowingValue() { |
||||
final String overflowingValue = Long.toString(Long.MAX_VALUE, 10) + "100"; |
||||
final String jsonStr = "{\"test\": " + overflowingValue + " }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getLong(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Cannot convert value to long: " + overflowingValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_wrongType() { |
||||
final String jsonStr = "{\"test\": \"bla\" }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getLong(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected number value but got string"); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_nullValue_withDefault() { |
||||
final long defaultValue = 11; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final long result = JsonUtil.getLong(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_nonExistentKey_withDefault() { |
||||
final long defaultValue = 11; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final long result = JsonUtil.getLong(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_validValue_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", Long.MAX_VALUE); |
||||
final long result = JsonUtil.getLong(node, "test", 11); |
||||
assertThat(result).isEqualTo(Long.MAX_VALUE); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_overflowingValue_withDefault() { |
||||
final String overflowingValue = Long.toString(Long.MAX_VALUE, 10) + "100"; |
||||
final String jsonStr = "{\"test\": " + overflowingValue + " }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getLong(rootNode, "test", 11)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Cannot convert value to long: " + overflowingValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getLong_wrongType_withDefault() { |
||||
final String jsonStr = "{\"test\": \"bla\" }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getLong(rootNode, "test", 11)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected number value but got string"); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_nonExistentKey() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final OptionalInt result = JsonUtil.getInt(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_nullValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final OptionalInt result = JsonUtil.getInt(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_validValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", Integer.MAX_VALUE); |
||||
final OptionalInt result = JsonUtil.getInt(node, "test"); |
||||
assertThat(result).hasValue(Integer.MAX_VALUE); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_overflowingValue() { |
||||
final String overflowingValue = Integer.toString(Integer.MAX_VALUE, 10) + "100"; |
||||
final String jsonStr = "{\"test\": " + overflowingValue + " }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getInt(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Cannot convert value to integer: " + overflowingValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_wrongType() { |
||||
final String jsonStr = "{\"test\": \"bla\" }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getInt(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected number value but got string"); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_nullValue_withDefault() { |
||||
final int defaultValue = 11; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final int result = JsonUtil.getInt(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_nonExistentKey_withDefault() { |
||||
final int defaultValue = 11; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final int result = JsonUtil.getInt(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_validValue_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", Integer.MAX_VALUE); |
||||
final int result = JsonUtil.getInt(node, "test", 11); |
||||
assertThat(result).isEqualTo(Integer.MAX_VALUE); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_overflowingValue_withDefault() { |
||||
final String overflowingValue = Integer.toString(Integer.MAX_VALUE, 10) + "100"; |
||||
final String jsonStr = "{\"test\": " + overflowingValue + " }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getInt(rootNode, "test", 11)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Cannot convert value to integer: " + overflowingValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getInt_wrongType_withDefault() { |
||||
final String jsonStr = "{\"test\": \"bla\" }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getInt(rootNode, "test", 11)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected number value but got string"); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_nonExistentKey() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final Optional<String> result = JsonUtil.getString(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_nullValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final Optional<String> result = JsonUtil.getString(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_validValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", "bla"); |
||||
final Optional<String> result = JsonUtil.getString(node, "test"); |
||||
assertThat(result).hasValue("bla"); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_wrongType() { |
||||
final String jsonStr = "{\"test\": 123 }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getString(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected string value but got number"); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_nullValue_withDefault() { |
||||
final String defaultValue = "bla"; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final String result = JsonUtil.getString(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_nonExistentKey_withDefault() { |
||||
final String defaultValue = "bla"; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final String result = JsonUtil.getString(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getString_validValue_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", "bla"); |
||||
final String result = JsonUtil.getString(node, "test", "11"); |
||||
assertThat(result).isEqualTo("bla"); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_nonExistentKey() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final Optional<String> result = JsonUtil.getValueAsString(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_nullValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final Optional<String> result = JsonUtil.getValueAsString(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_stringValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", "bla"); |
||||
final Optional<String> result = JsonUtil.getValueAsString(node, "test"); |
||||
assertThat(result).hasValue("bla"); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_nonStringValue() { |
||||
final String jsonStr = "{\"test\": 123 }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<String> result = JsonUtil.getValueAsString(rootNode, "test"); |
||||
assertThat(result).hasValue("123"); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_nullValue_withDefault() { |
||||
final String defaultValue = "bla"; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final String result = JsonUtil.getValueAsString(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_nonExistentKey_withDefault() { |
||||
final String defaultValue = "bla"; |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final String result = JsonUtil.getValueAsString(node, "test", defaultValue); |
||||
assertThat(result).isEqualTo(defaultValue); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_stringValue_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", "bla"); |
||||
final String result = JsonUtil.getValueAsString(node, "test", "11"); |
||||
assertThat(result).isEqualTo("bla"); |
||||
} |
||||
|
||||
@Test |
||||
public void getValueAsString_nonStringValue_withDefault() { |
||||
final String jsonStr = "{\"test\": 123 }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final String result = JsonUtil.getValueAsString(rootNode, "test", "11"); |
||||
assertThat(result).isEqualTo("123"); |
||||
} |
||||
|
||||
// Boolean
|
||||
@Test |
||||
public void getBoolean_nonExistentKey() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final Optional<Boolean> result = JsonUtil.getBoolean(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_nullValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final Optional<Boolean> result = JsonUtil.getBoolean(node, "test"); |
||||
assertThat(result).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_validValue() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", true); |
||||
final Optional<Boolean> result = JsonUtil.getBoolean(node, "test"); |
||||
assertThat(result).hasValue(true); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_wrongType() { |
||||
final String jsonStr = "{\"test\": 123 }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getBoolean(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected boolean value but got number"); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_nullValue_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.set("test", null); |
||||
final Boolean result = JsonUtil.getBoolean(node, "test", false); |
||||
assertThat(result).isEqualTo(false); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_nonExistentKey_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
final Boolean result = JsonUtil.getBoolean(node, "test", true); |
||||
assertThat(result).isEqualTo(true); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_validValue_withDefault() { |
||||
final ObjectNode node = mapper.createObjectNode(); |
||||
node.put("test", false); |
||||
final Boolean result = JsonUtil.getBoolean(node, "test", true); |
||||
assertThat(result).isEqualTo(false); |
||||
} |
||||
|
||||
@Test |
||||
public void getBoolean_wrongType_withDefault() { |
||||
final String jsonStr = "{\"test\": 123 }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getBoolean(rootNode, "test", true)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected boolean value but got number"); |
||||
} |
||||
|
||||
@Test |
||||
public void objectNodeFromMap() { |
||||
final Map<String, Object> map = new TreeMap<>(); |
||||
map.put("a", 1); |
||||
map.put("b", 2); |
||||
|
||||
final Map<String, Object> subMap = new TreeMap<>(); |
||||
subMap.put("c", "bla"); |
||||
subMap.put("d", 2L); |
||||
map.put("subtree", subMap); |
||||
|
||||
ObjectNode node = JsonUtil.objectNodeFromMap(map); |
||||
assertThat(node.get("a").asInt()).isEqualTo(1); |
||||
assertThat(node.get("b").asInt()).isEqualTo(2); |
||||
assertThat(node.get("subtree").get("c").asText()).isEqualTo("bla"); |
||||
assertThat(node.get("subtree").get("d").asLong()).isEqualTo(2L); |
||||
} |
||||
|
||||
@Test |
||||
public void objectNodeFromString() { |
||||
final String jsonStr = "{\"a\":1, \"b\":2}"; |
||||
|
||||
final ObjectNode result = JsonUtil.objectNodeFromString(jsonStr); |
||||
assertThat(result.get("a").asInt()).isEqualTo(1); |
||||
assertThat(result.get("b").asInt()).isEqualTo(2); |
||||
} |
||||
|
||||
@Test |
||||
public void objectNodeFromString_withComments_commentsDisabled() { |
||||
final String jsonStr = "// Comment\n{\"a\":1, \"b\":2}"; |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.objectNodeFromString(jsonStr, false)) |
||||
.hasCauseInstanceOf(JsonParseException.class) |
||||
.hasMessageContaining("Unexpected character ('/'"); |
||||
} |
||||
|
||||
@Test |
||||
public void objectNodeFromString_withComments_commentsEnabled() { |
||||
final String jsonStr = "// Comment\n{\"a\":1, \"b\":2}"; |
||||
|
||||
final ObjectNode result = JsonUtil.objectNodeFromString(jsonStr, true); |
||||
assertThat(result.get("a").asInt()).isEqualTo(1); |
||||
assertThat(result.get("b").asInt()).isEqualTo(2); |
||||
} |
||||
|
||||
@Test |
||||
public void getJson() throws JsonProcessingException { |
||||
final String jsonStr = "{\"a\":1, \"b\":2}"; |
||||
final ObjectNode objectNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final String resultUgly = JsonUtil.getJson(objectNode, false); |
||||
final String resultPretty = JsonUtil.getJson(objectNode, true); |
||||
|
||||
assertThat(resultUgly).isEqualToIgnoringWhitespace(jsonStr); |
||||
assertThat(resultPretty).isEqualToIgnoringWhitespace(jsonStr); |
||||
// Pretty printed value should have more whitespace and contain returns
|
||||
assertThat(resultPretty.length()).isGreaterThan(resultUgly.length()); |
||||
assertThat(resultPretty).contains("\n"); |
||||
assertThat(resultUgly).doesNotContain("\n"); |
||||
} |
||||
|
||||
@Test |
||||
public void getObjectNode_validValue() { |
||||
final String jsonStr = "{\"test\": {\"a\":1, \"b\":2} }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<ObjectNode> maybeTestNode = JsonUtil.getObjectNode(rootNode, "test"); |
||||
assertThat(maybeTestNode).isNotEmpty(); |
||||
final ObjectNode testNode = maybeTestNode.get(); |
||||
assertThat(testNode.get("a").asInt()).isEqualTo(1); |
||||
assertThat(testNode.get("b").asInt()).isEqualTo(2); |
||||
} |
||||
|
||||
@Test |
||||
public void getObjectNode_nullValue() { |
||||
final String jsonStr = "{\"test\": null }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<ObjectNode> maybeTestNode = JsonUtil.getObjectNode(rootNode, "test"); |
||||
assertThat(maybeTestNode).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getObjectNode_nonExistentKey() { |
||||
final String jsonStr = "{}"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<ObjectNode> maybeTestNode = JsonUtil.getObjectNode(rootNode, "test"); |
||||
assertThat(maybeTestNode).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getObjectNode_wrongNodeType() { |
||||
final String jsonStr = "{\"test\": \"abc\" }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getObjectNode(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected object value but got string"); |
||||
} |
||||
|
||||
@Test |
||||
public void getArrayNode_validValue() { |
||||
final String jsonStr = "{\"test\": [\"a\", \"b\"] }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<ArrayNode> maybeTestNode = JsonUtil.getArrayNode(rootNode, "test"); |
||||
assertThat(maybeTestNode).isNotEmpty(); |
||||
final ArrayNode testNode = maybeTestNode.get(); |
||||
assertThat(testNode.get(0).asText()).isEqualTo("a"); |
||||
assertThat(testNode.get(1).asText()).isEqualTo("b"); |
||||
} |
||||
|
||||
@Test |
||||
public void getArrayNode_nullValue() { |
||||
final String jsonStr = "{\"test\": null }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<ArrayNode> maybeTestNode = JsonUtil.getArrayNode(rootNode, "test"); |
||||
assertThat(maybeTestNode).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getArrayNode_nonExistentKey() { |
||||
final String jsonStr = "{}"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
final Optional<ArrayNode> maybeTestNode = JsonUtil.getArrayNode(rootNode, "test"); |
||||
assertThat(maybeTestNode).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void getArrayNode_wrongNodeType() { |
||||
final String jsonStr = "{\"test\": \"abc\" }"; |
||||
final ObjectNode rootNode = JsonUtil.objectNodeFromString(jsonStr); |
||||
|
||||
assertThatThrownBy(() -> JsonUtil.getArrayNode(rootNode, "test")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessageContaining("Expected array value but got string"); |
||||
} |
||||
} |
@ -0,0 +1,44 @@ |
||||
{ |
||||
"genesis": { |
||||
"config": { |
||||
"chainId": 2017, |
||||
"constantinoplefixblock": 0, |
||||
"homesteadBlock": 0, |
||||
"eip150Block": 0, |
||||
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", |
||||
"ibft2": { |
||||
|
||||
} |
||||
}, |
||||
"nonce": "0x0", |
||||
"timestamp": "0x5b3c3d18", |
||||
"number": "0x0", |
||||
"gasUsed": "0x0", |
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", |
||||
"gasLimit": "0x47b760", |
||||
"difficulty": "0x1", |
||||
"mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", |
||||
"coinbase": "0x0000000000000000000000000000000000000000", |
||||
"ibft2": { |
||||
"blockperiodseconds": 2, |
||||
"epochlength": 30000, |
||||
"requesttimeoutseconds": 10 |
||||
}, |
||||
"alloc": { |
||||
"24defc2d149861d3d245749b81fe0e6b28e04f31": { |
||||
"balance": "0x446c3b15f9926687d2c40534fdb564000000000000" |
||||
}, |
||||
"2a813d7db3de19b07f92268b6d4125ed295cbe00": { |
||||
"balance": "0x446c3b15f9926687d2c40534fdb542000000000000" |
||||
} |
||||
} |
||||
}, |
||||
"blockchain": { |
||||
"nodes": { |
||||
"keys": [ |
||||
{"invalidObj": "0xb295c4242fb40c6e8ac7b831c916846050f191adc560b8098ba6ad513079571ec1be6e5e1a715857a13a91963097962e048c36c5863014b59e8f67ed3f667680"}, |
||||
"0x6295c4242fb40c6e8ac7b831c916846050f191adc560b8098ba6ad513079571ec1be6e5e1a715857a13a91963097962e048c36c5863014b59e8f67ed3f667680" |
||||
] |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue