Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • clients/cesium-grp/cesium-plus-pod
  • clients/java/duniter4j
  • ji_emme/duniter4j
  • dvermd/cesium-plus-pod
  • okayotanoka/cesium-plus-pod
  • pokapow/cesium-plus-pod
  • pini-gh/cesium-plus-pod
7 results
Show changes
Showing
with 1272 additions and 528 deletions
package org.duniter.core.client.model.exception;
/*-
* #%L
* Duniter4j :: Core Client API
* %%
* Copyright (C) 2014 - 2017 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.exception.TechnicalException;
/**
......
......@@ -22,6 +22,7 @@ package org.duniter.core.client.model.local;
* #L%
*/
import org.duniter.core.model.IEntity;
import org.duniter.core.util.ObjectUtils;
import java.io.Serializable;
......@@ -32,13 +33,13 @@ import java.util.List;
* A wallet is a user account
* Created by eis on 13/01/15.
*/
public class Contact implements LocalEntity<Long>, Serializable {
public class Contact implements IEntity<Long>, Serializable {
private long id;
private long accountId;
private String name;
private long phoneContactId = 0;
private List<Identity> identities = new ArrayList<Identity>();
private List<Identity> identities = new ArrayList<>();
@Override
public Long getId() {
......@@ -113,7 +114,7 @@ public class Contact implements LocalEntity<Long>, Serializable {
public boolean hasIdentityForCurrency(String currencyId) {
return identities.stream()
.anyMatch(identity -> identity.getCurrencyId() != null
&& currencyId.equals(identity.getCurrencyId()));
.anyMatch(identity -> identity.getCurrency() != null
&& currencyId.equals(identity.getCurrency()));
}
}
......@@ -25,84 +25,42 @@ package org.duniter.core.client.model.local;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.duniter.core.client.model.Account;
import lombok.*;
import lombok.experimental.FieldNameConstants;
import org.duniter.core.client.model.bma.BlockchainParameters;
/**
* Created by eis on 05/02/15.
*/
public class Currency implements LocalEntity<String>, Serializable {
private String currencyName;
private Integer membersCount;
private String firstBlockSignature;
private Long lastUD;
@Data
@Builder
@FieldNameConstants
@NoArgsConstructor
@AllArgsConstructor
public class Currency implements ICurrency {
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class Fields {}
private String id;
private BlockchainParameters parameters;
public Currency() {
}
public Currency(String currencyName,
String firstBlockSignature,
int membersCount,
BlockchainParameters parameters) {
this.currencyName = currencyName;
this.firstBlockSignature = firstBlockSignature;
this.membersCount = membersCount;
this.parameters = parameters;
}
private String firstBlockSignature;
private Integer membersCount;
private Long dividend;
private Integer unitbase;
@JsonIgnore
public String getId() {
return currencyName;
}
public String getCurrencyName()
{
return currencyName;
}
public Integer getMembersCount() {
return membersCount;
}
public String getFirstBlockSignature() {
return firstBlockSignature;
}
public void setId(String id) {
this.currencyName = id;
}
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
public void setMembersCount(Integer membersCount) {
this.membersCount = membersCount;
}
public void setFirstBlockSignature(String firstBlockSignature) {
this.firstBlockSignature = firstBlockSignature;
}
@Deprecated
public Long getLastUD() {
return lastUD;
}
public void setLastUD(Long lastUD) {
this.lastUD = lastUD;
return dividend;
}
public BlockchainParameters getParameters() {
return parameters;
}
public void setParameters(BlockchainParameters parameters) {
this.parameters = parameters;
@JsonIgnore
@Deprecated
public void setLastUD(long lastUD) {
this.dividend = lastUD;
}
public String toString() {
return currencyName;
return id;
}
}
\ No newline at end of file
package org.duniter.core.client.model.local;
import lombok.Builder;
import lombok.Data;
import org.duniter.core.model.IEntity;
import java.math.BigInteger;
@Data
@Builder
public class Dividend implements IEntity<String> {
public static final String computeId(Dividend entity) {
return entity.currency + "-" + entity.number;
}
private String id;
private String currency;
private Integer number;
private Long dividend;
}
package org.duniter.core.client.model.elasticsearch;
package org.duniter.core.client.model.local;
/*
* #%L
* UCoin Java Client :: Core API
* UCoin Java :: Core Client API
* %%
* Copyright (C) 2014 - 2015 EIS
* 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
......@@ -22,24 +22,39 @@ package org.duniter.core.client.model.elasticsearch;
* #L%
*/
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.duniter.core.client.model.bma.BlockchainParameters;
import org.duniter.core.model.IEntity;
import java.io.Serializable;
/**
* Created by eis on 05/02/15.
*/
public class Currency extends org.duniter.core.client.model.local.Currency implements Serializable {
public interface ICurrency extends IEntity<String>, Serializable {
interface Fields extends IEntity.Fields {
String FIRST_BLOCK_SIGNATURE = "firstBlockSignature";
String MEMBER_COUNT = "membersCount";
String DIVIDEND = "dividend";
String PARAMETERS = "parameters";
String UNITBASE = "unitbase";
}
private String[] tags;
BlockchainParameters getParameters();
void setParameters(BlockchainParameters parameters);
public String[] getTags() {
return tags;
}
String getFirstBlockSignature();
void setFirstBlockSignature(String signature);
public void setTags(String[] tags) {
this.tags = tags;
}
Integer getMembersCount();
void setMembersCount(Integer memberCount);
Long getDividend();
void setDividend(Long dividend);
Integer getUnitbase();
void setUnitbase(Integer unitBase);
}
\ No newline at end of file
......@@ -2,7 +2,7 @@ package org.duniter.core.client.model.local;
/*
* #%L
* UCoin Java Client :: Core API
* Duniter4j :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
......@@ -23,46 +23,46 @@ package org.duniter.core.client.model.local;
*/
import org.duniter.core.client.model.BasicIdentity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
import org.duniter.core.client.model.BaseIdentity;
public class Identity extends BasicIdentity {
@Data
@FieldNameConstants
public class Identity extends BaseIdentity {
private static final long serialVersionUID = -7451079677730158794L;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class Fields extends BaseIdentity.Fields {}
private String currency;
// The timestamp value of the signature date (a BLOCK_UID)
private String timestamp = null;
// Indicate whether the certification is written in the blockchain or not.
private Boolean isMember = null;
private Boolean wasMember = null;
private String currencyId;
/**
* The timestamp value of the signature date (a BLOCK_UID)
* @return
*/
@JsonIgnore
public String getTimestamp() {
return timestamp;
}
@JsonIgnore
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
/**
* Indicate whether the certification is written in the blockchain or not.
*/
public Boolean getIsMember() {
return isMember;
}
public void setMember(Boolean isMember) {
this.isMember = isMember;
}
public String getCurrencyId() {
return currencyId;
@JsonIgnore
public String getCurrency() {
return currency;
}
public void setCurrencyId(String currencyId) {
this.currencyId = currencyId;
@JsonIgnore
public void setCurrency(String currency) {
this.currency = currency;
}
}
package org.duniter.core.client.model;
package org.duniter.core.client.model.local;
/*
* #%L
* UCoin Java Client :: Core API
* Duniter4j :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
......@@ -23,29 +23,28 @@ package org.duniter.core.client.model;
*/
import org.duniter.core.client.model.local.Identity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.experimental.FieldNameConstants;
import org.duniter.core.client.model.BaseIdentity;
import org.duniter.core.model.IEntity;
public class Member extends Identity {
@Data
@FieldNameConstants
public class Member extends Identity implements IEntity<String> {
private static final long serialVersionUID = 8448049949323699700L;
private String number;
private String hash;
public static class Fields extends Identity.Fields {}
public String getNumber() {
return number;
}
private static final long serialVersionUID = 8448049949323699700L;
public void setNumber(String number) {
this.number = number;
@JsonIgnore
public String getId() {
return getPubkey();
}
public String getHash() {
return hash;
@JsonIgnore
public void setId(String pubkey) {
setPubkey(pubkey);
}
public void setHash(String hash) {
this.hash = hash;
}
}
......@@ -23,6 +23,10 @@ package org.duniter.core.client.model.local;
*/
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldNameConstants;
import org.duniter.core.model.IEntity;
import java.io.Serializable;
......@@ -30,19 +34,10 @@ import java.io.Serializable;
* A wallet's movement (DU or transfer)
* @author
*/
public class Movement implements LocalEntity<Long>, Serializable {
public static final String PROPERTY_MEDIAN_TIME = "medianTime";
public static final String PROPERTY_BLOCK_NUMBER= "blockNumber";
public static final String PROPERTY_BLOCK_HASH = "blockHash";
public static final String PROPERTY_DIVIDEND = "dividend";
public static final String PROPERTY_IS_UD = "isUD";
public static final String PROPERTY_ISSUER = "issuer";
public static final String PROPERTY_RECIPIENT = "recipient";
public static final String PROPERTY_AMOUNT = "amount";
public static final String PROPERTY_UNITBASE = "unitbase";
public static final String PROPERTY_COMMENT = "comment";
public static final String PROPERTY_TX_VERSION = "txVersion";
@FieldNameConstants
@Data
@Builder
public class Movement implements IEntity<Long>, Serializable {
private Long id;
private long walletId;
......@@ -58,64 +53,6 @@ public class Movement implements LocalEntity<Long>, Serializable {
private String comment;
private String txVersion;
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
public long getWalletId() {
return walletId;
}
public void setWalletId(long walletId) {
this.walletId = walletId;
}
public int getUnitbase() {
return unitbase;
}
public void setUnitbase(int unitbase) {
this.unitbase = unitbase;
}
public String getBlockHash() {
return blockHash;
}
public void setBlockHash(String blockHash) {
this.blockHash = blockHash;
}
public long getAmount() {
return amount;
}
public void setAmount(long amount) {
this.amount = amount;
}
public Long getMedianTime() {
return medianTime;
}
public void setMedianTime(Long medianTime) {
this.medianTime = medianTime;
}
public Integer getBlockNumber() {
return blockNumber;
}
public void setBlockNumber(Integer blockNumber) {
this.blockNumber = blockNumber;
}
@JsonIgnore
public boolean isUD() {
return isUD;
......@@ -125,40 +62,9 @@ public class Movement implements LocalEntity<Long>, Serializable {
this.isUD = isUD;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
@JsonIgnore
public boolean isValidate() {
return blockNumber != null;
}
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getRecipient() {
return recipient;
}
public long getDividend() {
return dividend;
}
public void setDividend(long dividend) {
this.dividend = dividend;
}
}
......@@ -78,17 +78,17 @@ public final class Movements {
.map(recipient -> {
// If more than one issuer, apply a ratio (=input amount %)
Double amount = getTxOutputAmountByIssuerAndRecipient(outputs, issuer, recipient) * issuerInputRatio;
Movement movement = new Movement();
movement.setBlockNumber(block.getNumber());
movement.setBlockHash(block.getHash());
movement.setMedianTime(block.getMedianTime());
movement.setAmount(amount.longValue());
movement.setUnitbase(0); // conversion has been done when computed 'amount'
movement.setIssuer(issuer);
movement.setRecipient(recipient);
movement.setBlockNumber(block.getNumber());
movement.setComment(tx.getComment());
return movement;
return Movement.builder()
.blockNumber(block.getNumber())
.blockHash(block.getHash())
.medianTime(block.getMedianTime())
.amount(amount.longValue())
.unitbase(0) // conversion has been done when computed 'amount'
.issuer(issuer)
.recipient(recipient)
.blockNumber(block.getNumber())
.comment(tx.getComment())
.build();
})
// Exclude movements to itself (e.g. changes)
.filter(movement -> movement.getAmount() != 0);
......
......@@ -2,7 +2,7 @@ package org.duniter.core.client.model.local;
/*
* #%L
* UCoin Java Client :: Core API
* Duniter4j :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
......@@ -24,21 +24,22 @@ package org.duniter.core.client.model.local;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import lombok.Data;
import lombok.experimental.FieldNameConstants;
import org.apache.commons.lang3.StringUtils;
import org.duniter.core.client.model.bma.EndpointApi;
import org.duniter.core.client.model.bma.NetworkPeering;
import org.duniter.core.util.Preconditions;
import org.duniter.core.util.StringUtils;
import org.duniter.core.model.IEntity;
import org.duniter.core.util.http.InetAddressUtils;
import java.io.Serializable;
import java.util.StringJoiner;
public class Peer implements LocalEntity<String>, Serializable {
@Data
@FieldNameConstants
public class Peer implements IEntity<String> {
public static Builder newBuilder() {
public static Builder builder() {
return new Builder();
}
......@@ -49,61 +50,71 @@ public class Peer implements LocalEntity<String>, Serializable {
private String ipv4;
private String ipv6;
private Integer port;
private String epId;
private Boolean useSsl;
private String pubkey;
private String hash;
private String currency;
private String path;
private Peering peering;
private Stats stats;
public Builder() {
}
public Builder setApi(String api) {
public Builder api(String api) {
this.api = api;
return this;
}
public Builder setDns(String dns) {
public Builder dns(String dns) {
this.dns = dns;
return this;
}
public Builder setIpv4(String ipv4) {
public Builder ipv4(String ipv4) {
this.ipv4 = ipv4;
return this;
}
public Builder setIpv6(String ipv6) {
public Builder ipv6(String ipv6) {
this.ipv6 = ipv6;
return this;
}
public Builder setPort(int port) {
public Builder port(int port) {
this.port = port;
return this;
}
public Builder setUseSsl(boolean useSsl) {
public Builder useSsl(boolean useSsl) {
this.useSsl = useSsl;
return this;
}
public Builder setCurrency(String currency) {
public Builder currency(String currency) {
this.currency = currency;
return this;
}
public Builder setPubkey(String pubkey) {
public Builder pubkey(String pubkey) {
this.pubkey = pubkey;
return this;
}
public Builder setHash(String hash) {
public Builder hash(String hash) {
this.hash = hash;
return this;
}
public Builder setHost(String host) {
public Builder epId(String epId) {
this.epId = epId;
return this;
}
public Builder host(String host) {
Preconditions.checkNotNull(host);
if (InetAddressUtils.isIPv4Address(host)) {
this.ipv4 = host;
......@@ -117,35 +128,101 @@ public class Peer implements LocalEntity<String>, Serializable {
return this;
}
public Builder setEndpoint(NetworkPeering.Endpoint source) {
public Builder endpoint(NetworkPeering.Endpoint source) {
Preconditions.checkNotNull(source);
if (source.api != null) {
setApi(source.api.name());
api(source.api);
}
if (StringUtils.isNotBlank(source.id)) {
epId(source.id);
}
if (StringUtils.isNotBlank(source.dns)) {
setDns(source.dns);
dns(source.dns);
}
if (StringUtils.isNotBlank(source.ipv4)) {
setIpv4(source.ipv4);
ipv4(source.ipv4);
}
if (StringUtils.isNotBlank(source.ipv6)) {
setIpv6(source.ipv6);
ipv6(source.ipv6);
}
if (StringUtils.isNotBlank(source.ipv6)) {
setHost(source.ipv6);
host(source.ipv6);
}
if (source.port != null) {
setPort(source.port);
port(source.port);
}
if (StringUtils.isNotBlank(source.path)) {
path(source.path);
}
return this;
}
public Builder peering(NetworkPeering remotePeering) {
this.peering = this.peering != null ? this.peering : new Peering();
this.pubkey = remotePeering.getPubkey();
this.peering.setVersion(remotePeering.getVersion());
this.peering.setSignature(remotePeering.getSignature());
String raw = remotePeering.getRaw();
if (StringUtils.isBlank(raw)) {
raw = remotePeering.toUnsignedRaw();
}
this.peering.setRaw(raw);
// Block number+hash
if (remotePeering.getBlock() != null) {
String[] blockParts = remotePeering.getBlock().split("-");
if (blockParts.length == 2) {
this.peering.setBlockNumber(Integer.parseInt(blockParts[0]));
this.peering.setBlockHash(blockParts[1]);
}
}
return this;
}
public Builder stats(NetworkPeering remotePeering) {
this.stats = this.stats != null ? this.stats : new Stats();
// Block number+hash
if (remotePeering.getBlock() != null) {
String[] blockParts = remotePeering.getBlock().split("-");
if (blockParts.length == 2) {
this.stats.setBlockNumber(Integer.parseInt(blockParts[0]));
this.stats.setBlockHash(blockParts[1]);
}
}
// Update peer status UP/DOWN
if ("UP".equalsIgnoreCase(remotePeering.getStatus())) {
stats.setStatus(Peer.PeerStatus.UP);
// FIXME: Duniter 1.7 return lastUpTime in ms. Check if this a bug or not
stats.setLastUpTime((long)Math.round(System.currentTimeMillis() / 1000));
}
else {
stats.setStatus(Peer.PeerStatus.DOWN);
}
return this;
}
public void path(String path) {
this.path = path;
}
public Peer build() {
int port = this.port != null ? this.port : 80;
String api = this.api != null ? this.api : EndpointApi.BASIC_MERKLED_API.label();
boolean useSsl = this.useSsl != null ? this.useSsl :
(port == 443 || this.api == EndpointApi.BMAS.name());
String api = this.api != null ? this.api : EndpointApi.BASIC_MERKLED_API.name();
(port == 443 || EndpointApi.BMAS.label().equals(this.api));
Peer ep = new Peer(api, dns, ipv4, ipv6, port, useSsl);
if (StringUtils.isNotBlank(this.epId)) {
ep.setEpId(this.epId);
}
if (StringUtils.isNotBlank(this.currency)) {
ep.setCurrency(this.currency);
}
......@@ -155,28 +232,39 @@ public class Peer implements LocalEntity<String>, Serializable {
if (StringUtils.isNotBlank(this.hash)) {
ep.setHash(this.hash);
}
if (StringUtils.isNotBlank(this.path)) {
ep.setPath(this.path);
}
// Peering
if (this.peering != null) {
ep.setPeering(this.peering);
}
// Stats
if (this.stats != null) {
ep.setStats(this.stats);
}
return ep;
}
}
public static final String PROPERTY_STATS = "stats";
private String id;
private String api;
private String epId;
private String dns;
private String ipv4;
private String ipv6;
private String path;
private String url;
private String host;
private String pubkey;
private String host;
private String hash;
private String currency;
private Stats stats = new Stats();
private Peering peering = new Peering();
private int port;
private boolean useSsl;
......@@ -192,7 +280,7 @@ public class Peer implements LocalEntity<String>, Serializable {
*/
@Deprecated
public Peer(String host, Integer port) {
this.api = EndpointApi.BASIC_MERKLED_API.name();
this.api = EndpointApi.BASIC_MERKLED_API.label();
if (InetAddressUtils.isIPv4Address(host)) {
this.ipv4 = host;
}
......@@ -203,7 +291,7 @@ public class Peer implements LocalEntity<String>, Serializable {
this.dns = host;
}
this.port = port != null ? port : 80;
this.useSsl = (port == 443 || this.api == EndpointApi.BMAS.name());
this.useSsl = (port == 443 || EndpointApi.BMAS.label().equals(this.api));
init();
}
......@@ -223,25 +311,25 @@ public class Peer implements LocalEntity<String>, Serializable {
// else (if define) use dns
// else (if define) use ipv6
host = ((port == 443 || useSsl) && dns != null) ? dns :
(ipv4 != null && InetAddressUtils.isNotLocalIPv4Address(ipv4) ? ipv4 :
(ipv4 != null && InetAddressUtils.isInternetIPv4Address(ipv4) ? ipv4 :
(dns != null ? dns :
(ipv6 != null ? "[" + ipv6 + "]" : "")));
// Use local IPv4 if no other host found
if (StringUtils.isBlank(host) && ipv4 != null && InetAddressUtils.isIPv4Address(ipv4)) {
host = ipv4;
}
String protocol = (port == 443 || useSsl) ? "https" : "http";
this.url = protocol + "://" + host + (port != 80 ? (":" + port) : "");
String protocol = ((port == 443 || useSsl) ? "https" : "http");
this.url = protocol + "://" + host + (port != 80 ? (":" + port) : "") + (StringUtils.isNotBlank(path) ? path : "");
}
@JsonIgnore
public String getId() {
return id;
return hash;
}
@JsonIgnore
public void setId(String id) {
this.id = id;
public void setId(String hash) {
this.hash = hash;
}
@JsonIgnore
......@@ -254,11 +342,6 @@ public class Peer implements LocalEntity<String>, Serializable {
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;
}
......@@ -294,6 +377,14 @@ public class Peer implements LocalEntity<String>, Serializable {
init();
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getPort() {
return port;
}
......@@ -303,6 +394,14 @@ public class Peer implements LocalEntity<String>, Serializable {
init();
}
public String getEpId() {
return epId;
}
public void setEpId(String epId) {
this.epId = epId;
}
public boolean isUseSsl() {
return useSsl;
}
......@@ -344,11 +443,22 @@ public class Peer implements LocalEntity<String>, Serializable {
this.stats = stats;
}
public Peering getPeering() {
return peering;
}
public void setPeering(Peering peering) {
this.peering = peering;
}
public String toString() {
StringJoiner joiner = new StringJoiner(" ");
if (api != null) {
joiner.add(api);
}
if (epId != null) {
joiner.add(epId);
}
if (dns != null) {
joiner.add(dns);
}
......@@ -361,19 +471,37 @@ public class Peer implements LocalEntity<String>, Serializable {
if (port != 80) {
joiner.add(String.valueOf(port));
}
if (StringUtils.isNotBlank(path)) {
joiner.add(path);
}
return joiner.toString();
}
public enum PeerStatus {
UP,
DOWN,
ERROR
}
@Data
@FieldNameConstants
public static class Peering {
private Integer version;
private String signature;
private Integer blockNumber;
private String blockHash;
private String raw;
}
@Data
@FieldNameConstants
public static class Stats {
public static final String PROPERTY_STATUS = "status";
public static final String PROPERTY_LAST_UP_TIME = "lastUpTime";
private String software;
private String version;
private PeerStatus status = PeerStatus.UP; // default
private Integer blockNumber;
......@@ -386,110 +514,14 @@ public class Peer implements LocalEntity<String>, Serializable {
private Double consensusPct = 0d;
private String uid;
private Long lastUpTime;
private Long firstDownTime;
public Stats() {
}
public PeerStatus getStatus() {
return status;
}
@JsonIgnore
public boolean isReacheable() {
return status != null && status == PeerStatus.UP;
}
public void setStatus(PeerStatus status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public Integer getBlockNumber() {
return blockNumber;
}
public void setBlockNumber(Integer blockNumber) {
this.blockNumber = blockNumber;
}
public String getBlockHash() {
return blockHash;
}
public void setBlockHash(String blockHash) {
this.blockHash = blockHash;
}
public Long getMedianTime() {
return medianTime;
}
public void setMedianTime(Long medianTime) {
this.medianTime = medianTime;
}
public boolean isMainConsensus() {
return isMainConsensus;
}
public void setMainConsensus(boolean mainConsensus) {
this.isMainConsensus = mainConsensus;
}
public boolean isForkConsensus() {
return isForkConsensus;
}
public void setForkConsensus(boolean forkConsensus) {
this.isForkConsensus = forkConsensus;
}
public Double getConsensusPct() {
return consensusPct;
}
public void setConsensusPct(Double consensusPct) {
this.consensusPct = consensusPct;
}
public Integer getHardshipLevel() {
return hardshipLevel;
}
public void setHardshipLevel(Integer hardshipLevel) {
this.hardshipLevel = hardshipLevel;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public Long getLastUpTime() {
return lastUpTime;
}
public void setLastUpTime(Long lastUpTime) {
this.lastUpTime = lastUpTime;
}
}
}
package org.duniter.core.client.model.local;
/*-
* #%L
* Duniter4j :: Core Client API
* %%
* Copyright (C) 2014 - 2017 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.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import org.duniter.core.client.model.bma.*;
import org.duniter.core.service.CryptoService;
import org.duniter.core.util.CollectionUtils;
import org.duniter.core.util.Preconditions;
import org.duniter.core.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* Created by blavenie on 12/09/17.
*/
public final class Peers {
private static final Logger log = LoggerFactory.getLogger(Peers.class);
private Peers() {
// helper class
}
public static boolean hasEndPointAPI(Peer peer, IEndpointApi api) {
return hasEndPointAPI(peer, api.label());
}
public static boolean hasEndPointAPI(Peer peer, String api) {
return peer.getApi() != null && peer.getApi().equalsIgnoreCase(api);
}
public static String computeHash(Peer peer, CryptoService cryptoService) {
String uniqueKey = Joiner.on('-').skipNulls().join(
peer.getPubkey(),
peer.getDns(),
peer.getIpv4(),
peer.getIpv6(),
peer.getPort(),
peer.isUseSsl(),
peer.getApi(),
peer.getPath());
return cryptoService.hash(uniqueKey);
}
public static String buid(Peer peer) {
return buid(peer.getStats());
}
public static String buid(Peer.Stats stats) {
return stats.getStatus() == Peer.PeerStatus.UP && stats.getBlockNumber() != null
? stats.getBlockNumber() + "-" + stats.getBlockHash()
: null;
}
public static boolean hasBmaEndpoint(Peer peer) {
return hasEndPointAPI(peer, EndpointApi.BASIC_MERKLED_API) ||
hasEndPointAPI(peer, EndpointApi.BMAS);
}
public static boolean hasWs2pEndpoint(Peer peer) {
return hasEndPointAPI(peer, EndpointApi.WS2P);
}
public static boolean hasDuniterEndpoint(Peer peer) {
return hasBmaEndpoint(peer) ||
hasWs2pEndpoint(peer);
}
public static boolean hasEsCoreEndpoint(Peer peer) {
return hasEndPointAPI(peer, EndpointApi.ES_CORE_API);
}
public static boolean isReacheable(Peer peer) {
return peer.getStats() != null && peer.getStats().isReacheable();
}
public static NetworkPeers.Peer toBmaPeer(Peer endpointAsPeer) {
NetworkPeers.Peer result = new NetworkPeers.Peer();
try {
// Fill BMA peer, using the raw document
NetworkPeerings.parse(endpointAsPeer.getPeering().getRaw(), result);
result.setSignature(endpointAsPeer.getPeering().getSignature());
result.setRaw(endpointAsPeer.getPeering().getRaw());
// Override the status, last_try and first_down, using stats
Peer.PeerStatus status = getStatus(endpointAsPeer).orElse(Peer.PeerStatus.DOWN);
result.setStatus(status.name());
if (status == Peer.PeerStatus.UP) {
result.setLastTry(getLastUpTime(endpointAsPeer).get());
} else {
result.setFirstDown(getFirstDownTime(endpointAsPeer).get());
}
return result;
} catch (IOException e) {
log.error("Unable to parse peering raw document found in: " + e.getMessage());
// Continue to next endpoint
}
return null;
}
public static List<NetworkPeers.Peer> toBmaPeers(List<Peer> endpointAsPeers) {
if (CollectionUtils.isEmpty(endpointAsPeers)) return ImmutableList.of();
// Group by peering document
Multimap<String, Peer> groupByPeering = ArrayListMultimap.create();
endpointAsPeers.stream()
.filter(endpointAsPeer ->
endpointAsPeer.getPeering() != null
&& endpointAsPeer.getPubkey() != null
&& endpointAsPeer.getPeering().getSignature() != null
&& endpointAsPeer.getPeering().getRaw() != null
)
.forEach(endpointAsPeer -> {
String peeringKey = String.format("%s:%s:%s",
endpointAsPeer.getPubkey(),
endpointAsPeer.getPeering().getBlockNumber(),
endpointAsPeer.getPeering().getSignature());
groupByPeering.put(peeringKey, endpointAsPeer);
});
// Sort keys, to select only first peering doc, by pubkey (by block number)
Set<String> processedPubkeys = Sets.newHashSet();
return groupByPeering.keySet().stream()
.sorted(Comparator.naturalOrder())
.map(peeringKey -> {
String pubkey = peeringKey.substring(0, peeringKey.indexOf(':'));
// Skip if already processed
if (processedPubkeys.contains(pubkey)) return null;
// Remember the pubkey, to skip it next time
processedPubkeys.add(pubkey);
// Get the first endpoint found for this pubkey
return groupByPeering.get(peeringKey).stream().map(Peers::toBmaPeer)
.filter(Objects::nonNull)
.findFirst().orElse(null);
})
// Remove skipped items
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
public static NetworkWs2pHeads.Head toWs2pHead(Peer peer) {
NetworkWs2pHeads.Head result = new NetworkWs2pHeads.Head();
// TODO : add implementation
return result;
}
public static Optional<Peer.PeerStatus> getStatus(final Peer peer) {
return peer.getStats() != null ?
Optional.ofNullable(peer.getStats().getStatus()) :
Optional.empty();
}
public static Optional<Long> getLastUpTime(final Peer peer) {
return peer.getStats() != null ?
Optional.ofNullable(peer.getStats().getLastUpTime()) :
Optional.empty();
}
public static Optional<Long> getFirstDownTime(final Peer peer) {
return peer.getStats() != null ?
Optional.ofNullable(peer.getStats().getFirstDownTime()) :
Optional.empty();
}
public static String getPeeringBlockStamp(final Peer peer) {
return peer.getPeering() != null &&
peer.getPeering().getBlockNumber() != null &&
peer.getPeering().getBlockHash() != null
? (peer.getPeering().getBlockNumber() + "-" + peer.getPeering().getBlockHash()) : null;
}
public static String getStatsBlockStamp(final Peer peer) {
return peer.getStats() != null &&
peer.getStats().getBlockNumber() != null &&
peer.getStats().getBlockHash() != null
? (peer.getStats().getBlockNumber() + "-" + peer.getStats().getBlockHash()) : null;
}
public static NetworkPeering.Endpoint toBmaEndpoint(Peer ep) {
NetworkPeering.Endpoint bmaEp = new NetworkPeering.Endpoint();
bmaEp.setApi(ep.getApi());
bmaEp.setId(ep.getEpId());
bmaEp.setDns(ep.getDns());
bmaEp.setPort(ep.getPort());
bmaEp.setIpv4(ep.getIpv4());
bmaEp.setIpv6(ep.getIpv6());
bmaEp.setPath(ep.getPath());
return bmaEp;
}
public static NetworkPeers.Peer toBmaPeer(NetworkPeering peeringDocument) {
NetworkPeers.Peer result = new NetworkPeers.Peer();
result.setCurrency(peeringDocument.getCurrency());
result.setPubkey(peeringDocument.getPubkey());
result.setBlock(peeringDocument.getBlock());
result.setSignature(peeringDocument.getSignature());
result.setVersion(peeringDocument.getVersion());
result.setEndpoints(peeringDocument.getEndpoints());
result.setStatus(peeringDocument.getStatus());
result.setRaw(peeringDocument.getRaw());
return result;
}
public static Peer setPeering(Peer peer, NetworkPeering peeringDocument) {
Preconditions.checkNotNull(peer);
Preconditions.checkNotNull(peeringDocument);
Peer.Peering peering = peer.getPeering();
if (peering == null) {
peering = new Peer.Peering();
peer.setPeering(peering);
}
// Copy some fields
peer.setPubkey(peeringDocument.getPubkey());
peer.setCurrency(peeringDocument.getCurrency());
peering.setVersion(peeringDocument.getVersion());
peering.setSignature(peeringDocument.getSignature());
peering.setRaw(peeringDocument.getRaw());
// Copy block infos
if (StringUtils.isNotBlank(peeringDocument.getBlock())) {
String[] blockParts = peeringDocument.getBlock().split("-");
if (blockParts.length == 2) {
peering.setBlockNumber(Integer.parseInt(blockParts[0]));
peering.setBlockHash(blockParts[1]);
}
}
return peer;
}
public static Peer setStats(Peer peer, NetworkPeering peeringDocument) {
Preconditions.checkNotNull(peer);
Preconditions.checkNotNull(peeringDocument);
Peer.Stats stats = peer.getStats() != null ? peer.getStats() : new Peer.Stats();
// Copy block infos
if (StringUtils.isNotBlank(peeringDocument.getBlock())) {
String[] blockParts = peeringDocument.getBlock().split("-");
if (blockParts.length == 2) {
stats.setBlockNumber(Integer.parseInt(blockParts[0]));
stats.setBlockHash(blockParts[1]);
}
}
// Update peer status UP/DOWN
if ("UP".equalsIgnoreCase(peeringDocument.getStatus())) {
stats.setStatus(Peer.PeerStatus.UP);
// FIXME: Duniter 1.7 return lastUpTime in ms. Check if this a bug or not
stats.setLastUpTime((long)Math.round(System.currentTimeMillis() / 1000));
}
else {
stats.setStatus(Peer.PeerStatus.DOWN);
}
return peer;
}
}
......@@ -25,7 +25,11 @@ package org.duniter.core.client.model.local;
import java.io.Serializable;
import java.util.Collection;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.duniter.core.client.model.bma.WotCertification;
import org.duniter.core.model.IEntity;
import org.duniter.core.util.ObjectUtils;
import org.duniter.core.util.crypto.CryptoUtils;
import org.duniter.core.util.crypto.KeyPair;
......@@ -34,34 +38,27 @@ import org.duniter.core.util.crypto.KeyPair;
* A wallet is a user account
* Created by eis on 13/01/15.
*/
public class Wallet extends KeyPair implements LocalEntity<Long>, Serializable {
@Data
public class Wallet extends KeyPair implements IEntity<Long>, Serializable {
private Long id;
private Long accountId;
private String currency;
private String name;
private Long credit;
private Identity identity;
private Identity identity = new Identity();
private Double creditAsUD;
private long blockNumber = -1;
private long txBlockNumber = -1;
private Collection<WotCertification> certifications;
/**
* Use for UI, when some properties has not been displayed yet
*/
private boolean isDirty = false;
public Wallet() {
super(null, null);
this.identity = new Identity();
super();
}
public Wallet(String currency, String uid, byte[] pubKey, byte[] secKey) {
super(pubKey, secKey);
this.currency = currency;
this.identity = new Identity();
this.identity.setPubkey(pubKey == null ? null : CryptoUtils.encodeBase58(pubKey));
this.identity.setUid(uid);
}
......@@ -80,80 +77,22 @@ public class Wallet extends KeyPair implements LocalEntity<Long>, Serializable {
this.identity = identity;
}
public Identity getIdentity() {
return identity;
}
public void setIdentity(Identity identity) {
this.identity = identity;
}
@JsonIgnore
public String getPubKeyHash() {
return identity.getPubkey();
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
@JsonIgnore
public boolean isAuthenticate() {
return secretKey != null && identity != null && identity.getPubkey() != null;
}
@JsonIgnore
public boolean isSelfSend() {
return identity.getTimestamp() != null;
}
public String getCurrencyId() {
return currency;
}
public void setCurrencyId(String currencyId) {
this.currency = currencyId;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getCredit() {
return credit;
}
public void setCredit(Long credit) {
this.credit = credit;
}
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
public String toString() {
return name != null ? name : identity.getPubkey();
}
@JsonIgnore
public String getUid() {
return identity.getUid();
}
......@@ -162,6 +101,7 @@ public class Wallet extends KeyPair implements LocalEntity<Long>, Serializable {
identity.setUid(uid);
}
@JsonIgnore
public String getCertTimestamp() {
return identity.getTimestamp();
}
......@@ -170,52 +110,13 @@ public class Wallet extends KeyPair implements LocalEntity<Long>, Serializable {
identity.setTimestamp(timestamp);
}
public void setMember(Boolean isMember) {
identity.setMember(isMember);
}
@JsonIgnore
public Boolean getIsMember() {
return identity.getIsMember();
}
public boolean isDirty() {
return isDirty;
}
public void setDirty(boolean isDirty) {
this.isDirty = isDirty;
}
public Double getCreditAsUD() {
return creditAsUD;
}
public void setCreditAsUD(Double creditAsUD) {
this.creditAsUD = creditAsUD;
}
public Collection<WotCertification> getCertifications() {
return certifications;
}
public void setCertifications(Collection<WotCertification> certifications) {
this.certifications = certifications;
}
public long getBlockNumber() {
return blockNumber;
}
public void setBlockNumber(long blockNumber) {
this.blockNumber = blockNumber;
}
public long getTxBlockNumber() {
return txBlockNumber;
}
public void setTxBlockNumber(long txBlockNumber) {
this.txBlockNumber = txBlockNumber;
public void setIsMember(Boolean isMember) {
identity.setIsMember(isMember);
}
@Override
......@@ -227,4 +128,9 @@ public class Wallet extends KeyPair implements LocalEntity<Long>, Serializable {
}
return super.equals(o);
}
public String toString() {
return name != null ? name : identity.getPubkey();
}
}
package org.duniter.core.client.dao;
package org.duniter.core.client.repositories;
/*
* #%L
......@@ -23,19 +23,13 @@ package org.duniter.core.client.dao;
*/
import org.duniter.core.beans.Bean;
import org.duniter.core.client.model.local.LocalEntity;
import org.duniter.core.client.model.Account;
import org.duniter.core.repositories.CrudRepository;
/**
* Created by blavenie on 29/12/15.
* Created by eis on 07/02/15.
*/
public interface EntityDao<I, B extends LocalEntity<I>> extends Bean{
public interface AccountRepository<E extends Account> extends Bean, CrudRepository<Long, E> {
B create(B entity);
B update(B entity);
B getById(I id);
void remove(B entity);
}
package org.duniter.core.client.dao;
package org.duniter.core.client.repositories;
/*
* #%L
......@@ -22,20 +22,19 @@ package org.duniter.core.client.dao;
* #L%
*/
import org.duniter.core.client.model.local.Peer;
import org.duniter.core.beans.Bean;
import org.duniter.core.client.model.local.ICurrency;
import org.duniter.core.repositories.CrudRepository;
import org.duniter.core.util.Beans;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by blavenie on 29/12/15.
* Created by eis on 07/02/15.
*/
public interface PeerDao extends EntityDao<String, Peer> {
public interface CurrencyRepository<E extends ICurrency> extends Bean, CrudRepository<String, E> {
List<Peer> getPeersByCurrencyId(String currencyId);
boolean isExists(String currencyId, String peerId);
Long getMaxLastUpTime(String currencyId);
void updatePeersAsDown(String currencyId, long lastUpTimeTimeout);
default Iterable<String> findAllIds() {
return Beans.getStream(findAll()).map(E::getId).collect(Collectors.toList());
}
}
package org.duniter.elasticsearch.exception;
package org.duniter.core.client.repositories;
/*
* #%L
* Duniter4j :: ElasticSearch Plugin
* UCoin Java :: Core Client API
* %%
* Copyright (C) 2014 - 2016 EIS
* %%
......@@ -22,26 +22,25 @@ package org.duniter.elasticsearch.exception;
* #L%
*/
import org.elasticsearch.rest.RestStatus;
import org.duniter.core.beans.Bean;
import org.duniter.core.client.model.local.Dividend;
import org.duniter.core.client.model.local.ICurrency;
import org.duniter.core.repositories.CrudRepository;
import java.math.BigInteger;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
/**
* Created by blavenie on 01/03/16.
* Created by eis on 07/02/15.
*/
public class DocumentNotFoundException extends DuniterElasticsearchException {
public DocumentNotFoundException(Throwable cause) {
super(cause);
}
public DocumentNotFoundException(String msg, Object... args) {
super(msg, args);
}
public interface DividendRepository extends Bean, CrudRepository<String, Dividend> {
public DocumentNotFoundException(String msg, Throwable cause, Object... args) {
super(msg, args, cause);
}
/**
* Return a map of UD (key=blockNumber, value=amount)
* @return
*/
Iterable<Dividend> findAllByCurrency(String currency);
@Override
public RestStatus status() {
return RestStatus.BAD_REQUEST;
}
}
package org.duniter.core.client.repositories;
/*
* #%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 org.duniter.core.client.model.bma.NetworkWs2pHeads;
import org.duniter.core.client.model.local.Peer;
import org.duniter.core.repositories.CrudRepository;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* Created by blavenie on 29/12/15.
*/
public interface PeerRepository extends CrudRepository<String, Peer> {
List<Peer> getPeersByCurrencyId(String currencyId);
List<Peer> getPeersByCurrencyIdAndApi(String currencyId, String endpointApi);
/**
*
* @param currencyId
* @param endpointApi
* @param pubkeys filter on given pubkeys. If null, not filtering
* @return
*/
List<Peer> getPeersByCurrencyIdAndApiAndPubkeys(String currencyId, String endpointApi, String... pubkeys);
/**
* Get all UP peers
* @param currencyId
* @param pubkeys Allow to use to filter on specific pubkeys. If null, not filtering
* @return
*/
List<Peer> getUpPeersByCurrencyId(String currencyId, String... pubkeys);
/**
* Get WS2p heads as BMA /network/ws2p/head format
* @param currencyId
* @param pubkeys Allow to filter on given pubkeys. If null, not filtering
* @return
*/
List<NetworkWs2pHeads.Head> getWs2pPeersByCurrencyId(String currencyId, String... pubkeys);
boolean existsByCurrencyAndId(String currency, String peerId);
Long getMaxLastUpTime(String currencyId);
void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> endpointApis);
boolean hasPeersUpWithApi(String currencyId, Set<String> endpointApis);
}
package org.duniter.core.client.repositories.mem;
/*
* #%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.common.base.Preconditions;
import org.duniter.core.beans.Bean;
import org.duniter.core.model.IEntity;
import org.duniter.core.repositories.CrudRepository;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Created by blavenie on 29/12/15.
*/
public interface MemoryCrudRepository<ID extends Serializable, T extends IEntity<ID>> extends CrudRepository<ID, T> {
default void delete(T entity) {
Preconditions.checkNotNull(entity);
deleteById(entity.getId());
}
default <S extends T> Iterable<S> saveAll(Iterable<S> entities) {
if (entities == null) return null;
List<S> result = new ArrayList<>();
entities.forEach(entity -> {
S savedEntity = this.save(entity);
result.add(savedEntity);
});
return result;
}
default Iterable<T> findAllById(Iterable<ID> ids) {
if (ids == null) return null;
List<T> result = new ArrayList<>();
ids.forEach(entity -> this.findById(entity).map(result::add));
return result;
}
default void deleteAll(Iterable<? extends T> entities) {
if (entities != null) {
entities.forEach(this::delete);
}
}
default void deleteAll() {
deleteAll(findAll());
}
}
package org.duniter.core.client.dao.mem;
package org.duniter.core.client.repositories.mem;
/*
* #%L
......@@ -22,82 +22,68 @@ package org.duniter.core.client.dao.mem;
* #L%
*/
import org.duniter.core.client.dao.CurrencyDao;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.duniter.core.client.model.local.Currency;
import org.duniter.core.client.model.local.Dividend;
import org.duniter.core.client.repositories.CurrencyRepository;
import org.duniter.core.client.model.local.ICurrency;
import org.duniter.core.util.Preconditions;
import java.util.*;
/**
* Created by blavenie on 29/12/15.
*/
public class MemoryCurrencyDaoImpl implements CurrencyDao {
public class MemoryCurrencyRepositoryImpl implements CurrencyRepository<Currency>, MemoryCrudRepository<String, Currency> {
private Map<String, Currency> currencies = new HashMap<>();
private Map<String, org.duniter.core.client.model.local.Currency> currencies = new HashMap<>();
private Map<String, Map<Integer, Long>> currencyUDsByBlock = new HashMap<>();
public MemoryCurrencyDaoImpl() {
public MemoryCurrencyRepositoryImpl() {
super();
}
@Override
public org.duniter.core.client.model.local.Currency create(final org.duniter.core.client.model.local.Currency entity) {
currencies.put(entity.getId(), entity);
public <S extends Currency> S save(S entity) {
Preconditions.checkNotNull(entity);
Preconditions.checkNotNull(entity.getId());
if (!existsById(entity.getId())) {
currencies.put(entity.getId(), entity);
}
else {
currencies.put(entity.getId(), entity);
}
return entity;
}
@Override
public org.duniter.core.client.model.local.Currency update(final org.duniter.core.client.model.local.Currency currency) {
currencies.put(currency.getId(), currency);
return currency;
}
@Override
public void remove(final org.duniter.core.client.model.local.Currency currency) {
currencies.remove(currency.getId());
public void deleteById(String id) {
currencies.remove(id);
}
@Override
public List<org.duniter.core.client.model.local.Currency> getCurrencies(long accountId) {
List<org.duniter.core.client.model.local.Currency> result = new ArrayList<>();
result.addAll(currencies.values());
return result;
public long count() {
return currencies.size();
}
@Override
public org.duniter.core.client.model.local.Currency getById(String id) {
return currencies.get(id);
public Iterable<String> findAllIds() {
return ImmutableSet.copyOf(currencies.keySet());
}
@Override
public long getLastUD(String id) {
org.duniter.core.client.model.local.Currency currency = getById(id);
if (currency == null) {
return -1;
}
return currency.getLastUD();
public Iterable<Currency> findAll() {
return ImmutableList.copyOf(currencies.values());
}
@Override
public Map<Integer, Long> getAllUD(String id) {
return currencyUDsByBlock.get(id);
}
@Override
public void insertUDs(String id, Map<Integer, Long> newUDs) {
Map<Integer, Long> udsByBlock = currencyUDsByBlock.get(id);
if (udsByBlock == null) {
udsByBlock = new HashMap<>();
currencyUDsByBlock.put(id, udsByBlock);
}
udsByBlock.putAll(newUDs);
public Optional<Currency> findById(String id) {
return Optional.ofNullable(currencies.get(id));
}
@Override
public boolean isExists(String currencyId) {
return currencies.get(currencyId) != null;
public boolean existsById(String id) {
return currencies.containsKey(id);
}
}
package org.duniter.core.client.dao.mem;
package org.duniter.core.client.repositories.mem;
/*
* #%L
......@@ -22,82 +22,70 @@ package org.duniter.core.client.dao.mem;
* #L%
*/
import org.duniter.core.client.dao.PeerDao;
import org.duniter.core.client.model.local.Peer;
import com.google.common.collect.ImmutableList;
import org.duniter.core.client.model.local.Dividend;
import org.duniter.core.client.repositories.DividendRepository;
import java.util.*;
import java.math.BigInteger;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Created by blavenie on 29/12/15.
*/
public class MemoryPeerDaoImpl implements PeerDao {
public class MemoryDividendRepositoryImpl implements DividendRepository, MemoryCrudRepository<String, Dividend> {
private Map<String, Peer> peersByCurrencyId = new HashMap<>();
private Map<String, Dividend> dividends = new HashMap<>();
public MemoryPeerDaoImpl() {
public MemoryDividendRepositoryImpl() {
super();
}
@Override
public Peer create(Peer entity) {
entity.setId(entity.computeKey());
peersByCurrencyId.put(entity.getId(), entity);
return entity;
}
public <S extends Dividend> S save(S entity) {
String id = entity.getId();
if (id == null) {
id = Dividend.computeId(entity);
entity.setId(id);
}
dividends.put(id, entity);
@Override
public Peer update(Peer entity) {
peersByCurrencyId.put(entity.getId(), entity);
return entity;
}
@Override
public Peer getById(String id) {
return peersByCurrencyId.get(id);
public void deleteById(String id) {
dividends.remove(id);
}
@Override
public void remove(Peer entity) {
peersByCurrencyId.remove(entity.getId());
public long count() {
return dividends.size();
}
@Override
public List<Peer> getPeersByCurrencyId(final String currencyId) {
return peersByCurrencyId.values().stream()
.filter(peer -> currencyId.equals(peer.getCurrency()))
.collect(Collectors.toList());
public Iterable<Dividend> findAll() {
return ImmutableList.copyOf(dividends.values());
}
@Override
public boolean isExists(final String currencyId, final String peerId) {
return peersByCurrencyId.values().stream()
.anyMatch(peer -> currencyId.equals(peer.getCurrency()) && peerId.equals(peer.getId()));
public Optional<Dividend> findById(String id) {
return Optional.ofNullable(dividends.get(id));
}
@Override
public Long getMaxLastUpTime(String currencyId) {
OptionalLong max = getPeersByCurrencyId(currencyId).stream()
.mapToLong(peer -> peer.getStats() != null ? peer.getStats().getLastUpTime() : -1)
.max();
if (!max.isPresent()) {
return null;
}
return max.getAsLong();
public Iterable<Dividend> findAllByCurrency(String currency) {
return dividends.values().stream()
.filter(entity -> currency.equals(entity.getCurrency()))
.sorted(Comparator.comparing(Dividend::getNumber))
.collect(Collectors.toList());
}
@Override
public void updatePeersAsDown(String currencyId, long lastUpTimeTimeout) {
long maxLastUpTime = (System.currentTimeMillis() - lastUpTimeTimeout)/1000;
getPeersByCurrencyId(currencyId).stream()
.filter(peer -> peer.getStats() != null && peer.getStats().getLastUpTime() <= maxLastUpTime)
.forEach(peer -> {
peer.getStats().setStatus(Peer.PeerStatus.DOWN);
});
public boolean existsById(String id) {
return dividends.get(id) != null;
}
}
package org.duniter.core.client.repositories.mem;
/*
* #%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.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import org.duniter.core.beans.InitializingBean;
import org.duniter.core.client.model.local.Currency;
import org.duniter.core.client.repositories.PeerRepository;
import org.duniter.core.client.model.bma.NetworkWs2pHeads;
import org.duniter.core.client.model.local.Peer;
import org.duniter.core.client.model.local.Peers;
import org.duniter.core.client.service.ServiceLocator;
import org.duniter.core.service.CryptoService;
import java.util.*;
import java.util.stream.Collectors;
/**
* Created by blavenie on 29/12/15.
*/
public class MemoryPeerRepositoryImpl implements PeerRepository, InitializingBean, MemoryCrudRepository<String, Peer> {
private Map<String, Peer> peersById = new HashMap<>();
private CryptoService cryptoService;
public MemoryPeerRepositoryImpl() {
super();
}
@Override
public void afterPropertiesSet() throws Exception {
cryptoService = ServiceLocator.instance().getCryptoService();
}
@Override
public <S extends Peer> S save(S entity) {
String id = entity.getId();
if (id == null) {
id = Peers.computeHash(entity, cryptoService);
entity.setId(id);
}
peersById.put(entity.getId(), entity);
return entity;
}
@Override
public Optional<Peer> findById(String id) {
return Optional.ofNullable(peersById.get(id));
}
@Override
public Iterable<Peer> findAll() {
return ImmutableList.copyOf(peersById.values());
}
@Override
public long count() {
return peersById.size();
}
@Override
public void delete(Peer entity) {
Preconditions.checkNotNull(entity);
deleteById(entity.getId());
}
@Override
public void deleteById(String id) {
peersById.remove(id);
}
@Override
public List<Peer> getPeersByCurrencyId(final String currency) {
Preconditions.checkNotNull(currency);
return peersById.values().stream()
.filter(peer -> currency.equals(peer.getCurrency()))
.collect(Collectors.toList());
}
@Override
public List<Peer> getPeersByCurrencyIdAndApi(final String currency, final String endpointApi) {
Preconditions.checkNotNull(currency);
Preconditions.checkNotNull(endpointApi);
return peersById.values().stream()
.filter(peer ->
// Filter on currency
currency.equals(peer.getCurrency()) &&
// Filter on API
peer.getApi() != null &&
endpointApi.equals(peer.getApi()))
.collect(Collectors.toList());
}
@Override
public List<Peer> getPeersByCurrencyIdAndApiAndPubkeys(String currencyId, String endpointApi, String... pubkeys) {
Preconditions.checkNotNull(currencyId);
Preconditions.checkNotNull(endpointApi);
List pubkeysAsList = pubkeys != null ? Arrays.asList(pubkeys) : null;
return peersById.values().stream()
.filter(peer ->
// Filter on currency
currencyId.equals(peer.getCurrency()) &&
// Filter on API
(endpointApi == null || (
peer.getApi() != null &&
endpointApi.equals(peer.getApi()))
) &&
// Filter on pubkeys
(pubkeysAsList == null || (
peer.getPubkey() != null &&
pubkeysAsList.contains(peer.getPubkey()))
))
.collect(Collectors.toList());
}
@Override
public List<Peer> getUpPeersByCurrencyId(String currencyId, String... pubkeys) {
Preconditions.checkNotNull(currencyId);
return getPeersByCurrencyIdAndApiAndPubkeys(currencyId, null, pubkeys)
.stream()
.filter(Peers::isReacheable)
.collect(Collectors.toList());
}
@Override
public List<NetworkWs2pHeads.Head> getWs2pPeersByCurrencyId(String currencyId, String... pubkeys) {
Preconditions.checkNotNull(currencyId);
return getPeersByCurrencyIdAndApiAndPubkeys(currencyId, null, pubkeys)
.stream()
.map(Peers::toWs2pHead)
// Skip if no message
.filter(head -> head.getMessage() != null)
.collect(Collectors.toList());
}
@Override
public boolean existsById(final String id) {
Preconditions.checkNotNull(id);
return peersById.containsKey(id);
}
@Override
public boolean existsByCurrencyAndId(final String currency, final String id) {
Preconditions.checkNotNull(currency);
return peersById.values().stream()
.anyMatch(peer -> currency.equals(peer.getCurrency()) && id.equals(peer.getId()));
}
@Override
public Long getMaxLastUpTime(String currencyId) {
Preconditions.checkNotNull(currencyId);
OptionalLong max = getPeersByCurrencyId(currencyId).stream()
.mapToLong(peer -> peer.getStats() != null ? peer.getStats().getLastUpTime() : -1)
.max();
if (!max.isPresent()) {
return null;
}
return max.getAsLong();
}
@Override
public void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> endpointApis) {
long minUpTimeInSec = minUpTimeInMs / 1000L;
long firstDownTime = System.currentTimeMillis() / 1000L;
getPeersByCurrencyId(currencyId).stream()
.filter(peer ->
peer.getStats() != null
&& peer.getStats().isReacheable()
&& (
peer.getStats().getLastUpTime() == null
|| peer.getStats().getLastUpTime() < minUpTimeInSec
)
&& (endpointApis == null || endpointApis.contains(peer.getApi()))
)
.forEach(peer -> {
peer.getStats().setStatus(Peer.PeerStatus.DOWN);
peer.getStats().setFirstDownTime(firstDownTime);
});
}
@Override
public boolean hasPeersUpWithApi(String currencyId, Set<String> api) {
return getPeersByCurrencyId(currencyId)
.stream()
.anyMatch(p ->
api.contains(p.getApi()) &&
p.getStats() != null &&
Peer.PeerStatus.UP.equals(p.getStats().getStatus())
);
}
/* -- protected methods -- */
}