Skip to content

Commit

Permalink
Added a wrapper for readTree and treeToValue
Browse files Browse the repository at this point in the history
  • Loading branch information
rmoreliovlabs committed Sep 22, 2022
1 parent 8d95b96 commit 4c18c64
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 49 deletions.
15 changes: 3 additions & 12 deletions rskj-core/src/main/java/co/rsk/config/RemascConfigFactory.java
Expand Up @@ -19,7 +19,7 @@
package co.rsk.config;

import co.rsk.remasc.RemascException;
import com.fasterxml.jackson.databind.JsonMappingException;
import co.rsk.util.JacksonParserUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
Expand All @@ -45,17 +45,8 @@ public RemascConfig createRemascConfig(String config) {
RemascConfig remascConfig;

try (InputStream is = RemascConfigFactory.class.getClassLoader().getResourceAsStream(this.configPath)) {
JsonNode node = mapper.readTree(is);

if (node.isEmpty()) {
throw JsonMappingException.from(node.traverse(), "Json node is empty");
}

remascConfig = mapper.treeToValue(node.get(config), RemascConfig.class);

if (remascConfig == null) {
throw new NullPointerException();
}
JsonNode node = JacksonParserUtil.readTree(mapper, is);
remascConfig = JacksonParserUtil.treeToValue(mapper, node.get(config), RemascConfig.class);
} catch (Exception ex) {
logger.error("Error reading REMASC configuration[{}]: {}", config, ex);
throw new RemascException("Error reading REMASC configuration[" + config + "]: ", ex);
Expand Down
Expand Up @@ -20,6 +20,7 @@

import co.rsk.rpc.JsonRpcMethodFilter;
import co.rsk.rpc.ModuleDescription;
import co.rsk.util.JacksonParserUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -86,11 +87,7 @@ private ByteBuf buildErrorContent(int errorCode, String errorMessage) throws Jso
errorProperties.put("code", jsonNodeFactory.numberNode(errorCode));
errorProperties.put("message", jsonNodeFactory.textNode(errorMessage));
JsonNode error = jsonNodeFactory.objectNode().set("error", jsonNodeFactory.objectNode().setAll(errorProperties));
Object object = mapper.treeToValue(error, Object.class);

if (object == null) {
throw new NullPointerException();
}
Object object = JacksonParserUtil.treeToValue(mapper, error, Object.class);

return Unpooled.wrappedBuffer(mapper.writeValueAsBytes(object));
}
Expand Down
Expand Up @@ -19,7 +19,7 @@

import java.io.IOException;

import com.fasterxml.jackson.databind.JsonMappingException;
import co.rsk.util.JacksonParserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -77,19 +77,9 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBufHolder msg) {

try (ByteBufInputStream source = new ByteBufInputStream(content)) {

final JsonNode jsonNodeRequest = mapper.readTree(source);

if (jsonNodeRequest.isEmpty()) {
throw JsonMappingException.from(jsonNodeRequest.traverse(), "Request is empty");
}

final JsonNode jsonNodeRequest = JacksonParserUtil.readTree(mapper, source);
RskWebSocketJsonParameterValidator.Result validationResult = parameterValidator.validate(jsonNodeRequest);

RskJsonRpcRequest request = mapper.treeToValue(jsonNodeRequest, RskJsonRpcRequest.class);

if (request == null) {
throw new NullPointerException();
}
RskJsonRpcRequest request = JacksonParserUtil.treeToValue(mapper, jsonNodeRequest, RskJsonRpcRequest.class);

JsonRpcResultOrError resultOrError = null;

Expand Down
55 changes: 55 additions & 0 deletions rskj-core/src/main/java/co/rsk/util/JacksonParserUtil.java
@@ -0,0 +1,55 @@
package co.rsk.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.InputStream;

public final class JacksonParserUtil {
private JacksonParserUtil() {
}

public static <T> T treeToValue(ObjectMapper mapper, TreeNode treeNode, Class<T> aClass) throws IllegalArgumentException, JsonProcessingException {
T result = mapper.treeToValue(treeNode, aClass);

if (result == null) {
throw new NullPointerException("Input is null");
}

return result;
}

public static JsonNode readTree(ObjectMapper mapper, InputStream is) throws IOException {
JsonNode result = mapper.readTree(is);

if (result.isEmpty()) {
throw JsonMappingException.from(mapper.getDeserializationContext(), "Input is empty");
}

return result;
}

public static JsonNode readTree(ObjectMapper mapper, String content) throws IOException {
JsonNode result = mapper.readTree(content);

if (result.isEmpty()) {
throw JsonMappingException.from(mapper.getDeserializationContext(), "Input is empty");
}

return result;
}

public static JsonNode readTree(ObjectMapper mapper, byte[] content) throws IOException {
JsonNode result = mapper.readTree(content);

if (result.isEmpty()) {
throw JsonMappingException.from(mapper.getDeserializationContext(), "Input is empty");
}

return result;
}
}
Expand Up @@ -19,6 +19,7 @@

import java.io.IOException;

import co.rsk.util.JacksonParserUtil;
import org.junit.Assert;
import org.junit.Test;

Expand All @@ -39,9 +40,9 @@ public void testParameterValidator_expectValid() throws IOException {
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

// right cases
JsonNode request1 = mapper.readTree("{'jsonrpc':'2.0','id':'teste','method':'eth_subscribe','params':['newHeads']}");
JsonNode request2 = mapper.readTree("{'jsonrpc':'2.0','id':'10','method':'eth_subscribe','params':['newHeads']}");
JsonNode request3 = mapper.readTree("{'jsonrpc':'2.0','id':10,'method':'eth_subscribe','params':['newHeads']}");
JsonNode request1 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':'teste','method':'eth_subscribe','params':['newHeads']}");
JsonNode request2 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':'10','method':'eth_subscribe','params':['newHeads']}");
JsonNode request3 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':10,'method':'eth_subscribe','params':['newHeads']}");

Assert.assertTrue(validator.validate(request1).isValid());
Assert.assertTrue(validator.validate(request2).isValid());
Expand All @@ -55,10 +56,10 @@ public void testParameterValidator_expectNotValid() throws IOException {
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

// wrong cases
JsonNode request4 = mapper.readTree("{'jsonrpc':'2.0','id':3.3,'method':'eth_subscribe','params':['newHeads']}");
JsonNode request5 = mapper.readTree("{'jsonrpc':'2.0','id':{},'method':'eth_subscribe','params':['newHeads']}");
JsonNode request6 = mapper.readTree("{'jsonrpc':'2.0','id':false,'method':'eth_subscribe','params':['newHeads']}");
JsonNode request7 = mapper.readTree("{'jsonrpc':'2.0','id':null,'method':'eth_subscribe','params':['newHeads']}");
JsonNode request4 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':3.3,'method':'eth_subscribe','params':['newHeads']}");
JsonNode request5 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':{},'method':'eth_subscribe','params':['newHeads']}");
JsonNode request6 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':false,'method':'eth_subscribe','params':['newHeads']}");
JsonNode request7 = JacksonParserUtil.readTree(mapper, "{'jsonrpc':'2.0','id':null,'method':'eth_subscribe','params':['newHeads']}");

Assert.assertFalse(validator.validate(request4).isValid());
Assert.assertFalse(validator.validate(request5).isValid());
Expand Down
Expand Up @@ -2,6 +2,7 @@

import co.rsk.rpc.CorsConfiguration;
import co.rsk.rpc.ModuleDescription;
import co.rsk.util.JacksonParserUtil;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -117,11 +118,7 @@ private void smokeTest(String contentType, String host, InetAddress rpcAddress,
try {
Response response = sendJsonRpcMessage(randomPort, contentType, host);
String responseBody = response.body().string();
JsonNode jsonRpcResponse = OBJECT_MAPPER.readTree(responseBody);

if (jsonRpcResponse.isEmpty()) {
throw JsonMappingException.from(jsonRpcResponse.traverse(), "Empty response");
}
JsonNode jsonRpcResponse = JacksonParserUtil.readTree(OBJECT_MAPPER, responseBody);

assertThat(response.code(), is(HttpResponseStatus.OK.code()));
assertThat(response.header("Content-Length"), is(notNullValue()));
Expand Down
Expand Up @@ -37,6 +37,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import co.rsk.rpc.modules.RskJsonRpcRequest;
import co.rsk.util.JacksonParserUtil;
import org.ethereum.rpc.Web3;
import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -161,7 +163,7 @@ public void onFailure(IOException e, Response response) {

@Override
public void onMessage(ResponseBody message) throws IOException {
JsonNode jsonRpcResponse = OBJECT_MAPPER.readTree(message.bytes());
JsonNode jsonRpcResponse = JacksonParserUtil.readTree(OBJECT_MAPPER, message.bytes());
assertThat(jsonRpcResponse.at("/result").asText(), is(mockResult));
message.close();
wsAsyncResultLatch.countDown();
Expand Down Expand Up @@ -203,12 +205,7 @@ private byte[] getJsonRpcDummyMessage(String value) {

byte[] request = new byte[0];
try {
Object object = OBJECT_MAPPER.treeToValue(JSON_NODE_FACTORY.objectNode().setAll(jsonRpcRequestProperties), Object.class);

if (object == null) {
throw new NullPointerException();
}

Object object = JacksonParserUtil.treeToValue(OBJECT_MAPPER, JSON_NODE_FACTORY.objectNode().setAll(jsonRpcRequestProperties), Object.class);
request = OBJECT_MAPPER.writeValueAsBytes(object);
} catch (JsonProcessingException e) {
fail(e.getMessage());
Expand Down
65 changes: 65 additions & 0 deletions rskj-core/src/test/java/co/rsk/util/JacksonParserUtilTest.java
@@ -0,0 +1,65 @@
/*
* This file is part of RskJ
* Copyright (C) 2017 RSK Labs Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package co.rsk.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map;

public class JacksonParserUtilTest {


@Test
public void test_treeToValue() throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = JacksonParserUtil.readTree(mapper, "{\"prop\": \"value\"}");
Map jsonMap = JacksonParserUtil.treeToValue(new ObjectMapper(), jsonNode, Map.class);

Assert.assertEquals("value", jsonNode.get("prop").asText());
}

@Test
public void test_readTreeStringContent() throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = JacksonParserUtil.readTree(mapper, "{\"prop\": \"value\"}");

Assert.assertEquals("value", jsonNode.get("prop").asText());
}

@Test
public void test_readTreeBytesContent() throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = JacksonParserUtil.readTree(mapper, "{\"prop\": \"value\"}".getBytes());

Assert.assertEquals("value", jsonNode.get("prop").asText());
}

@Test
public void test_readTreeInputStreamContent() throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = JacksonParserUtil.readTree(mapper, new ByteArrayInputStream("{\"prop\": \"value\"}".getBytes()));

Assert.assertEquals("value", jsonNode.get("prop").asText());
}
}

0 comments on commit 4c18c64

Please sign in to comment.