diff --git a/duniter4j-client/pom.xml b/duniter4j-client/pom.xml index 94dbf2284d8dfa1ed19ccc67a10b4bcc1595b9e3..730cd83447ef809e93669e2ff8d7b27cfbd6831e 100644 --- a/duniter4j-client/pom.xml +++ b/duniter4j-client/pom.xml @@ -21,9 +21,7 @@ <i18n.bundleOutputName>duniter4j-client-i18n</i18n.bundleOutputName> <i18n.bundleCsvFile>${i18n.bundleOutputName}.csv</i18n.bundleCsvFile> - <maven.jar.main.class> - org.duniter.client.Main - </maven.jar.main.class> + <maven.jar.main.class>org.duniter.client.Main</maven.jar.main.class> <bundlePrefix>duniter4j-client-${project.version}</bundlePrefix> diff --git a/duniter4j-client/src/main/java/org/duniter/client/Main.java b/duniter4j-client/src/main/java/org/duniter/client/Main.java index c7b1c7258314d38bffd860888e06d61e1f7f2cbf..a03b93a68a647db1ba7151220bc61e9dff18a032 100644 --- a/duniter4j-client/src/main/java/org/duniter/client/Main.java +++ b/duniter4j-client/src/main/java/org/duniter/client/Main.java @@ -51,16 +51,16 @@ import java.util.Map; @Parameters(resourceBundle = "i18n.duniter4j-client") public class Main { - @Parameter(names = "-debug", description = "Debug mode", descriptionKey = "duniter4j.params.debug") + @Parameter(names = "-debug", description = "Debug mode", descriptionKey = "duniter4j.client.params.debug") private boolean debug = false; - @Parameter(names = "--help", help = true) + @Parameter(names = "--help", help = true, description = "Display help", descriptionKey = "duniter4j.client.params.help") private boolean help; @Parameter(names = "--basedir", hidden = true) private File basedir; - @Parameter(names = "--config", description = "Configuration file path", descriptionKey="duniter4j.params.config" ) + @Parameter(names = "--config", description = "Configuration file path", descriptionKey="duniter4j.client.params.config" ) private String configFilename = "duniter-client.config"; public static void main(String ... args) { diff --git a/duniter4j-client/src/main/java/org/duniter/client/actions/NetworkAction.java b/duniter4j-client/src/main/java/org/duniter/client/actions/NetworkAction.java index b2c64093006593e6e1c1dc035264018078c19738..2903072d42764f718353f0572e27f6fbada47aa5 100644 --- a/duniter4j-client/src/main/java/org/duniter/client/actions/NetworkAction.java +++ b/duniter4j-client/src/main/java/org/duniter/client/actions/NetworkAction.java @@ -30,6 +30,8 @@ import org.duniter.client.actions.params.PeerParameters; import org.duniter.client.actions.utils.RegexAnsiConsole; import org.duniter.client.actions.utils.Formatters; import org.apache.commons.io.IOUtils; +import org.duniter.core.client.config.Configuration; +import org.duniter.core.client.config.ConfigurationOption; import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.service.ServiceLocator; import org.duniter.core.client.service.local.NetworkService; @@ -76,7 +78,12 @@ public class NetworkAction extends AbstractAction { final Peer mainPeer = peerParameters.getPeer(); checkOutputFileIfNotNull(); // make sure the file (if any) is writable - dateFormat = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, I18n.getDefaultLocale()); + // Reducing node timeout when broadcast + if (peerParameters.timeout != null) { + Configuration.instance().getApplicationConfig().setOption(ConfigurationOption.NETWORK_TIMEOUT.getKey(), peerParameters.timeout.toString()); + } + + dateFormat = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.MEDIUM, I18n.getDefaultLocale()); console = new RegexAnsiConsole(); System.setOut(console); @@ -122,22 +129,24 @@ public class NetworkAction extends AbstractAction { Peer.Stats mainConsensusStats = mainConsensusPeer.getStats(); if (mainConsensusStats.isMainConsensus()) { Long mediantTime = mainConsensusStats.getMedianTime(); + String medianTime = dateFormat.format(new Date(mediantTime * 1000)); String mainBuid = formatBuid(mainConsensusStats); - console.resetFgRegexps() - .fgRegexp(I18n.t("duniter4j.client.network.ssl"), Ansi.Color.MAGENTA) - .fgRegexp(I18n.t("duniter4j.client.network.mirror"), Ansi.Color.CYAN) - .fgRegexp(mainBuid, Ansi.Color.GREEN); + console.reset() + .fgString(I18n.t("duniter4j.client.network.ssl"), Ansi.Color.MAGENTA) + .fgString(I18n.t("duniter4j.client.network.mirror"), Ansi.Color.CYAN) + .fgString(mainBuid, Ansi.Color.GREEN) + .fgString(medianTime, Ansi.Color.GREEN); peers.stream() .filter(peer -> peer.getStats().isForkConsensus()) .map(peer -> formatBuid(peer.getStats())) - .forEach(forkConsensusBuid -> console.fgRegexp(Formatters.formatBuid(forkConsensusBuid), Ansi.Color.YELLOW)); + .forEach(forkConsensusBuid -> console.fgString(Formatters.formatBuid(forkConsensusBuid), Ansi.Color.YELLOW)); // Log blockchain info console.println("\t" + I18n.t("duniter4j.client.network.header", mainBuid, - dateFormat.format(new Date(mediantTime * 1000)), + medianTime, mainConsensusStats.getConsensusPct() )); } diff --git a/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java b/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java index d8ee63e11057b7ec20b8d6832dd8c1a8a0bf3c59..e38a78dc90a3964d178c55a96d0f26bbcf89ae52 100644 --- a/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java +++ b/duniter4j-client/src/main/java/org/duniter/client/actions/TransactionAction.java @@ -31,6 +31,8 @@ import com.google.common.collect.ImmutableList; import org.duniter.client.actions.params.AuthParameters; import org.duniter.client.actions.params.PeerParameters; import org.duniter.client.actions.utils.Formatters; +import org.duniter.core.client.config.Configuration; +import org.duniter.core.client.config.ConfigurationOption; import org.duniter.core.client.model.bma.EndpointApi; import org.duniter.core.client.model.local.Currency; import org.duniter.core.client.model.local.Peer; @@ -73,6 +75,9 @@ public class TransactionAction extends AbstractAction { @Parameter(names = "--comment", description = "TX Comment") public String comment; + @Parameter(names = "--broadcast", description = "Broadcast document sent to all nodes") + public boolean broadcast = false; + private int mainConsensusPeerCount = 0; private int forkConsensusPeerCount = 0; @@ -89,7 +94,9 @@ public class TransactionAction extends AbstractAction { peerParameters.parse(); // Reducing node timeout when broadcast - + if (peerParameters.timeout != null) { + Configuration.instance().getApplicationConfig().setOption(ConfigurationOption.NETWORK_TIMEOUT.getKey(), peerParameters.timeout.toString()); + } Peer peer = peerParameters.getPeer(); @@ -126,7 +133,7 @@ public class TransactionAction extends AbstractAction { wallet.setCurrencyId(currency.getId()); // Send TX document to ONE peer - if (!peerParameters.broadcast) { + if (!broadcast) { sendToPeer(peer, wallet); } diff --git a/duniter4j-client/src/main/java/org/duniter/client/actions/params/PeerParameters.java b/duniter4j-client/src/main/java/org/duniter/client/actions/params/PeerParameters.java index 665915442bc9f2a1a5661b761b39f3c684015dcd..c89e74d2a57ca70b622418040c346e59ce391b3a 100644 --- a/duniter4j-client/src/main/java/org/duniter/client/actions/params/PeerParameters.java +++ b/duniter4j-client/src/main/java/org/duniter/client/actions/params/PeerParameters.java @@ -39,16 +39,13 @@ public class PeerParameters { private static Logger log = LoggerFactory.getLogger(PeerParameters.class); - @Parameter(names = {"-p", "--peer"}, description = "Peer address (use format: 'host:port')", descriptionKey = "duniter4j.params.peer") + @Parameter(names = {"-p", "--peer"}, description = "Peer address (use format: 'host:port')", descriptionKey = "duniter4j.client.params.peer") public String peerStr; - @Parameter(names = "--broadcast", description = "Broadcast document sent to all nodes") - public boolean broadcast = false; - - @Parameter(names = "--ssl", description = "Using SSL connection to node") + @Parameter(names = "--ssl", description = "Using SSL connection to node", descriptionKey = "duniter4j.client.params.peer.useSsl") public boolean useSsl = false; - @Parameter(names = "--timeout", description = "HTTP request timeout, in millisecond") + @Parameter(names = "--timeout", description = "HTTP request timeout, in millisecond", descriptionKey = "duniter4j.client.params.peer.timeout") public Long timeout = null; private Peer peer = null; @@ -71,14 +68,14 @@ public class PeerParameters { } peer = peerBuilder.build(); - log.info(I18n.t("duniter4j.client.params.peer", peer.getHost(), peer.getPort())); + log.info(I18n.t("duniter4j.client.info.peer", peer.getHost(), peer.getPort())); } else { Configuration config = Configuration.instance(); peer = Peer.newBuilder().setHost(config.getNodeHost()) .setPort(config.getNodePort()) .build(); - log.info(I18n.t("duniter4j.client.params.peer.fallback", peer.getHost(), peer.getPort())); + log.info(I18n.t("duniter4j.client.info.peer.fallback", peer.getHost(), peer.getPort())); } } diff --git a/duniter4j-client/src/main/java/org/duniter/client/actions/utils/RegexAnsiConsole.java b/duniter4j-client/src/main/java/org/duniter/client/actions/utils/RegexAnsiConsole.java index f5098565d45983d5b3dc5320d19560af3a50a0c6..7d20823fb19f7de0272eca6dd9868282758b0a3b 100644 --- a/duniter4j-client/src/main/java/org/duniter/client/actions/utils/RegexAnsiConsole.java +++ b/duniter4j-client/src/main/java/org/duniter/client/actions/utils/RegexAnsiConsole.java @@ -41,6 +41,7 @@ import static org.fusesource.jansi.Ansi.ansi; public class RegexAnsiConsole extends PrintStream { private Long rowsCount = 0l; + private Map<String, Ansi.Color> fgStrings = Maps.newHashMap(); private Map<Pattern, Ansi.Color> fgRegexps = Maps.newHashMap(); public RegexAnsiConsole(OutputStream delegate) { @@ -80,9 +81,16 @@ public class RegexAnsiConsole extends PrintStream { super.print(ansi); return this; } - - public RegexAnsiConsole resetFgRegexps() { + + public RegexAnsiConsole reset() { + fgStrings.clear(); fgRegexps.clear(); + super.print(ansi().reset()); + return this; + } + + public RegexAnsiConsole fgString(String value, Ansi.Color color) { + fgStrings.put(value, color); return this; } @@ -94,16 +102,15 @@ public class RegexAnsiConsole extends PrintStream { @Override public void print(String s) { - for (Pattern pattern: fgRegexps.keySet()) { - Matcher matcher = pattern.matcher(s); + for (Map.Entry<Pattern, Ansi.Color> entry: fgRegexps.entrySet()) { + Matcher matcher = entry.getKey().matcher(s); if (matcher.find()) { - Ansi.Color fgColor = fgRegexps.get(pattern); Ansi ansi = ansi(); if (matcher.start() > 0) { ansi.a(s.substring(0, matcher.start())); } - ansi.fg(fgColor) + ansi.fg(entry.getValue()) .a(s.substring(matcher.start(), matcher.end())) .reset(); if (matcher.end() < s.length()) { @@ -113,6 +120,25 @@ public class RegexAnsiConsole extends PrintStream { } } + for (Map.Entry<String, Ansi.Color> entry: fgStrings.entrySet()) { + String expression = entry.getKey(); + int index = s.indexOf(expression); + if (index != -1) { + Ansi ansi = ansi(); + if (index > 0) { + ansi.a(s.substring(0, index)); + } + + ansi.fg(entry.getValue()) + .a(expression) + .reset(); + if (index + expression.length() < s.length()) { + ansi.a(s.substring(index + expression.length())); + } + s = ansi.toString(); + } + } + long newLineCount = 0; for (int i=0; i<s.length(); i++) { if (s.charAt(i) == '\n') newLineCount++; diff --git a/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties b/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties new file mode 100644 index 0000000000000000000000000000000000000000..a24a330f67ee62c3b99a3ddbe4d9afd2b9b07223 --- /dev/null +++ b/duniter4j-client/src/main/resources/i18n/duniter4j-client_en_GB.properties @@ -0,0 +1,34 @@ +duniter4j.client.info.peer=Duniter peer\: [%s\:%s] +duniter4j.client.info.peer.fallback=Fallback to default Duniter peer\: [%s\:%d] +duniter4j.client.network.action=Display network peers +duniter4j.client.network.cesiumPlus=Cs+ +duniter4j.client.network.error.outputFieNotWritable=Output file not writable +duniter4j.client.network.header=Main BlockChain version\: block [%1$s] computed at [%2$s] validated by [%3$3.2f%%] of peers +duniter4j.client.network.loadingPeers=Reading network peers... +duniter4j.client.network.mirror=Mirror +duniter4j.client.network.noPeers=No peers found +duniter4j.client.network.params.continue=Continue scanning? (Will refresh on new peer/block). +duniter4j.client.network.params.output=Output CSV file +duniter4j.client.network.ssl=SSL +duniter4j.client.params.authScrypt.ask.passwd=Please enter your Scrypt password\: +duniter4j.client.params.authScrypt.ask.salt=Please enter your Scrypt Salt (Secret identifier)\: +duniter4j.client.params.authScrypt.ask.scryptParams=Please enter your Scrypt parameters (N,r,p)\: [%d,%d,%d] +duniter4j.client.params.authScrypt.error.scryptParams=Invalid Scrypt parameters (expected 3 values)" +duniter4j.client.params.config=Configuration file path +duniter4j.client.params.debug=Show debug logs +duniter4j.client.params.error.invalidOption=Invalid value of option [%s] +duniter4j.client.params.help=Display help +duniter4j.client.params.peer=Duniter peer (host\:port) +duniter4j.client.params.peer.fallback= +duniter4j.client.params.peer.timeout=Maximal delay for a peer response, in milliseconds +duniter4j.client.params.peer.useSsl=Use SSL for peer's connection ? +duniter4j.client.transaction.action=Send a transaction +duniter4j.client.transaction.broadcast.failed=Transaction has NOT been sent. Not a single peer has accepted the transaction. +duniter4j.client.transaction.broadcast.memberPeerCount=%d member peers found for broadcast +duniter4j.client.transaction.broadcast.success=Transaction successfully sent (to %d nodes on the main blockchain) +duniter4j.client.transaction.broadcast.successOnForkOnly=Transaction has NOT been sent to the main consensus BlockChain, but ONLY to %d peers on a fork of the blockchain +duniter4j.client.transaction.broadcast.summary=Generate Transation\:\n\t- From\: %s\n\t- To\: %s\n\t- Amount\: %s %s +duniter4j.client.transaction.error.broadcast.noMemberPeer=No members peers found\! Skipping --broadcast option +duniter4j.client.transaction.error.unknownAuth=Unknown authentication type +duniter4j.client.transaction.loadingMemberPeers=Retrieving member's peers... +duniter4j.client.transaction.sent=Transaction successfully sent. diff --git a/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties b/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties new file mode 100644 index 0000000000000000000000000000000000000000..b0f6d285e88a947a437fa63036da38b4abd9b033 --- /dev/null +++ b/duniter4j-client/src/main/resources/i18n/duniter4j-client_fr_FR.properties @@ -0,0 +1,34 @@ +duniter4j.client.info.peer=Noeud Duniter \: [%s\:%s] +duniter4j.client.info.peer.fallback=Noeud Duniter (par défaut) \: [%s\:%d] +duniter4j.client.network.action=Afficher les noeuds Duniter +duniter4j.client.network.cesiumPlus=Cs+ +duniter4j.client.network.error.outputFieNotWritable=Fichier de sortie non inscriptible +duniter4j.client.network.header=Chaine de bloc principal \: bloc [%1$s] calculé à [%2$s] validé par [%3$3.2f%%] des noeuds +duniter4j.client.network.loadingPeers=Lecture des noeuds du réseau... +duniter4j.client.network.mirror=Mirroir +duniter4j.client.network.noPeers=Aucun noeud trouvé +duniter4j.client.network.params.continue=Continue scanning? (Will refresh on new peer/block). +duniter4j.client.network.params.output=Output CSV file +duniter4j.client.network.ssl=SSL +duniter4j.client.params.authScrypt.ask.passwd=Veuillez entrer votre mot de passe Scrypt (password) \: +duniter4j.client.params.authScrypt.ask.salt=Veuillez entrer votre identifiant secret Scrypt (Salt)\: +duniter4j.client.params.authScrypt.ask.scryptParams=Veuillez entrer les paramètres de Scrypt (N,r,p)\: [%d,%d,%d] +duniter4j.client.params.authScrypt.error.scryptParams=Paramètre Scrypt non valide (3 valeurs attendues - format 'N,r,p')" +duniter4j.client.params.config=Fichier de configuration +duniter4j.client.params.debug=Activer les logs de débuggage +duniter4j.client.params.error.invalidOption=Valeur d'option [%s] invalid +duniter4j.client.params.help=Affichage de l'aide +duniter4j.client.params.peer=Noeud Duniter (hôte\:port) +duniter4j.client.params.peer.fallback= +duniter4j.client.params.peer.timeout=Délai de réponse max. d'un noeud, en millisecondes +duniter4j.client.params.peer.useSsl=Utiliser une connection SSL ? +duniter4j.client.transaction.action=Effectuer une transaction +duniter4j.client.transaction.broadcast.failed=Transaction NON envoyée. Aucun noeud n'a accepté la transaction. +duniter4j.client.transaction.broadcast.memberPeerCount=%d noeud membres trouvé, pour l'envoi multiple +duniter4j.client.transaction.broadcast.success=Transaction envoyée avec succès (à %d noeuds de la branche principale de la chaine de blocs) +duniter4j.client.transaction.broadcast.successOnForkOnly=Transaction NON envoyée sur la branche principale, mais seulement sur %d noeud d'une branche secondaire de la cheine de blocs +duniter4j.client.transaction.broadcast.summary=Envoi de la transation\:\n\t- De\: %s\n\t- A\: %s\n\t- Montant\: %s %s +duniter4j.client.transaction.error.broadcast.noMemberPeer=Aucun noeud membre trouvé \! L'option --broadcast va être ignorée +duniter4j.client.transaction.error.unknownAuth=Type d'authentification inconnue +duniter4j.client.transaction.loadingMemberPeers=Récupération des noeuds membres... +duniter4j.client.transaction.sent=Transaction envoyé avec succès. diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java index 772a3de3dd8d465193f243e8dffb79e77ffb2ec2..567f0d5a8d95f863754f1ae6669fb92e9d4c4a2e 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java @@ -32,6 +32,7 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; @@ -301,8 +302,8 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean catch (ConnectException e) { throw new HttpConnectException(I18n.t("duniter4j.client.core.connect", request.toString()), e); } - catch (SocketTimeoutException e) { - throw new TechnicalException(I18n.t("duniter4j.client.core.timeout"), e); + catch (SocketTimeoutException | ConnectTimeoutException e) { + throw new HttpTimeoutException(I18n.t("duniter4j.client.core.timeout"), e); } catch (IOException e) { throw new TechnicalException(e.getMessage(), e); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/exception/HttpTimeoutException.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/exception/HttpTimeoutException.java new file mode 100644 index 0000000000000000000000000000000000000000..683666aaa266481d0c4c80f9a4e560c81a7d9b6a --- /dev/null +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/exception/HttpTimeoutException.java @@ -0,0 +1,56 @@ +package org.duniter.core.client.service.exception; + +/* + * #%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.Error; +import org.duniter.core.exception.TechnicalException; + +/** + * Created by eis on 11/02/15. + */ +public class HttpTimeoutException extends TechnicalException{ + + private static final long serialVersionUID = -5260280401104018980L; + + public HttpTimeoutException() { + super(); + } + + public HttpTimeoutException(String message, Throwable cause) { + super(message, cause); + } + + public HttpTimeoutException(String message) { + super(message); + } + + public HttpTimeoutException(Error error) { + super(error.getMessage()); + setCode(error.getUcode()); + } + + public HttpTimeoutException(Throwable cause) { + super(cause); + } + +} diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/util/http/InetAddressUtils.java b/duniter4j-core-shared/src/main/java/org/duniter/core/util/http/InetAddressUtils.java index 5f2c60b61595d23153de0ef60c1ab05c3bd56733..39b9b83f8e021bc5bf2ec6cbc174a4fe8b0d2bf3 100644 --- a/duniter4j-core-shared/src/main/java/org/duniter/core/util/http/InetAddressUtils.java +++ b/duniter4j-core-shared/src/main/java/org/duniter/core/util/http/InetAddressUtils.java @@ -36,7 +36,12 @@ public class InetAddressUtils { public static boolean isNotLocalIPv4Address(String input) { return org.apache.http.conn.util.InetAddressUtils.isIPv4Address(input) && - !LOCAL_IP_ADDRESS_PATTERN.matcher(input).matches(); + !LOCAL_IP_ADDRESS_PATTERN.matcher(input).find(); + } + + public static boolean isLocalIPv4Address(String input) { + return org.apache.http.conn.util.InetAddressUtils.isIPv4Address(input) && + LOCAL_IP_ADDRESS_PATTERN.matcher(input).find(); } public static boolean isIPv4Address(String input) { diff --git a/duniter4j-core-shared/src/test/java/org/duniter/core/util/http/InetAddressUtilsTest.java b/duniter4j-core-shared/src/test/java/org/duniter/core/util/http/InetAddressUtilsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..84db99f2d3e1708da0c7de8b74410e7f23fb9614 --- /dev/null +++ b/duniter4j-core-shared/src/test/java/org/duniter/core/util/http/InetAddressUtilsTest.java @@ -0,0 +1,27 @@ +package org.duniter.core.util.http; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by blavenie on 30/03/17. + */ +public class InetAddressUtilsTest { + + @Test + public void isNotLocalIPv4Address() { + + Assert.assertFalse(InetAddressUtils.isNotLocalIPv4Address("192.168.1.11")); + Assert.assertFalse(InetAddressUtils.isNotLocalIPv4Address("abc")); + + Assert.assertTrue(InetAddressUtils.isNotLocalIPv4Address("82.239.120.237")); + } + + @Test + public void isLocalIPv4Address() { + + boolean check = InetAddressUtils.isLocalIPv4Address("192.168.1.11"); + Assert.assertTrue(check); + } + +}