Commit 38a7eca5 authored by Benoit Lavenier's avatar Benoit Lavenier

[fix] Peer (bean): add path

[enh] Peers: add methods to convert into BMA peer
parent 85d28bfc
Pipeline #4426 passed with stage
in 28 seconds
......@@ -23,9 +23,9 @@ package org.duniter.core.client.dao;
*/
import org.duniter.core.client.model.bma.EndpointApi;
import org.duniter.core.client.model.bma.NetworkPeers;
import org.duniter.core.client.model.local.Peer;
import java.util.Collection;
import java.util.List;
import java.util.Set;
......@@ -38,8 +38,23 @@ public interface PeerDao extends EntityDao<String, Peer> {
List<Peer> getPeersByCurrencyIdAndApi(String currencyId, String endpointApi);
/**
*
* @param currencyId
* @param endpointApi
* @param pubkeys
* @return
*/
List<Peer> getPeersByCurrencyIdAndApiAndPubkeys(String currencyId, String endpointApi, String[] pubkeys);
/**
* Get peers as BMA /network/peers format
* @param currencyId
* @param pubkeys use to filter on specific pubkeys. If null, not filtering
* @return
*/
List<NetworkPeers.Peer> getBmaPeersByCurrencyId(String currencyId, String[] pubkeys);
boolean isExists(String currencyId, String peerId);
Long getMaxLastUpTime(String currencyId);
......
......@@ -23,10 +23,11 @@ package org.duniter.core.client.dao.mem;
*/
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.duniter.core.client.dao.PeerDao;
import org.duniter.core.client.model.bma.EndpointApi;
import org.duniter.core.client.model.bma.NetworkPeers;
import org.duniter.core.client.model.local.Peer;
import org.duniter.core.client.model.local.Peers;
import org.duniter.core.util.Preconditions;
import java.util.*;
......@@ -94,21 +95,33 @@ public class MemoryPeerDaoImpl implements PeerDao {
public List<Peer> getPeersByCurrencyIdAndApiAndPubkeys(String currencyId, String endpointApi, String[] pubkeys) {
Preconditions.checkNotNull(currencyId);
Preconditions.checkNotNull(endpointApi);
List pubkeysAsList = ImmutableList.copyOf(pubkeys);
List pubkeysAsList = pubkeys != null ? ImmutableList.copyOf(pubkeys) : null;
return peersByCurrencyId.values().stream()
.filter(peer ->
// Filter on currency
currencyId.equals(peer.getCurrency()) &&
// Filter on API
peer.getApi() != null &&
endpointApi.equals(peer.getApi()) &&
(endpointApi == null || (
peer.getApi() != null &&
endpointApi.equals(peer.getApi()))
) &&
// Filter on pubkeys
peer.getPubkey() != null &&
pubkeysAsList.contains(peer.getPubkey()))
(pubkeysAsList == null || (
peer.getPubkey() != null &&
pubkeysAsList.contains(peer.getPubkey()))
))
.collect(Collectors.toList());
}
@Override
public List<NetworkPeers.Peer> getBmaPeersByCurrencyId(String currencyId, String[] pubkeys) {
Preconditions.checkNotNull(currencyId);
return Peers.toBmaPeers(getPeersByCurrencyIdAndApiAndPubkeys(currencyId, null, pubkeys));
}
@Override
public boolean isExists(final String currencyId, final String peerId) {
Preconditions.checkNotNull(currencyId);
......@@ -148,4 +161,7 @@ public class MemoryPeerDaoImpl implements PeerDao {
Peer.PeerStatus.UP.equals(p.getStats().getStatus())
);
}
/* -- protected methods -- */
}
......@@ -24,6 +24,7 @@ package org.duniter.core.client.model.bma;
public enum EndpointApi {
BASIC_MERKLED_API,
BMAS,
BMATOR,
......@@ -34,5 +35,13 @@ public enum EndpointApi {
MONIT_API,
UNDEFINED,
// TODO: remove this ?
GCHANGE_API
GCHANGE_API;
public boolean useHttpProtocol(String api) {
return !useWebSocketProtocol(api);
}
public static boolean useWebSocketProtocol(String api) {
return WS2P.name().equals(api);
}
}
......@@ -52,6 +52,7 @@ public class Peer implements LocalEntity<String>, Serializable {
private String pubkey;
private String hash;
private String currency;
private String path;
public Builder() {
......@@ -147,6 +148,10 @@ public class Peer implements LocalEntity<String>, Serializable {
return this;
}
public void setPath(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.name();
......@@ -165,6 +170,9 @@ 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);
}
return ep;
}
......@@ -183,10 +191,11 @@ public class Peer implements LocalEntity<String>, Serializable {
private String id;
private String api;
private String epId;
private String dns;
private String ipv4;
private String ipv6;
private String epId;
private String path;
private String url;
private String host;
......@@ -249,8 +258,8 @@ public class Peer implements LocalEntity<String>, Serializable {
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
......@@ -275,7 +284,7 @@ public class Peer implements LocalEntity<String>, Serializable {
@JsonIgnore
public String computeKey() {
return Joiner.on('-').skipNulls().join(pubkey, dns, ipv4, ipv6, port, useSsl, api);
return Joiner.on('-').skipNulls().join(pubkey, dns, ipv4, ipv6, port, useSsl, api, path);
}
public String getApi() {
......@@ -313,6 +322,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;
}
......@@ -391,6 +408,9 @@ 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();
}
......
......@@ -22,7 +22,19 @@ package org.duniter.core.client.model.local;
* #L%
*/
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.duniter.core.client.model.bma.EndpointApi;
import org.duniter.core.client.model.bma.NetworkPeering;
import org.duniter.core.client.model.bma.NetworkPeers;
import org.duniter.core.client.model.bma.Protocol;
import org.duniter.core.util.CollectionUtils;
import org.duniter.core.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Created by blavenie on 12/09/17.
......@@ -69,4 +81,93 @@ public final class Peers {
return peer.getStats() != null && peer.getStats().isReacheable();
}
public static List<NetworkPeers.Peer> toBmaPeers(List<Peer> peers) {
if (CollectionUtils.isEmpty(peers)) return null;
// Group endpoint by pubkey
Map<String, List<Peer>> epByPubkeys = Maps.newHashMap();
peers.stream().forEach(peer -> {
String pubkey = peer.getPubkey();
if (StringUtils.isNotBlank(pubkey)) {
List<Peer> endpoints = epByPubkeys.get(pubkey);
if (endpoints == null) {
endpoints = Lists.newArrayList();
epByPubkeys.put(pubkey, endpoints);
}
endpoints.add(peer);
}
});
return epByPubkeys.values().stream().map(endpoints -> {
Peer firstEp = endpoints.get(0);
NetworkPeers.Peer result = new NetworkPeers.Peer();
result.setCurrency(firstEp.getCurrency());
result.setPubkey(firstEp.getPubkey());
result.setBlock(getBlockStamp(firstEp));
// Compute status (=UP is at least one endpoint is UP)
String status = endpoints.stream()
.map(Peers::getStatus)
.filter(s -> s == Peer.PeerStatus.UP)
.findAny()
.orElse(Peer.PeerStatus.DOWN).name();
result.setStatus(status);
// Default values (not stored yet)
result.setVersion(Protocol.VERSION); // TODO: get it from the storage (DB, ES, etc.) ?
result.setStatusTS(0L); // TODO make sure this is used by clients ?
// Compute endpoints list
List<NetworkPeering.Endpoint> bmaEps = endpoints.stream()
.map(Peers::toBmaEndpoint)
.collect(Collectors.toList());
result.setEndpoints(bmaEps.toArray(new NetworkPeering.Endpoint[bmaEps.size()]));
// Compute last try
Long lastUpTime = endpoints.stream()
.map(Peers::getLastUpTime)
.filter(Objects::nonNull)
.max(Long::compare)
.orElse(null);
// Compute last try
result.setLastTry(lastUpTime);
return result;
}).collect(Collectors.toList());
}
public static Peer.PeerStatus getStatus(final Peer peer) {
return peer.getStats() != null &&
peer.getStats().getStatus() != null ?
peer.getStats().getStatus() : null;
}
public static Long getLastUpTime(final Peer peer) {
return peer.getStats() != null &&
peer.getStats().getLastUpTime() != null ?
peer.getStats().getLastUpTime() : null;
}
public static String getBlockStamp(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(EndpointApi.valueOf(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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment