From 717fa4b6870fedbe267702325b136460feef70a3 Mon Sep 17 00:00:00 2001
From: Benoit Lavenier <benoit.lavenier@e-is.pro>
Date: Thu, 2 Jan 2020 10:52:51 +0100
Subject: [PATCH] [fix] Endpoints.parse() return an optional

---
 .../client/dao/mem/MemoryPeerDaoImpl.java     |  8 ++---
 .../core/client/model/bma/Endpoints.java      | 13 ++++----
 .../client/model/bma/NetworkPeerings.java     |  8 +++--
 .../bma/jackson/EndpointDeserializer.java     |  2 +-
 .../core/client/model/bma/EndpointsTest.java  | 33 +++++++++----------
 .../duniter4j-core-client-test.properties     |  2 +-
 6 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java
index 7e02285b..2692269d 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java
@@ -160,8 +160,8 @@ public class MemoryPeerDaoImpl implements PeerDao {
     @Override
     public void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> endpointApis) {
 
-        long minUpTimeInS = Math.round(minUpTimeInMs / 1000);
-        long firstDownTimeInMs = Math.round(System.currentTimeMillis() / 1000);
+        long minUpTimeInSec = minUpTimeInMs / 1000L;
+        long firstDownTime = System.currentTimeMillis() / 1000L;
 
         getPeersByCurrencyId(currencyId).stream()
                 .filter(peer ->
@@ -169,13 +169,13 @@ public class MemoryPeerDaoImpl implements PeerDao {
                         && peer.getStats().isReacheable()
                         && (
                                 peer.getStats().getLastUpTime() == null
-                                || peer.getStats().getLastUpTime() < minUpTimeInS
+                                || peer.getStats().getLastUpTime() < minUpTimeInSec
                         )
                         && (endpointApis == null || endpointApis.contains(peer.getApi()))
                 )
                 .forEach(peer -> {
                     peer.getStats().setStatus(Peer.PeerStatus.DOWN);
-                    peer.getStats().setFirstDownTime(firstDownTimeInMs);
+                    peer.getStats().setFirstDownTime(firstDownTime);
                 });
     }
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Endpoints.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Endpoints.java
index 206a7882..ca095458 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Endpoints.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Endpoints.java
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
+import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -54,7 +55,7 @@ public class Endpoints {
        // helper class
     }
 
-    public static NetworkPeering.Endpoint parse(String raw) throws IOException {
+    public static Optional<NetworkPeering.Endpoint> parse(String raw) throws IOException {
 
         NetworkPeering.Endpoint endpoint = new NetworkPeering.Endpoint();
         endpoint.setRaw(raw);
@@ -64,7 +65,7 @@ public class Endpoints {
         if (mather.matches()) {
             endpoint.api = EndpointApi.BASIC_MERKLED_API;
             parseDefaultFormatEndPoint(mather, endpoint, 1);
-            return endpoint;
+            return Optional.of(endpoint);
         }
 
         // BMAS API
@@ -72,7 +73,7 @@ public class Endpoints {
         if (mather.matches()) {
             endpoint.api = EndpointApi.BMAS;
             parseDefaultFormatEndPoint(mather, endpoint, 1);
-            return endpoint;
+            return Optional.of(endpoint);
         }
 
         // WS2P API
@@ -83,7 +84,7 @@ public class Endpoints {
                 endpoint.api = EndpointApi.valueOf(api);
                 endpoint.id = mather.group(2);
                 parseDefaultFormatEndPoint(mather, endpoint, 3);
-                return endpoint;
+                return Optional.of(endpoint);
             } catch(Exception e) {
                 // Unknown API
                 throw new IOException("Unable to deserialize endpoint: WS2P api [" + api + "]", e); // link the exception
@@ -97,7 +98,7 @@ public class Endpoints {
             try {
                 endpoint.api = EndpointApi.valueOf(api);
                 parseDefaultFormatEndPoint(mather, endpoint, 2);
-                return endpoint;
+                return Optional.of(endpoint);
             } catch(Exception e) {
                 // Unknown API
                 throw new IOException("Unable to deserialize endpoint: unknown api [" + api + "]", e); // link the exception
@@ -105,7 +106,7 @@ public class Endpoints {
         }
 
         log.warn("Unable to parse Endpoint: " + raw);
-        return endpoint;
+        return Optional.empty();
     }
 
     public static void parseDefaultFormatEndPoint(Matcher matcher, NetworkPeering.Endpoint endpoint, int startGroup) {
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java
index 5545c74e..d2850757 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java
@@ -80,9 +80,11 @@ public class NetworkPeerings {
             List<NetworkPeering.Endpoint> endpoints = Lists.newArrayList();
             for (; i < lines.length - 1; ) {
                 line = lines[i++].trim();
-                NetworkPeering.Endpoint ep = Endpoints.parse(line);
-                Preconditions.checkNotNull(ep, "Unable to parse endpoint: " + line);
-                endpoints.add(ep);
+                NetworkPeering.Endpoint ep = Endpoints.parse(line).orElse(null);
+                // Add to endpoint, only if not null
+                if (ep != null) {
+                    endpoints.add(ep);
+                }
             }
             result.setEndpoints(endpoints.toArray(new NetworkPeering.Endpoint[endpoints.size()]));
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/EndpointDeserializer.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/EndpointDeserializer.java
index e8926159..86e694f9 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/EndpointDeserializer.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/jackson/EndpointDeserializer.java
@@ -51,7 +51,7 @@ public class EndpointDeserializer extends JsonDeserializer<NetworkPeering.Endpoi
         String ept = jp.getText();
 
         try {
-            return Endpoints.parse(ept);
+            return Endpoints.parse(ept).orElse(null);
         } catch(IOException e) {
             // Unable to parse endpoint: continue (will skip this endpoint)
             if (debug) {
diff --git a/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/EndpointsTest.java b/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/EndpointsTest.java
index 3271e266..ec1da27f 100644
--- a/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/EndpointsTest.java
+++ b/duniter4j-core-client/src/test/java/org/duniter/core/client/model/bma/EndpointsTest.java
@@ -9,7 +9,7 @@ public class EndpointsTest {
     public void parse() throws Exception {
 
         // Parse valid endpoints
-        NetworkPeering.Endpoint ep = Endpoints.parse("BASIC_MERKLED_API g1.duniter.fr 81.81.81.81 80");
+        NetworkPeering.Endpoint ep = Endpoints.parse("BASIC_MERKLED_API g1.duniter.fr 81.81.81.81 80").orElse(null);
         Assert.assertNotNull(ep);
         Assert.assertEquals(EndpointApi.BASIC_MERKLED_API, ep.api);
         Assert.assertEquals("g1.duniter.fr", ep.dns);
@@ -19,7 +19,7 @@ public class EndpointsTest {
         Assert.assertNull(ep.id);
         Assert.assertNull(ep.path);
 
-        ep = Endpoints.parse("BMAS g1.duniter.fr 443");
+        ep = Endpoints.parse("BMAS g1.duniter.fr 443").orElse(null);
         Assert.assertNotNull(ep);
         Assert.assertEquals(EndpointApi.BMAS, ep.api);
         Assert.assertEquals("g1.duniter.fr", ep.dns);
@@ -28,7 +28,7 @@ public class EndpointsTest {
         Assert.assertNull(ep.id);
         Assert.assertNull(ep.path);
 
-        ep = Endpoints.parse("WS2P fb17fcd4 g1.duniter.fr 443 /ws2p");
+        ep = Endpoints.parse("WS2P fb17fcd4 g1.duniter.fr 443 /ws2p").orElse(null);
         Assert.assertNotNull(ep);
         Assert.assertNotNull(ep.id);
         Assert.assertNotNull(ep.path);
@@ -38,13 +38,13 @@ public class EndpointsTest {
         Assert.assertEquals(443, ep.port.intValue());
 
         // ws2pId on 7 characters
-        ep = Endpoints.parse("WS2P 90e9b12 duniter.g1.1000i100.fr 443 /ws2p");
+        ep = Endpoints.parse("WS2P 90e9b12 duniter.g1.1000i100.fr 443 /ws2p").orElse(null);
         Assert.assertNotNull(ep);
         Assert.assertEquals(ep.api, EndpointApi.WS2P);
         Assert.assertNotNull(ep.id);
         Assert.assertNotNull(ep.path);
 
-        ep = Endpoints.parse("WS2PTOR 1be86653 3k2zovlpihbt3j3g.onion 20901");
+        ep = Endpoints.parse("WS2PTOR 1be86653 3k2zovlpihbt3j3g.onion 20901").orElse(null);
         Assert.assertNotNull(ep);
         Assert.assertNotNull(ep.id);
         Assert.assertNull(ep.path);
@@ -53,7 +53,7 @@ public class EndpointsTest {
         Assert.assertNotNull(ep.port);
         Assert.assertEquals(20901, ep.port.intValue());
 
-        ep = Endpoints.parse("GCHANGE_API data.gchange.fr 443");
+        ep = Endpoints.parse("GCHANGE_API data.gchange.fr 443").orElse(null);
         Assert.assertNotNull(ep);
         Assert.assertEquals(ep.api, EndpointApi.GCHANGE_API);
         Assert.assertNull(ep.id);
@@ -61,20 +61,17 @@ public class EndpointsTest {
 
         // Parse Invalid endpoints
 
-        // FIXME: make sure this must failed (missing port)
-        ep = Endpoints.parse("BMAS g1.cgeek.fr");
-        Assert.assertNotNull(ep);
-        Assert.assertNull(ep.api);
+        // This must failed (missing port)
+        ep = Endpoints.parse("BMAS g1.cgeek.fr").orElse(null);
+        Assert.assertNull(ep);
 
-        // FIXME: make sure this must failed (because bad ID)
-        ep = Endpoints.parse("WS2P R8t2sg7w g1.ambau.ovh 443");
-        Assert.assertNotNull(ep);
-        Assert.assertNull(ep.api);
+        // This must failed (because bad ID)
+        ep = Endpoints.parse("WS2P R8t2sg7w g1.ambau.ovh 443").orElse(null);
+        Assert.assertNull(ep);
 
-        // FIXME: make sure this must failed (missing path first '/')
-        ep = Endpoints.parse("WS2P 90e9b12 duniter.g1.1000i100.fr 443 ws2p");
-        Assert.assertNotNull(ep);
-        Assert.assertNull(ep.api);
+        // This must failed (missing path first '/')
+        ep = Endpoints.parse("WS2P 90e9b12 duniter.g1.1000i100.fr 443 ws2p").orElse(null);
+        Assert.assertNull(ep);
     }
 
 }
diff --git a/duniter4j-core-client/src/test/resources/duniter4j-core-client-test.properties b/duniter4j-core-client/src/test/resources/duniter4j-core-client-test.properties
index de6f268f..5d010a60 100644
--- a/duniter4j-core-client/src/test/resources/duniter4j-core-client-test.properties
+++ b/duniter4j-core-client/src/test/resources/duniter4j-core-client-test.properties
@@ -1,5 +1,5 @@
 duniter4j.node.host=g1-test.duniter.org
-duniter4j.node.port=10900
+duniter4j.node.port=443
 
 duniter4j.node.elasticsearch.host=localhost
 duniter4j.node.elasticsearch.port=9200
-- 
GitLab