From 1faa5f0c0eb107eb34673bdc8566e82fb335c50f Mon Sep 17 00:00:00 2001 From: blavenie <benoit.lavenier@e-is.pro> Date: Thu, 5 Jan 2017 03:05:00 +0100 Subject: [PATCH] - limit the use of Gson --- .../model/bma/jackson/JacksonUtils.java | 24 ++++++++++ .../CurrencyRegistryRemoteServiceImpl.java | 20 +++----- .../bma/BlockchainRemoteServiceTest.java | 22 ++++++--- .../CurrencyRegistryRemoteServiceTest.java | 5 +- .../rest/security/RestSecurityAuthAction.java | 9 ++-- .../service/BlockchainService.java | 48 ++++++++++++------- .../service/CurrencyService.java | 14 +++--- 7 files changed, 92 insertions(+), 50 deletions(-) diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/JacksonUtils.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/JacksonUtils.java index 8f7214f1..c6b577f8 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/JacksonUtils.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/JacksonUtils.java @@ -4,6 +4,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.duniter.core.client.model.bma.BlockchainBlock; import org.duniter.core.client.model.bma.NetworkPeering; +import org.duniter.core.client.model.bma.gson.JsonArrayParser; +import org.duniter.core.client.model.bma.gson.JsonAttributeParser; + +import java.util.List; /** * Created by blavenie on 07/12/16. @@ -30,4 +34,24 @@ public abstract class JacksonUtils extends SimpleModule { return objectMapper; } + + public static List<String> getValuesFromJSONAsString(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValues(jsonString); + } + + public static String getValueFromJSONAsString(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValueAsString(jsonString); + } + + public static Number getValueFromJSONAsNumber(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValueAsNumber(jsonString); + } + + public static int getValueFromJSONAsInt(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValueAsInt(jsonString); + } + + public static List<String> getArrayValuesFromJSONAsInt(String jsonString) { + return new JsonArrayParser().getValuesAsList(jsonString); + } } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java index a34d8bea..cd2019ef 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java @@ -22,11 +22,13 @@ package org.duniter.core.client.service.elasticsearch; * #L% */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; import org.duniter.core.beans.InitializingBean; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.model.bma.gson.GsonUtils; +import org.duniter.core.client.model.bma.jackson.JacksonUtils; import org.duniter.core.client.model.elasticsearch.Currency; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.model.local.Wallet; @@ -34,16 +36,11 @@ import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.client.service.bma.BaseRemoteServiceImpl; import org.duniter.core.exception.TechnicalException; import org.duniter.core.service.CryptoService; -import org.duniter.core.util.StringUtils; -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Closeable; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.List; @@ -60,7 +57,6 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp private Configuration config; private Peer peer; - private Gson gson; public CurrencyRegistryRemoteServiceImpl() { super(); @@ -71,7 +67,6 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp super.afterPropertiesSet(); config = Configuration.instance(); peer = new Peer(config.getNodeElasticSearchHost(), config.getNodeElasticSearchPort()); - gson = GsonUtils.newBuilder().create(); } @Override @@ -79,7 +74,6 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp super.close(); config = null; peer = null; - gson = null; } @Override @@ -97,7 +91,7 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp String jsonResponse; try { jsonResponse = executeRequest(peer, URL_STATUS, String.class); - int statusCode = GsonUtils.getValueFromJSONAsInt(jsonResponse, "status"); + int statusCode = JacksonUtils.getValueFromJSONAsInt(jsonResponse, "status"); return statusCode == HttpStatus.SC_OK; } catch(TechnicalException e) { @@ -118,7 +112,7 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp String path = getPath(peer, URL_ALL_CURRENCY_NAMES); String jsonResponse = executeRequest(new HttpGet(path), String.class); - List<String> currencyNames = GsonUtils.getValuesFromJSONAsString(jsonResponse, "currencyName"); + List<String> currencyNames = JacksonUtils.getValuesFromJSONAsString(jsonResponse, "currencyName"); // Sort into alphabetical order Collections.sort(currencyNames); @@ -132,7 +126,7 @@ public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl imp log.debug("Registering a new currency..."); } - String currencyJson = gson.toJson(currency); + String currencyJson = GsonUtils.newBuilder().create().toJson(currency); CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); String signature = cryptoService.sign(currencyJson, wallet.getSecKey()); diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java index dd096011..7f33904a 100644 --- a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java +++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceTest.java @@ -23,14 +23,14 @@ package org.duniter.core.client.service.bma; */ -import com.google.gson.Gson; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.JsonSyntaxException; import org.duniter.core.client.TestResource; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.model.bma.BlockchainBlock; import org.duniter.core.client.model.bma.BlockchainParameters; import org.duniter.core.client.model.bma.ErrorCode; -import org.duniter.core.client.model.bma.gson.GsonUtils; +import org.duniter.core.client.model.bma.jackson.JacksonUtils; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.model.local.Wallet; import org.duniter.core.client.service.ServiceLocator; @@ -40,6 +40,8 @@ import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; + public class BlockchainRemoteServiceTest { private static final Logger log = LoggerFactory.getLogger(BlockchainRemoteServiceTest.class); @@ -113,11 +115,12 @@ public class BlockchainRemoteServiceTest { Assert.assertEquals(10, result.length); // Make sure all json are valid blocks - Gson gson = GsonUtils.newBuilder().create(); + ObjectMapper objectMapper = JacksonUtils.newObjectMapper(); + int number = 0; for (String jsonBlock: result) { try { - gson.fromJson(jsonBlock, BlockchainBlock.class); + objectMapper.readValue(jsonBlock, BlockchainBlock.class); } catch(JsonSyntaxException e) { e.printStackTrace(); @@ -134,9 +137,14 @@ public class BlockchainRemoteServiceTest { isWebSocketNewBlockReceived = false; service.addBlockListener(createTestPeer(), (message) -> { - BlockchainBlock block = GsonUtils.newBuilder().create().fromJson(message, BlockchainBlock.class); - log.debug("Received block #" + block.getNumber()); - isWebSocketNewBlockReceived = true; + try { + BlockchainBlock block = JacksonUtils.newObjectMapper().readValue(message, BlockchainBlock.class); + log.debug("Received block #" + block.getNumber()); + isWebSocketNewBlockReceived = true; + } + catch (IOException e) { + Assert.fail(e.getMessage()); + } }); int count = 0; diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java index 03933ed7..371731ce 100644 --- a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java +++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java @@ -26,6 +26,7 @@ import org.duniter.core.client.TestResource; import org.duniter.core.client.config.Configuration; import org.duniter.core.client.model.Currency; import org.duniter.core.client.model.bma.gson.GsonUtils; +import org.duniter.core.client.model.bma.jackson.JacksonUtils; import org.duniter.core.client.model.local.Wallet; import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.service.CryptoService; @@ -77,11 +78,11 @@ public class CurrencyRegistryRemoteServiceTest { } @Test - public void registerCurrency() { + public void registerCurrency() throws Exception { Currency currency = new Currency(); currency.setCurrencyName("register-test-" + System.currentTimeMillis()); - String currencyJson = GsonUtils.newBuilder().create().toJson(currency); + String currencyJson = JacksonUtils.newObjectMapper().writeValueAsString(currency); String pubKey = resource.getFixtures().getUserPublicKey(); String secretKey = resource.getFixtures().getUserSecretKey(); diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java index 300e5d92..ad1e92ae 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java @@ -22,8 +22,7 @@ package org.duniter.elasticsearch.rest.security; * #L% */ -import com.google.gson.Gson; -import org.duniter.core.client.model.bma.gson.GsonUtils; +import com.fasterxml.jackson.databind.ObjectMapper; import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.util.StringUtils; import org.duniter.elasticsearch.security.challenge.ChallengeMessageStore; @@ -45,7 +44,7 @@ public class RestSecurityAuthAction extends BaseRestHandler { private ChallengeMessageStore challengeMessageStore; private SecurityTokenStore securityTokenStore; - private Gson gson; + private ObjectMapper objectMapper; @Inject public RestSecurityAuthAction(Settings settings, RestController controller, Client client, @@ -55,7 +54,7 @@ public class RestSecurityAuthAction extends BaseRestHandler { super(settings, controller, client); this.challengeMessageStore = challengeMessageStore; this.securityTokenStore = securityTokenStore; - this.gson = GsonUtils.newBuilder().create(); + this.objectMapper = new ObjectMapper(); controller.registerHandler(POST, "/auth", this); securityController.allow(POST, "/auth"); } @@ -63,7 +62,7 @@ public class RestSecurityAuthAction extends BaseRestHandler { @Override protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception { - AuthData authData = gson.fromJson(request.content().toUtf8(), AuthData.class); + AuthData authData = objectMapper.readValue(request.content().toUtf8(), AuthData.class); // TODO Authorization: Basic instead ? diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java index e6bc12cd..59814fd8 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java @@ -23,15 +23,17 @@ package org.duniter.elasticsearch.service; */ +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Objects; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; -import com.google.gson.Gson; import org.duniter.core.client.model.bma.BlockchainBlock; import org.duniter.core.client.model.bma.BlockchainParameters; import org.duniter.core.client.model.bma.EndpointProtocol; import org.duniter.core.client.model.bma.gson.GsonUtils; import org.duniter.core.client.model.bma.gson.JsonAttributeParser; +import org.duniter.core.client.model.bma.jackson.JacksonUtils; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.service.bma.BlockchainRemoteService; import org.duniter.core.client.service.bma.NetworkRemoteService; @@ -98,13 +100,13 @@ public class BlockchainService extends AbstractService { private final JsonAttributeParser blockHashParser = new JsonAttributeParser("hash"); private final JsonAttributeParser blockPreviousHashParser = new JsonAttributeParser("previousHash"); - private Gson gson; + private ObjectMapper objectMapper; @Inject public BlockchainService(Client client, PluginSettings settings, ThreadPool threadPool, final ServiceLocator serviceLocator){ super("duniter.blockchain", client, settings); - this.gson = GsonUtils.newBuilder().create(); + this.objectMapper = JacksonUtils.newObjectMapper(); this.threadPool = threadPool; threadPool.scheduleOnStarted(() -> { blockchainRemoteService = serviceLocator.getBlockchainRemoteService(); @@ -369,21 +371,28 @@ public class BlockchainService extends AbstractService { // Serialize into JSON // WARN: must use GSON, to have same JSON result (e.g identities and joiners field must be converted into String) - String json = gson.toJson(block); + try { + String json = objectMapper.writeValueAsString(block); - // Preparing indexBlocksFromNode - IndexRequestBuilder indexRequest = client.prepareIndex(block.getCurrency(), BLOCK_TYPE) - .setId(block.getNumber().toString()) - .setSource(json); + // Preparing indexBlocksFromNode + IndexRequestBuilder indexRequest = client.prepareIndex(block.getCurrency(), BLOCK_TYPE) + .setId(block.getNumber().toString()) + .setSource(json); - // Execute indexBlocksFromNode - ActionFuture<IndexResponse> futureResponse = indexRequest - .setRefresh(true) - .execute(); + // Execute indexBlocksFromNode + ActionFuture<IndexResponse> futureResponse = indexRequest + .setRefresh(true) + .execute(); - if (wait) { - futureResponse.actionGet(); + if (wait) { + futureResponse.actionGet(); + } } + catch(JsonProcessingException e) { + throw new TechnicalException(e); + } + + } /** @@ -491,9 +500,14 @@ public class BlockchainService extends AbstractService { // Serialize into JSON // WARN: must use GSON, to have same JSON result (e.g identities and joiners field must be converted into String) - String json = gson.toJson(currentBlock); + try { + String json = objectMapper.writeValueAsString(currentBlock); + - indexCurrentBlockFromJson(currentBlock.getCurrency(), json, wait); + indexCurrentBlockFromJson(currentBlock.getCurrency(), json, wait); + } catch(IOException e) { + throw new TechnicalException(e); + } } /** @@ -694,7 +708,7 @@ public class BlockchainService extends AbstractService { if (searchHit.source() != null) { String jsonString = new String(searchHit.source()); try { - block = GsonUtils.newBuilder().create().fromJson(jsonString, BlockchainBlock.class); + block = objectMapper.readValue(jsonString, BlockchainBlock.class); } catch(Exception e) { if (logger.isDebugEnabled()) { logger.debug("Error while parsing block from JSON:\n" + jsonString); diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java index 867e0ef4..3b7b23fc 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java @@ -24,6 +24,7 @@ package org.duniter.elasticsearch.service; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.gson.Gson; @@ -32,6 +33,7 @@ import org.apache.commons.lang3.ArrayUtils; import org.duniter.core.client.model.bma.BlockchainBlock; import org.duniter.core.client.model.bma.BlockchainParameters; import org.duniter.core.client.model.bma.gson.GsonUtils; +import org.duniter.core.client.model.bma.jackson.JacksonUtils; import org.duniter.core.client.model.elasticsearch.Currency; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.service.bma.BlockchainRemoteService; @@ -72,7 +74,7 @@ public class CurrencyService extends AbstractService { public static final String INDEX = "currency"; public static final String CURRENCY_TYPE = "record"; - private final Gson gson; + private final ObjectMapper objectMapper; private BlockchainRemoteService blockchainRemoteService; @Inject @@ -81,7 +83,7 @@ public class CurrencyService extends AbstractService { CryptoService cryptoService, BlockchainRemoteService blockchainRemoteService) { super("duniter." + INDEX, client, settings, cryptoService); - this.gson = GsonUtils.newBuilder().create(); + this.objectMapper = JacksonUtils.newObjectMapper(); this.blockchainRemoteService = blockchainRemoteService; } @@ -299,14 +301,14 @@ public class CurrencyService extends AbstractService { Preconditions.checkNotNull(signature); if (!cryptoService.verify(jsonCurrency, signature, pubkey)) { - String currencyName = GsonUtils.getValueFromJSONAsString(jsonCurrency, "currencyName"); + String currencyName = JacksonUtils.getValueFromJSONAsString(jsonCurrency, "currencyName"); logger.warn(String.format("Currency not added, because bad signature. blockchain [%s]", currencyName)); throw new InvalidSignatureException("Bad signature"); } Currency currency = null; try { - currency = gson.fromJson(jsonCurrency, Currency.class); + currency = objectMapper.readValue(jsonCurrency, Currency.class); Preconditions.checkNotNull(currency); Preconditions.checkNotNull(currency.getCurrencyName()); } catch(Throwable t) { @@ -380,7 +382,7 @@ public class CurrencyService extends AbstractService { SearchHit[] searchHits = response.getHits().getHits(); for (SearchHit searchHit : searchHits) { if (searchHit.source() != null) { - Currency currency = gson.fromJson(new String(searchHit.source(), "UTF-8"), Currency.class); + Currency currency = objectMapper.readValue(new String(searchHit.source(), "UTF-8"), Currency.class); return currency.getSenderPubkey(); } else { @@ -389,7 +391,7 @@ public class CurrencyService extends AbstractService { } } } - catch(SearchPhaseExecutionException | JsonSyntaxException | UnsupportedEncodingException e) { + catch(SearchPhaseExecutionException | JsonSyntaxException | IOException e) { // Failed or no item on index } -- GitLab