From 6f1e4c43d7cb5765bf38982cb0327ab660ce3aeb Mon Sep 17 00:00:00 2001 From: Benoit Lavenier <benoit.lavenier@e-is.pro> Date: Fri, 10 Jan 2020 13:53:18 +0100 Subject: [PATCH] [enh] Allow to get /wot/pending and /wot/requirements --- .../model/bma/WotPendingMembership.java | 58 +++++++++ .../model/bma/WotPendingMemberships.java | 38 ++++++ .../client/model/bma/WotRequirements.java | 122 ++++++++++++++++++ .../model/bma/WotRequirementsResponse.java | 36 ++++++ .../bma/BlockchainRemoteServiceImpl.java | 1 + .../client/service/bma/WotRemoteService.java | 8 +- .../service/bma/WotRemoteServiceImpl.java | 38 +++++- .../service/bma/WotRemoteServiceTest.java | 34 ++++- 8 files changed, 321 insertions(+), 14 deletions(-) create mode 100644 duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMembership.java create mode 100644 duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMemberships.java create mode 100644 duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirements.java create mode 100644 duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirementsResponse.java diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMembership.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMembership.java new file mode 100644 index 00000000..74555d1f --- /dev/null +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMembership.java @@ -0,0 +1,58 @@ +package org.duniter.core.client.model.bma; + +import java.io.Serializable; + +public class WotPendingMembership implements Serializable { + private static final long serialVersionUID = 1L; + + private String pubkey; + private String uid; + private String version; + private String currency; + private String membership; + private long blockNumber; + private String blockHash; + + public String getPubkey() { + return pubkey; + } + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + public String getUid() { + return uid; + } + public void setUid(String uid) { + this.uid = uid; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getCurrency() { + return currency; + } + public void setCurrency(String currency) { + this.currency = currency; + } + public String getMembership() { + return membership; + } + public void setMembership(String membership) { + this.membership = membership; + } + public long getBlockNumber() { + return blockNumber; + } + public void setBlockNumber(long blockNumber) { + this.blockNumber = blockNumber; + } + public String getBlockHash() { + return blockHash; + } + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + } \ No newline at end of file diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMemberships.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMemberships.java new file mode 100644 index 00000000..8d7e5e8e --- /dev/null +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotPendingMemberships.java @@ -0,0 +1,38 @@ +package org.duniter.core.client.model.bma; + +/* + * #%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.BasicIdentity; + +import java.io.Serializable; + +public class WotPendingMemberships extends BasicIdentity { + private static final long serialVersionUID = -5631089862725952431L; + + private WotPendingMembership[] memberships; + + public WotPendingMembership[] getMemberships() { + return memberships; + } + +} diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirements.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirements.java new file mode 100644 index 00000000..b050da1d --- /dev/null +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirements.java @@ -0,0 +1,122 @@ +package org.duniter.core.client.model.bma; + +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonSetter; + +import java.io.Serializable; + +public class WotRequirements implements Serializable { + private static final long serialVersionUID = 1L; + + private String pubkey; + private String uid; + private String sig; + private Meta meta; + private String revocation_sig; + private Boolean revoked; + private Long revoked_on; + private Boolean expired; + private Boolean outdistanced; + private Boolean isSentry; + private Boolean wasMember; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getSig() { + return sig; + } + + public void setSig(String sig) { + this.sig = sig; + } + + public Meta getMeta() { + return meta; + } + + public void setMeta(Meta meta) { + this.meta = meta; + } + + public String getRevocation_sig() { + return revocation_sig; + } + + public void setRevocation_sig(String revocation_sig) { + this.revocation_sig = revocation_sig; + } + + public Boolean getRevoked() { + return revoked; + } + + public void setRevoked(Boolean revoked) { + this.revoked = revoked; + } + + public Long getRevoked_on() { + return revoked_on; + } + + public void setRevoked_on(Long revoked_on) { + this.revoked_on = revoked_on; + } + + public Boolean getExpired() { + return expired; + } + + public void setExpired(Boolean expired) { + this.expired = expired; + } + + public Boolean getOutdistanced() { + return outdistanced; + } + + public void setOutdistanced(Boolean outdistanced) { + this.outdistanced = outdistanced; + } + + public Boolean getSentry() { + return isSentry; + } + + public void setSentry(Boolean sentry) { + isSentry = sentry; + } + + public Boolean getWasMember() { + return wasMember; + } + + public void setWasMember(Boolean wasMember) { + this.wasMember = wasMember; + } + + public static class Meta implements Serializable { + private String timestamp; + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + } +} \ No newline at end of file diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirementsResponse.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirementsResponse.java new file mode 100644 index 00000000..e6972804 --- /dev/null +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/WotRequirementsResponse.java @@ -0,0 +1,36 @@ +package org.duniter.core.client.model.bma; + +/* + * #%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.BasicIdentity; + +public class WotRequirementsResponse extends BasicIdentity { + private static final long serialVersionUID = -5631089862725952141L; + + private WotRequirements[] identities; + + public WotRequirements[] getIdentities() { + return identities; + } + +} diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java index 017650c1..97bc1d8a 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/BlockchainRemoteServiceImpl.java @@ -482,6 +482,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement .append('\n').toString(); } + /** * Get UD, by block number * diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java index 4cc37b8c..4f26739c 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteService.java @@ -23,8 +23,7 @@ package org.duniter.core.client.service.bma; */ import org.duniter.core.beans.Service; -import org.duniter.core.client.model.bma.WotCertification; -import org.duniter.core.client.model.bma.WotLookup; +import org.duniter.core.client.model.bma.*; import org.duniter.core.client.model.local.*; import java.util.Collection; @@ -39,7 +38,8 @@ public interface WotRemoteService extends Service { WotLookup.Uid find(Peer peer, String uidOrPubKey); WotLookup.Uid find(String currencyId, String uidOrPubKey); - void getRequirements(String currencyId, String pubKey); + List<WotRequirements> getRequirements(Peer peer, String pubKey); + List<WotRequirements> getRequirements(String currencyId, String pubKey); WotLookup.Uid findByUid(Peer peer, String uid); WotLookup.Uid findByUid(String currencyId, String uid); @@ -70,6 +70,8 @@ public interface WotRemoteService extends Service { Map<String, String> getMembersUids(Peer peer); List<Member> getMembers(Peer peer); List<Member> getMembers(String currencyId); + List<WotPendingMembership> getPendingMemberships(Peer peer); + List<WotPendingMembership> getPendingMemberships(String currencyId); void sendIdentity(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid); void sendIdentity(String currencyId, byte[] pubKey, byte[] secKey, String uid, String blockUid); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java index a230da41..9fc355c4 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/bma/WotRemoteServiceImpl.java @@ -23,6 +23,7 @@ package org.duniter.core.client.service.bma; */ import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.commons.collections4.MapUtils; @@ -31,6 +32,7 @@ import org.duniter.core.client.model.ModelUtils; import org.duniter.core.client.model.bma.*; import org.duniter.core.client.model.local.*; import org.duniter.core.client.service.ServiceLocator; +import org.duniter.core.client.service.exception.HttpBadRequestException; import org.duniter.core.client.service.local.CurrencyService; import org.duniter.core.exception.TechnicalException; import org.duniter.core.service.CryptoService; @@ -60,6 +62,8 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe public static final String URL_MEMBERS = URL_BASE + "/members"; + public static final String URL_PENDING = URL_BASE + "/pending"; + public static final String URL_LOOKUP = URL_BASE + "/lookup/%s"; public static final String URL_REQUIREMENT = URL_BASE+"/requirements/%s"; @@ -169,15 +173,35 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe return result; } - public void getRequirements(String currencyId, String pubKey) { - if (log.isDebugEnabled()) { - log.debug(String.format("TODO: implement /wot/requirements on [%s]", pubKey)); + public List<WotPendingMembership> getPendingMemberships(Peer peer) { + try { + WotPendingMemberships lists = httpService.executeRequest(peer, URL_PENDING, WotPendingMemberships.class); + return ImmutableList.copyOf(lists.getMemberships()); + } catch (HttpBadRequestException e) { + log.debug("Unable to get pending memberships"); + return null; } - // get parameter - String path = String.format(URL_REQUIREMENT, pubKey); - // TODO : managed requirements - //WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + } + + @Override + public List<WotPendingMembership> getPendingMemberships(String currencyId) { + return getPendingMemberships(peerService.getActivePeerByCurrencyId(currencyId)); + } + + @Override + public List<WotRequirements> getRequirements(Peer peer, String pubKey) { + try { + WotRequirementsResponse response = httpService.executeRequest(peer, String.format(URL_REQUIREMENT, pubKey), WotRequirementsResponse.class); + return ImmutableList.copyOf(response.getIdentities()); + } catch (HttpBadRequestException e) { + log.debug(String.format("Unable to get memberships for {%.8s}", pubKey)); + return null; + } + } + @Override + public List<WotRequirements> getRequirements(String currencyId, String pubKey) { + return getRequirements(peerService.getActivePeerByCurrencyId(currencyId), pubKey); } public WotLookup.Uid findByUid(Peer peer, String uid) { diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java index a58bb52f..54d37f7c 100644 --- a/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java +++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/service/bma/WotRemoteServiceTest.java @@ -23,9 +23,10 @@ package org.duniter.core.client.service.bma; */ +import org.apache.commons.lang3.mutable.MutableInt; import org.duniter.core.client.TestResource; import org.duniter.core.client.config.Configuration; -import org.duniter.core.client.model.bma.ErrorCode; +import org.duniter.core.client.model.bma.*; import org.duniter.core.client.model.local.Identity; import org.duniter.core.client.model.local.Member; import org.duniter.core.client.model.local.Peer; @@ -34,9 +35,6 @@ import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.client.service.exception.HttpBadRequestException; import org.duniter.core.util.CollectionUtils; import org.duniter.core.util.crypto.CryptoUtils; -import org.duniter.core.client.model.bma.BlockchainBlock; -import org.duniter.core.client.model.bma.WotCertification; -import org.duniter.core.client.model.bma.WotLookup; import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -184,6 +182,34 @@ public class WotRemoteServiceTest { Assert.assertTrue(result.size() > 0); } + @Test + public void getPendingMemberships() { + Peer peer = createTestPeer(); + List<WotPendingMembership> result = service.getPendingMemberships(peer); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + } + + @Test + public void getRequirements() { + Peer peer = createTestPeer(); + List<WotPendingMembership> pendingMemberships = service.getPendingMemberships(peer); + Assume.assumeTrue(CollectionUtils.isNotEmpty(pendingMemberships)); + + MutableInt counter = new MutableInt(0); + pendingMemberships.stream() + // Get first 10 + .filter(ms -> { + counter.increment(); + return counter.getValue() < 10; + }) + .forEach(ms -> { + List<WotRequirements> result = service.getRequirements(peer, ms.getPubkey()); + Assert.assertNotNull(result); + Assert.assertNotNull(result.size() > 0); + }); + } + /* -- internal methods */ protected Wallet createTestWallet() { -- GitLab