Skip to content
Snippets Groups Projects
Commit 63400c0a authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

- Client: add missing i18n keys

- Client: transaction options ar now optional (ask in prompt)
- Network peers : filter on currency, to evict bad currrency peers
parent 46cda03b
No related branches found
No related tags found
No related merge requests found
Showing
with 122 additions and 550 deletions
......@@ -22,15 +22,13 @@ package org.duniter.client.actions;
* #L%
*/
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
import com.beust.jcommander.*;
import com.beust.jcommander.validators.PositiveInteger;
import com.google.common.collect.ImmutableList;
import org.duniter.client.actions.params.AuthParameters;
import org.duniter.client.actions.params.PeerParameters;
import org.duniter.client.actions.utils.Formatters;
import org.duniter.client.actions.validators.PubkeyValidator;
import org.duniter.core.client.config.Configuration;
import org.duniter.core.client.config.ConfigurationOption;
import org.duniter.core.client.model.bma.EndpointApi;
......@@ -66,10 +64,10 @@ public class TransactionAction extends AbstractAction {
@ParametersDelegate
public PeerParameters peerParameters = new PeerParameters();
@Parameter(names = "--amount", description = "Amount", required = true, validateWith = PositiveInteger.class)
public int amount;
@Parameter(names = "--amount", description = "Amount", validateWith = PositiveInteger.class)
public Integer amount;
@Parameter(names = "--output", description = "Output pubkey", required = true)
@Parameter(names = "--output", description = "Output pubkey", validateWith = PubkeyValidator.class)
public String output;
@Parameter(names = "--comment", description = "TX Comment")
......@@ -102,7 +100,6 @@ public class TransactionAction extends AbstractAction {
Currency currency = ServiceLocator.instance().getBlockchainRemoteService().getCurrencyFromPeer(peer);
ServiceLocator.instance().getCurrencyService().save(currency);
peer.setCurrencyId(currency.getId());
peer.setCurrency(currency.getCurrencyName());
ServiceLocator.instance().getPeerService().save(peer);
......@@ -115,9 +112,9 @@ public class TransactionAction extends AbstractAction {
cryptoService.getSeed(
new String(authParameters.salt),
new String(authParameters.password),
authParameters.scryptPArams.get(0), // N
authParameters.scryptPArams.get(1), // p
authParameters.scryptPArams.get(2) // r
authParameters.scryptParams.get(0), // N
authParameters.scryptParams.get(1), // p
authParameters.scryptParams.get(2) // r
));
}
else {
......@@ -132,6 +129,9 @@ public class TransactionAction extends AbstractAction {
keypair.getSecKey());
wallet.setCurrencyId(currency.getId());
// Parse TX parameters
parseTransactionParameters();
// Send TX document to ONE peer
if (!broadcast) {
sendToPeer(peer, wallet);
......@@ -147,6 +147,33 @@ public class TransactionAction extends AbstractAction {
}
}
protected void parseTransactionParameters() {
// Get output
while (output == null) {
JCommander.getConsole().print(I18n.t("duniter4j.client.transaction.params.output.ask") + " ");
output = new String(JCommander.getConsole().readPassword(false));
try {
new PubkeyValidator().validate("output", output);
} catch (ParameterException e) {
JCommander.getConsole().println(e.getMessage());
output = null;
}
}
// Get Amount
while (amount == null) {
JCommander.getConsole().print(I18n.t("duniter4j.client.transaction.params.amount.ask") + " ");
String amountStr = new String(JCommander.getConsole().readPassword(false));
try {
new PositiveInteger().validate("amount", amountStr);
amount = Integer.parseInt(amountStr);
} catch (ParameterException e) {
JCommander.getConsole().println(e.getMessage());
}
}
}
protected void sendToPeer(Peer peer, Wallet wallet) {
TransactionRemoteService txService = ServiceLocator.instance().getTransactionRemoteService();
......@@ -192,7 +219,6 @@ public class TransactionAction extends AbstractAction {
logTxSummary(wallet);
peers.stream().forEach(peer -> {
peer.setCurrencyId(currency.getId());
peer.setCurrency(currency.getCurrencyName());
peerService.save(peer);
......@@ -228,7 +254,6 @@ public class TransactionAction extends AbstractAction {
}
protected void logTxSummary(Wallet wallet) {
// Log TX summary
JCommander.getConsole().println(I18n.t("duniter4j.client.transaction.broadcast.summary",
......
......@@ -41,31 +41,32 @@ import java.util.stream.Collectors;
*/
public class AuthParameters {
@Parameter(names = "--auth-scrypt", description = "Authenticate using Scrypt ?")
@Parameter(names = "--auth-scrypt", description = "Authenticate using Scrypt ?", descriptionKey = "duniter4j.client.params.authScrypt")
public boolean authScrypt = true;
@Parameter(names = "--salt", description = "Salt (to generate the keypair)", password = true)
@Parameter(names = "--salt", description = "Salt (to generate the keypair)", password = true, descriptionKey = "duniter4j.client.params.authScrypt.salt")
public char[] salt;
@Parameter(names = "--passwd", description = "Password (to generate the keypair)", password = true)
@Parameter(names = "--passwd", description = "Password (to generate the keypair)", password = true, descriptionKey = "duniter4j.client.params.authScrypt.passwd")
public char[] password;
@Parameter(names = "--scrypt-params", description = "Scrypt parameters (N,r,p)",
splitter = CommaParameterSplitter.class,
validateWith = PositiveInteger.class)
public List<Integer> scryptPArams;
validateWith = PositiveInteger.class,
descriptionKey = "duniter4j.client.params.authScrypt.scryptParams")
public List<Integer> scryptParams;
public void parse() {
// Compute keypair and wallet
if (StringUtils.isBlank(salt) && authScrypt) {
JCommander.getConsole().print(I18n.t("duniter4j.client.params.authScrypt.ask.salt"));
salt = JCommander.getConsole().readPassword(true);
JCommander.getConsole().print(I18n.t("duniter4j.client.params.authScrypt.ask.salt") + " ");
salt = JCommander.getConsole().readPassword(false);
}
if (StringUtils.isBlank(password) && authScrypt){
JCommander.getConsole().print(I18n.t("duniter4j.client.params.authScrypt.ask.passwd"));
password = JCommander.getConsole().readPassword(true);
JCommander.getConsole().print(I18n.t("duniter4j.client.params.authScrypt.ask.passwd") + " ");
password = JCommander.getConsole().readPassword(false);
}
if (scryptPArams == null && authScrypt) {
if (scryptParams == null && authScrypt) {
JCommander.getConsole().print(I18n.t("duniter4j.client.params.authScrypt.ask.scryptParams",
Ed25519CryptoServiceImpl.SCRYPT_PARAMS_N,
Ed25519CryptoServiceImpl.SCRYPT_PARAMS_r,
......@@ -76,10 +77,10 @@ public class AuthParameters {
if (parts.length != 3) {
throw new ParameterException(I18n.t("duniter4j.client.params.authScrypt.error.scryptParams"));
}
scryptPArams = Arrays.asList(parts).stream().map(part -> Integer.parseInt(part)).collect(Collectors.toList());
scryptParams = Arrays.asList(parts).stream().map(part -> Integer.parseInt(part)).collect(Collectors.toList());
}
else {
scryptPArams = ImmutableList.of(
scryptParams = ImmutableList.of(
Ed25519CryptoServiceImpl.SCRYPT_PARAMS_N,
Ed25519CryptoServiceImpl.SCRYPT_PARAMS_r,
Ed25519CryptoServiceImpl.SCRYPT_PARAMS_p);
......
package org.duniter.client.actions.validators;
import com.beust.jcommander.IParameterValidator;
import com.beust.jcommander.ParameterException;
import org.duniter.core.client.model.bma.Constants;
import java.util.regex.Pattern;
public class PubkeyValidator implements IParameterValidator {
private final static Pattern PUBKEY_PATTERN = Pattern.compile("^" + Constants.Regex.PUBKEY + "$");
public PubkeyValidator() {
}
public void validate(String option, String value) throws ParameterException {
if(!PUBKEY_PATTERN.matcher(value).matches()) {
throw new ParameterException("Parameter " + option + " should be a valid public key (found " + value + ")");
}
}
}
\ No newline at end of file
......@@ -3,7 +3,7 @@ duniter4j.client.info.peer.fallback=Fallback to default Duniter peer\: [%s\:%d]
duniter4j.client.network.action=Display network peers
duniter4j.client.network.cesiumPlus=Cs+
duniter4j.client.network.error.outputFieNotWritable=Output file not writable
duniter4j.client.network.header=Main BlockChain version\: block [%1$s] computed at [%2$s] validated by [%3$3.2f%%] of peers
duniter4j.client.network.header=Main block [%1$s] computed at [%2$s] validated by [%3$3.2f%%] of peers
duniter4j.client.network.loadingPeers=Reading network peers...
duniter4j.client.network.mirror=Mirror
duniter4j.client.network.noPeers=No peers found
......@@ -31,4 +31,10 @@ duniter4j.client.transaction.broadcast.summary=Generate Transation\:\n\t- From\:
duniter4j.client.transaction.error.broadcast.noMemberPeer=No members peers found\! Skipping --broadcast option
duniter4j.client.transaction.error.unknownAuth=Unknown authentication type
duniter4j.client.transaction.loadingMemberPeers=Retrieving member's peers...
duniter4j.client.transaction.params.amount.ask=Please enter the amount (integer value)\:
duniter4j.client.transaction.params.output.ask=Please enter output (public key)\:
duniter4j.client.transaction.sent=Transaction successfully sent.
duniter4j.client.params.authScrypt=Authenticate using salt (Scrypt) ?
duniter4j.client.params.authScrypt.salt=Secret identifier (Salt)
duniter4j.client.params.authScrypt.passwd=Password
duniter4j.client.params.authScrypt.scryptParams=Scrypt parameters (N,r,p)
......@@ -3,7 +3,7 @@ duniter4j.client.info.peer.fallback=Noeud Duniter (par défaut) \: [%s\:%d]
duniter4j.client.network.action=Afficher les noeuds Duniter
duniter4j.client.network.cesiumPlus=Cs+
duniter4j.client.network.error.outputFieNotWritable=Fichier de sortie non inscriptible
duniter4j.client.network.header=Chaine de bloc principal \: bloc [%1$s] calculé à [%2$s] validé par [%3$3.2f%%] des noeuds
duniter4j.client.network.header=Bloc principal [%1$s] calculé à [%2$s] validé par [%3$3.2f%%] des noeuds
duniter4j.client.network.loadingPeers=Lecture des noeuds du réseau...
duniter4j.client.network.mirror=Mirroir
duniter4j.client.network.noPeers=Aucun noeud trouvé
......@@ -31,4 +31,10 @@ duniter4j.client.transaction.broadcast.summary=Envoi de la transation\:\n\t- De\
duniter4j.client.transaction.error.broadcast.noMemberPeer=Aucun noeud membre trouvé \! L'option --broadcast va être ignorée
duniter4j.client.transaction.error.unknownAuth=Type d'authentification inconnue
duniter4j.client.transaction.loadingMemberPeers=Récupération des noeuds membres...
duniter4j.client.transaction.params.amount.ask=Veuillez entrer le montant (valeur entière) \:
duniter4j.client.transaction.params.output.ask=Veuillez entrer le destinataire (clef publique) \:
duniter4j.client.transaction.sent=Transaction envoyé avec succès.
duniter4j.client.params.authScrypt=Authentification par salage Scrypt ?
duniter4j.client.params.authScrypt.salt=Identifiant secret (salt)
duniter4j.client.params.authScrypt.passwd=Mot de passe
duniter4j.client.params.authScrypt.scryptParams=Paramètre de salage Scrypt (N,r,p)
......@@ -80,11 +80,6 @@
<groupId>org.nuiton.i18n</groupId>
<artifactId>nuiton-i18n</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
......
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java :: Core Client API
* %%
* Copyright (C) 2014 - 2016 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import org.duniter.core.client.model.bma.EndpointApi;
import org.duniter.core.client.model.bma.NetworkPeering;
import org.duniter.core.util.http.InetAddressUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
public class EndpointAdapter extends TypeAdapter<NetworkPeering.Endpoint> {
@Override
public NetworkPeering.Endpoint read(JsonReader reader) throws IOException {
if (reader.peek() == com.google.gson.stream.JsonToken.NULL) {
reader.nextNull();
return null;
}
String ept = reader.nextString();
ArrayList<String> parts = new ArrayList<>(Arrays.asList(ept.split(" ")));
NetworkPeering.Endpoint endpoint = new NetworkPeering.Endpoint();
endpoint.port = Integer.parseInt(parts.remove(parts.size() - 1));
for (String word : parts) {
if (InetAddressUtils.isIPv4Address(word)) {
endpoint.ipv4 = word;
} else if (InetAddressUtils.isIPv6Address(word)) {
endpoint.ipv6 = word;
} else if (word.trim().length() > 0) {
endpoint.dns = word;
} else {
try {
endpoint.api = EndpointApi.valueOf(word);
} catch (IllegalArgumentException e) {
// skip this part
}
}
}
if (endpoint.api == null) {
endpoint.api = EndpointApi.UNDEFINED;
}
return endpoint;
}
public void write(JsonWriter writer, NetworkPeering.Endpoint endpoint) throws IOException {
if (endpoint == null) {
writer.nullValue();
return;
}
writer.value(endpoint.api.name() + " " +
endpoint.dns + " " +
endpoint.ipv4 + " " +
endpoint.ipv6 + " " +
endpoint.port);
}
}
\ No newline at end of file
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.common.collect.Multimap;
import com.google.gson.GsonBuilder;
import org.duniter.core.client.model.bma.BlockchainBlock;
import org.duniter.core.client.model.bma.NetworkPeering;
import org.duniter.core.util.json.JsonArrayParser;
import org.duniter.core.util.json.JsonAttributeParser;
import java.util.List;
public class GsonUtils {
public static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static GsonBuilder newBuilder() {
return new GsonBuilder()
// make sure date will be serialized
.setDateFormat(DATE_PATTERN)
// Register Multimap adapter
.registerTypeAdapter(Multimap.class, new MultimapTypeAdapter())
// Register Blockchain.* adapter
.registerTypeAdapter(BlockchainBlock.Identity.class, new IdentityTypeAdapter())
.registerTypeAdapter(BlockchainBlock.Joiner.class, new JoinerTypeAdapter())
.registerTypeAdapter(BlockchainBlock.Revoked.class, new RevokedTypeAdapter())
// Register endpoint adapter
.registerTypeAdapter(NetworkPeering.Endpoint.class, new EndpointAdapter())
;
}
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);
}
}
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.gson.*;
import org.duniter.core.client.model.bma.BlockchainBlock;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Type;
public class IdentityTypeAdapter implements JsonDeserializer<BlockchainBlock.Identity>, JsonSerializer<BlockchainBlock.Identity>{
@Override
public BlockchainBlock.Identity deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String identityStr = json.getAsString();
if (StringUtils.isBlank(identityStr)) {
return null;
}
String[] identityParts = identityStr.split(":");
if (identityParts.length != 4) {
throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 4 parts, but found %s.", identityParts.length));
}
BlockchainBlock.Identity result = new BlockchainBlock.Identity();
int i = 0;
result.setPublicKey(identityParts[i++]);
result.setSignature(identityParts[i++]);
result.setBlockUid(identityParts[i++]);
result.setUserId(identityParts[i++]);
return result;
}
@Override
public JsonElement serialize(BlockchainBlock.Identity identity, Type type, JsonSerializationContext context) {
String result = new StringBuilder()
.append(identity.getPublicKey()).append(":")
.append(identity.getSignature()).append(":")
.append(identity.getBlockUid()).append(":")
.append(identity.getUserId()).toString();
return context.serialize(result.toString(), String.class);
}
}
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.gson.*;
import org.duniter.core.client.model.bma.BlockchainBlock;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Type;
public class JoinerTypeAdapter implements JsonDeserializer<BlockchainBlock.Joiner>, JsonSerializer<BlockchainBlock.Joiner>{
@Override
public BlockchainBlock.Joiner deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String identityStr = json.getAsString();
if (StringUtils.isBlank(identityStr)) {
return null;
}
String[] identityParts = identityStr.split(":");
if (identityParts.length != 5) {
throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 5 parts, but found %s.", identityParts.length));
}
BlockchainBlock.Joiner result = new BlockchainBlock.Joiner();
int i = 0;
result.setPublicKey(identityParts[i++]);
result.setSignature(identityParts[i++]);
result.setMembershipBlockUid(identityParts[i++]);
result.setIdtyBlockUid(identityParts[i++]);
result.setUserId(identityParts[i++]);
return result;
}
@Override
public JsonElement serialize(BlockchainBlock.Joiner member, Type type, JsonSerializationContext context) {
String result = new StringBuilder()
.append(member.getPublicKey()).append(":")
.append(member.getSignature()).append(":")
.append(member.getMembershipBlockUid()).append(":")
.append(member.getIdtyBlockUid()).append(":")
.append(member.getUserId()).toString();
return context.serialize(result.toString(), String.class);
}
}
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import org.duniter.core.util.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.*;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class MultimapTypeAdapter implements JsonSerializer<Multimap>, JsonDeserializer<Multimap> {
@Override
public JsonElement serialize(final Multimap src, final Type typeOfSrc, final JsonSerializationContext context) {
return context.serialize(src.asMap(), createMapType(typeOfSrc));
}
@Override
public Multimap deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
throws JsonParseException {
final Multimap multimap = HashMultimap.create();
final Map map = context.deserialize(json, createMapType(typeOfT));
for (final Object key : map.keySet()) {
final Collection values = (Collection) map.get(key);
multimap.putAll(key, values);
}
return multimap;
}
private Type createMapType(final Type multimapType) {
Preconditions.checkArgument(multimapType instanceof ParameterizedType);
final ParameterizedType paramType = (ParameterizedType)multimapType;
final Type[] typeArguments = paramType.getActualTypeArguments();
Preconditions.checkArgument(2 == typeArguments.length, "Type must contain exactly 2 sortType arguments.");
final ParameterizedTypeImpl valueType = new ParameterizedTypeImpl(Collection.class, null, typeArguments[1]);
final ParameterizedTypeImpl mapType = new ParameterizedTypeImpl(Map.class, null, typeArguments[0], valueType);
return mapType;
}
}
\ No newline at end of file
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class ParameterizedTypeImpl implements ParameterizedType {
private final Type rawType;
private final Type ownerType;
private final Type[] typeArguments;
public ParameterizedTypeImpl(final Type rawType, final Type ownerType, final Type... typeArguments) {
this.rawType = rawType;
this.ownerType = ownerType;
this.typeArguments = typeArguments;
}
@Override
public Type[] getActualTypeArguments() {
return typeArguments;
}
@Override
public Type getRawType() {
return rawType;
}
@Override
public Type getOwnerType() {
return ownerType;
}
}
\ No newline at end of file
package org.duniter.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.gson.*;
import org.duniter.core.client.model.bma.BlockchainBlock;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Type;
public class RevokedTypeAdapter implements JsonDeserializer<BlockchainBlock.Revoked>, JsonSerializer<BlockchainBlock.Revoked>{
@Override
public BlockchainBlock.Revoked deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String identityStr = json.getAsString();
if (StringUtils.isBlank(identityStr)) {
return null;
}
String[] identityParts = identityStr.split(":");
if (identityParts.length != 2) {
throw new JsonParseException(String.format("Bad format for BlockchainBlock.Revoked. Should have 4 parts, but found %s.", identityParts.length));
}
BlockchainBlock.Revoked result = new BlockchainBlock.Revoked();
int i = 0;
result.setSignature(identityParts[i++]);
result.setUserId(identityParts[i++]);
return result;
}
@Override
public JsonElement serialize(BlockchainBlock.Revoked input, Type type, JsonSerializationContext context) {
String result = new StringBuilder()
.append(input.getSignature()).append(":")
.append(input.getUserId()).toString();
return context.serialize(result.toString(), String.class);
}
}
......@@ -239,6 +239,21 @@ public class Peer implements LocalEntity<String>, Serializable {
this.id = id;
}
@JsonIgnore
public String getHost() {
return this.host; // computed in init()
}
@JsonIgnore
public String getUrl() {
return this.url; // computed in init()
}
@JsonIgnore
public String computeKey() {
return Joiner.on('-').skipNulls().join(pubkey, dns, ipv4, ipv6, port, useSsl);
}
public String getApi() {
return api;
}
......@@ -296,16 +311,6 @@ public class Peer implements LocalEntity<String>, Serializable {
this.pubkey = pubkey;
}
@JsonIgnore
public String getHost() {
return this.host; // computed in init()
}
@JsonIgnore
public String getUrl() {
return this.url; // computed in init()
}
public String getHash() {
return hash;
}
......@@ -322,21 +327,14 @@ public class Peer implements LocalEntity<String>, Serializable {
this.currency = currency;
}
@JsonIgnore
public Stats getStats() {
return stats;
}
@JsonIgnore
public void setStats(Stats stats) {
this.stats = stats;
}
@JsonIgnore
public String computeKey() {
return Joiner.on('-').skipNulls().join(pubkey, dns, ipv4, ipv6, port, useSsl);
}
public String toString() {
StringJoiner joiner = new StringJoiner(" ");
if (api != null) {
......
......@@ -370,7 +370,7 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean
}
}
// deserialize using gson
// deserialize Json
else {
try {
result = readValue(content, ResultClass);
......
......@@ -38,6 +38,7 @@ import org.duniter.core.client.service.exception.HttpNotFoundException;
import org.duniter.core.exception.TechnicalException;
import org.duniter.core.service.CryptoService;
import org.duniter.core.util.CollectionUtils;
import org.duniter.core.util.ObjectUtils;
import org.duniter.core.util.Preconditions;
import org.duniter.core.util.StringUtils;
import org.duniter.core.util.concurrent.CompletableFutures;
......@@ -125,13 +126,15 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
}
@Override
public List<Peer> getPeers(Peer firstPeer, Filter filter, Sort sort) {
public List<Peer> getPeers(final Peer mainPeer, Filter filter, Sort sort) {
try {
return asyncGetPeers(firstPeer, null)
return asyncGetPeers(mainPeer, null)
.thenCompose(CompletableFutures::allOfToList)
.thenApply(this::fillPeerStatsConsensus)
.thenApply(peers -> peers.stream()
// Filter on currency
.filter(peer -> ObjectUtils.equals(mainPeer.getCurrency(), peer.getCurrency()))
// filter, then sort
.filter(peerFilter(filter))
.sorted(peerComparator(sort))
......@@ -154,7 +157,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
}
@Override
public CompletableFuture<List<CompletableFuture<Peer>>> asyncGetPeers(Peer mainPeer, ExecutorService executor) throws ExecutionException, InterruptedException {
public CompletableFuture<List<CompletableFuture<Peer>>> asyncGetPeers(final Peer mainPeer, ExecutorService executor) throws ExecutionException, InterruptedException {
Preconditions.checkNotNull(mainPeer);
log.debug("Loading network peers...");
......@@ -169,7 +172,12 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
.thenApply(v -> {
final Map<String, String> memberUids = memberUidsFuture.join();
return peersFuture.join().stream()
.map(peer -> asyncRefreshPeer(peer, memberUids, pool))
.map(peer -> {
if (mainPeer.getUrl().equals(peer.getUrl())) {
return asyncRefreshPeer(mainPeer, memberUids, pool);
}
return asyncRefreshPeer(peer, memberUids, pool);
})
.collect(Collectors.toList());
});
}
......@@ -533,6 +541,9 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network
protected Peer getCurrentBlock(final Peer peer) {
JsonNode json = executeRequest(peer, BMA_URL_BLOCKCHAIN_CURRENT , JsonNode.class);
String currency = json.has("currency") ? json.get("currency").asText() : null;
peer.setCurrency(currency);
Integer number = json.has("number") ? json.get("number").asInt() : null;
peer.getStats().setBlockNumber(number);
......
......@@ -23,8 +23,8 @@ package org.duniter.core.client.service.bma;
*/
import com.fasterxml.jackson.core.JsonProcessingException;
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;
......@@ -40,8 +40,6 @@ 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);
......@@ -122,7 +120,7 @@ public class BlockchainRemoteServiceTest {
try {
objectMapper.readValue(jsonBlock, BlockchainBlock.class);
}
catch(JsonSyntaxException e) {
catch(JsonProcessingException e) {
e.printStackTrace();
Assert.fail(String.format("Invalid block format #%s. See previous error", number));
}
......
......@@ -35,6 +35,7 @@ import org.duniter.core.model.NullProgressionModel;
import org.duniter.core.model.ProgressionModel;
import org.duniter.core.service.CryptoService;
import org.duniter.core.util.CollectionUtils;
import org.duniter.core.util.ObjectUtils;
import org.duniter.core.util.Preconditions;
import org.duniter.core.util.concurrent.CompletableFutures;
import org.duniter.core.util.json.JsonSyntaxException;
......@@ -132,6 +133,8 @@ public class PeerService extends AbstractService {
.thenCompose(CompletableFutures::allOfToList)
.thenApply(networkService::fillPeerStatsConsensus)
.thenApply(peers -> peers.stream()
// filter on currency
.filter(peer -> ObjectUtils.equals(firstPeer.getCurrency(), peer.getCurrency()))
// filter, then sort
.filter(networkService.peerFilter(filterDef))
.map(peer -> savePeer(peer))
......
......@@ -18,7 +18,6 @@
<slf4j.version>1.7.5</slf4j.version>
<guava.version>18.0</guava.version>
<xml-apis.version>2.0.2</xml-apis.version>
<gson.version>2.2.2</gson.version>
<kalium.version>0.5.0</kalium.version>
<scrypt.version>1.4.0</scrypt.version>
<elasticsearch.version>2.3.3</elasticsearch.version>
......@@ -206,11 +205,6 @@
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
......@@ -221,11 +215,6 @@
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!-- NaCL lib -->
<dependency>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment