IGNITE-10346 Improved TcpDiscoveryVmIpFinder usability in Yardstick - Fixes #5632.
authoroleg-ostanin <oostanin@gridagin.com>
Fri, 28 Dec 2018 12:46:11 +0000 (15:46 +0300)
committerAlexey Goncharuk <alexey.goncharuk@gmail.com>
Fri, 28 Dec 2018 12:46:11 +0000 (15:46 +0300)
Signed-off-by: Alexey Goncharuk <alexey.goncharuk@gmail.com>
modules/yardstick/README.txt
modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteBenchmarkUtils.java
modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteNode.java

index b54bf27..71ed387 100644 (file)
@@ -69,6 +69,10 @@ If you want to execute all the available benchmarks across the remote hosts then
 execute the following command on the DRIVER side:
 ./bin/benchmark-run-all.sh config/benchmark-remote.properties
 
+5. If you use TcpDiscoverySpi in your IgniteConfiguration use AUTOSET_DISCOVERY_VM_IP_FINDER=true property to enable replacing
+addresses from SERVER_HOSTS property to IpFinder configuration. That way you can leave default values '127.0.0.1' in
+Ignite configuration files as is and those values will be replaced with actual addresses. Use PORT_RANGE property to set
+port range for host addresses.
 
 Provided Benchmarks
 ===================
index b3db813..c840294 100644 (file)
@@ -18,7 +18,8 @@
 package org.apache.ignite.yardstick;
 
 import java.util.ArrayList;
