Package org.infinispan.test.fwk

Source Code of org.infinispan.test.fwk.JGroupsConfigBuilder

package org.infinispan.test.fwk;

import org.infinispan.config.parsing.JGroupsStackParser;
import org.infinispan.config.parsing.XmlConfigHelper;
import org.jgroups.util.Util;
import org.w3c.dom.Element;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* This class owns the logic of associating network resources(i.e. ports) with threads, in order to make sure that there
* won't be any clashes between multiple clusters running in parallel on same host. Used for parallel test suite.
*
* @author Mircea.Markus@jboss.com
*/
public class JGroupsConfigBuilder {

   public static final String JGROUPS_STACK;

   private static String bind_addr = "127.0.0.1";
   private static String tcpConfig;
   private static String udpConfig;

   private static final ThreadLocal<String> threadTcpStartPort = new ThreadLocal<String>() {
      private final AtomicInteger uniqueAddr = new AtomicInteger(7900);

      @Override
      protected String initialValue() {
         return uniqueAddr.getAndAdd(50) + "";
      }
   };

   /**
    * Holds unique mcast_addr for each thread used for JGroups channel construction.
    */
   private static final ThreadLocal<String> threadMcastIP = new ThreadLocal<String>() {
      private final AtomicInteger uniqueAddr = new AtomicInteger(11);

      @Override
      protected String initialValue() {
         return "228.10.10." + uniqueAddr.getAndIncrement();
      }
   };

   /**
    * Holds unique mcast_port for each thread used for JGroups channel construction.
    */
   private static final ThreadLocal<Integer> threadMcastPort = new ThreadLocal<Integer>() {
      private final AtomicInteger uniquePort = new AtomicInteger(45589);

      @Override
      protected Integer initialValue() {
         return uniquePort.getAndIncrement();
      }
   };

   private static final Pattern TCP_START_PORT = Pattern.compile("bind_port=[^;]*");
   private static final Pattern TCP_INITIAL_HOST = Pattern.compile("initial_hosts=[^;]*");
   private static final Pattern UDP_MCAST_ADDRESS = Pattern.compile("mcast_addr=[^;]*");
   private static final Pattern UDP_MCAST_PORT = Pattern.compile("mcast_port=[^;]*");

   static {
      JGROUPS_STACK = System.getProperties().getProperty("protocol.stack", "tcp");
      System.out.println("Transport protocol stack used = " + JGROUPS_STACK);

      try {
         bind_addr = Util.getBindAddress(null).getHostAddress();
      } catch (Exception e) {
      }
   }

   public static String getJGroupsConfig() {
      if (JGROUPS_STACK.equalsIgnoreCase("tcp")) return getTcpConfig();
      if (JGROUPS_STACK.equalsIgnoreCase("udp")) return getUdpConfig();
      throw new IllegalStateException("Unknown protocol stack : " + JGROUPS_STACK);
   }

   public static String getTcpConfig() {
      loadTcp();

      if (tcpConfig.contains("TCPPING")) {
         return getTcpConfigWithTCPPINGDiscoevry();
      } else {
         return replaceMCastAddressAndPort(tcpConfig);
      }
   }

   private static String getTcpConfigWithTCPPINGDiscoevry() {
      // replace mcast_addr
      Matcher m = TCP_START_PORT.matcher(tcpConfig);
      String result;
      String newStartPort;
      if (m.find()) {
         newStartPort = threadTcpStartPort.get();
         result = m.replaceFirst("bind_port=" + newStartPort);
      } else {
         System.out.println("Config is:" + tcpConfig);
         Thread.dumpStack();
         throw new IllegalStateException();
      }

      if (result.indexOf("TCPGOSSIP") < 0) // onluy adjust for TCPPING
      {
         m = TCP_INITIAL_HOST.matcher(result);
         if (m.find()) {
            result = m.replaceFirst("initial_hosts=" + bind_addr + "[" + newStartPort + "]");
         }
      }
      return result;
   }

   public static String getUdpConfig() {
      loadUdp();
      // replace mcast_addr
      String config = udpConfig;
      return replaceMCastAddressAndPort(config);
   }

   private static String replaceMCastAddressAndPort(String config) {
      Matcher m = UDP_MCAST_ADDRESS.matcher(config);
      String result;
      if (m.find()) {
         String newAddr = threadMcastIP.get();
         result = m.replaceFirst("mcast_addr=" + newAddr);
      } else {
         Thread.dumpStack();
         throw new IllegalStateException();
      }

      // replace mcast_port
      m = UDP_MCAST_PORT.matcher(result);
      if (m.find()) {
         String newPort = threadMcastPort.get().toString();
         result = m.replaceFirst("mcast_port=" + newPort);
      }
      return result;
   }

   private static void loadTcp() {
      if (tcpConfig != null) return;
      String xmlString = readFile("stacks/tcp.xml");
      tcpConfig = getJgroupsConfig(xmlString);
   }

   private static void loadUdp() {
      if (udpConfig != null) return;
      String xmlString = readFile("stacks/udp.xml");
      udpConfig = getJgroupsConfig(xmlString);
   }

   private static String getJgroupsConfig(String xmlString) {
      try {
         Element e = XmlConfigHelper.stringToElement(xmlString);
         JGroupsStackParser parser = new JGroupsStackParser();
         return parser.parseClusterConfigXml(e);
      } catch (Exception ex) {
         throw new RuntimeException("Unexpected!", ex);
      }
   }

   private static String readFile(String fileName) {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      InputStream is = cl.getResourceAsStream(fileName);
      BufferedReader bf = new BufferedReader(new InputStreamReader(is));
      StringBuilder result = new StringBuilder();
      String line;
      try {
         while ((line = bf.readLine()) != null) result.append(line);
      } catch (IOException e) {
         throw new RuntimeException("Unexpected!", e);
      } finally {
         try {
            bf.close();
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
      return result.toString();
   }
}
TOP

Related Classes of org.infinispan.test.fwk.JGroupsConfigBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.