-import java.util.List;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -159,7 +160,7 @@ public class IgniteBenchmarkUtils {
      * @param arg Argument name.
      * @param val Argument value.
      */
-    private static void addArg(List<String> args, String arg, Object val) {
+    private static void addArg(Collection<String> args, String arg, Object val) {
         args.add(arg);
         args.add(val.toString());
     }
@@ -182,4 +183,53 @@ public class IgniteBenchmarkUtils {
 
         return lgr;
     }
+
+    /**
+     * Checks if address list contains no localhost addresses.
+     *
+     * @param adrList address list.
+     * @return {@code true} if address list contains no localhost addresses or {@code false} otherwise.
+     */
+    static boolean checkIfNoLocalhost(Iterable<String> adrList) {
+        int locAdrNum = 0;
+
+        for (String adr : adrList) {
+            if (adr.contains("127.0.0.1") || adr.contains("localhost"))
+                locAdrNum++;
+        }
+
+        return locAdrNum == 0;
+    }
+
+    /**
+     * Parses portRange string.
+     *
+     * @param portRange {@code String} port range as 'int..int'.
+     * @return {@code Collection<Integer>} Port list.
+     */
+    static Collection<Integer> getPortList(String portRange) {
+        int firstPort;
+        int lastPort;
+
+        try {
+            String[] numArr = portRange.split("\\.\\.");
+
+            firstPort = Integer.valueOf(numArr[0]);
+            lastPort = numArr.length > 1 ? Integer.valueOf(numArr[1]) : firstPort;
+        }
+        catch (NumberFormatException e) {
+            BenchmarkUtils.println(String.format("Failed to parse PORT_RANGE property: %s; %s",
+                portRange, e.getMessage()));
+
+            throw new IllegalArgumentException(String.format("Wrong value for PORT_RANGE property: %s",
+                portRange));
+        }
+
+        Collection<Integer> res = new HashSet<>();
+
+        for (int port = firstPort; port <= lastPort; port++)
+            res.add(port);
+
+        return res;
+    }
 }
index e107f78..ef02852 100644 (file)
 
 package org.apache.ignite.yardstick;
 
+import java.net.InetSocketAddress;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.TreeSet;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteSpring;
@@ -37,6 +43,7 @@ import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.yardstick.io.FileUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
@@ -48,11 +55,16 @@ import org.yardstickframework.BenchmarkServer;
 import org.yardstickframework.BenchmarkUtils;
 
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER;
+import static org.apache.ignite.yardstick.IgniteBenchmarkUtils.checkIfNoLocalhost;
+import static org.apache.ignite.yardstick.IgniteBenchmarkUtils.getPortList;
 
 /**
  * Standalone Ignite node.
  */
 public class IgniteNode implements BenchmarkServer {
+    /** Default port range */
+    private static final String DFLT_PORT_RANGE = "47500..47549";
+
     /** Grid instance. */
     private Ignite ignite;
 
@@ -195,6 +207,11 @@ public class IgniteNode implements BenchmarkServer {
             c.setDataStorageConfiguration(pcCfg);
         }
 
+        // If we use TcpDiscoverySpi try to set addresses from SERVER_HOSTS property to
+        // TcpDiscoveryIpFinder configuration.
+        if (c.getDiscoverySpi() instanceof TcpDiscoverySpi)
+            replaceAdrList(c, cfg);
+
         ignite = IgniteSpring.start(c, appCtx);
 
         BenchmarkUtils.println("Configured marshaller: " + ignite.cluster().localNode().attribute(ATTR_MARSHALLER));
@@ -205,7 +222,8 @@ public class IgniteNode implements BenchmarkServer {
      * @return Tuple with grid configuration and Spring application context.
      * @throws Exception If failed.
      */
-    public static IgniteBiTuple<IgniteConfiguration, ? extends ApplicationContext> loadConfiguration(String springCfgPath)
+    public static IgniteBiTuple<IgniteConfiguration, ? extends ApplicationContext> loadConfiguration(
+        String springCfgPath)
         throws Exception {
         URL url;
 
@@ -267,4 +285,72 @@ public class IgniteNode implements BenchmarkServer {
     public Ignite ignite() {
         return ignite;
     }
+
+    /**
+     * Replaces addresses in IpFinder list.
+     *
+     * @param c Ignite configuration.
+     * @param cfg Benchmark configuration.
+     */
+    private void replaceAdrList(IgniteConfiguration c, BenchmarkConfiguration cfg) {
+        if (cfg.customProperties() == null)
+            return;
+
+        if (cfg.customProperties().get("AUTOSET_DISCOVERY_VM_IP_FINDER") == null
+            || !Boolean.valueOf(cfg.customProperties().get("AUTOSET_DISCOVERY_VM_IP_FINDER")))
+            return;
+
+        if (cfg.customProperties().get("SERVER_HOSTS") == null)
+            return;
+
+        String hosts = cfg.customProperties().get("SERVER_HOSTS");
+
+        Collection<String> adrSetFromProp = new HashSet<>(Arrays.asList(hosts.split(",")));
+
+        if(adrSetFromProp.isEmpty())
+            return;
+
+        TcpDiscoverySpi spi = (TcpDiscoverySpi)c.getDiscoverySpi();
+
+        Collection<InetSocketAddress> regAdrList = spi.getIpFinder().getRegisteredAddresses();
+
+        Collection<String> adrList = new ArrayList<>(regAdrList.size());
+
+        for (InetSocketAddress adr : regAdrList)
+            adrList.add(adr.getHostString());
+
+        if (checkIfNoLocalhost(adrSetFromProp)) {
+            Collection<InetSocketAddress> newAdrList = new ArrayList<>(adrSetFromProp.size());
+
+            Collection<String> toDisplay = new TreeSet<>();
+
+            String portRange = cfg.customProperties().get("PORT_RANGE") != null ?
+                cfg.customProperties().get("PORT_RANGE") :
+                DFLT_PORT_RANGE;
+
+            for (String adr : adrSetFromProp) {
+                for (Integer port : getPortList(portRange))
+                    newAdrList.add(new InetSocketAddress(adr, port));
+
+                toDisplay.add(String.format("/%s:%s", adr, portRange));
+            }
+
+            BenchmarkUtils.println("Setting SERVER_HOSTS addresses for IpFinder configuration.");
+
+            BenchmarkUtils.println(String.format("Replacing list: \n %s \n to list: \n %s",
+                regAdrList, toDisplay));
+
+            spi.getIpFinder().unregisterAddresses(regAdrList);
+
+            spi.getIpFinder().registerAddresses(newAdrList);
+
+            for (String adr : IgniteUtils.allLocalIps()) {
+                if (adrSetFromProp.contains(adr)) {
+                    BenchmarkUtils.println(String.format("Setting 'localhost' property to %s", adr));
+
+                    c.setLocalHost(adr);
+                }
+            }
+        }
+    }
 }