http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fc768b83/modules/core/src/main/java/org/apache/ignite/internal/util/GridUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUtils.java deleted file mode 100644 index b3627fc..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUtils.java +++ /dev/null @@ -1,9141 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.util; - -import org.apache.ignite.*; -import org.apache.ignite.cache.*; -import org.apache.ignite.cluster.*; -import org.apache.ignite.compute.*; -import org.apache.ignite.configuration.*; -import org.apache.ignite.events.*; -import org.apache.ignite.internal.*; -import org.apache.ignite.internal.mxbean.*; -import org.apache.ignite.internal.processors.cache.*; -import org.apache.ignite.internal.processors.cache.version.*; -import org.apache.ignite.lang.*; -import org.apache.ignite.lifecycle.*; -import org.apache.ignite.portables.*; -import org.apache.ignite.spi.*; -import org.apache.ignite.internal.managers.deployment.*; -import org.apache.ignite.internal.processors.streamer.*; -import org.apache.ignite.spi.discovery.*; -import org.apache.ignite.internal.util.io.*; -import org.apache.ignite.internal.util.lang.*; -import org.apache.ignite.internal.util.typedef.*; -import org.apache.ignite.internal.util.typedef.internal.*; -import org.apache.ignite.internal.util.worker.*; -import org.jdk8.backport.*; -import org.jetbrains.annotations.*; -import sun.misc.*; - -import javax.management.*; -import javax.naming.*; -import javax.net.ssl.*; -import java.io.*; -import java.lang.annotation.Annotation; -import java.lang.management.*; -import java.lang.reflect.Array; -import java.lang.reflect.*; -import java.math.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.nio.channels.spi.*; -import java.nio.charset.*; -import java.security.*; -import java.security.cert.*; -import java.sql.*; -import java.sql.Timestamp; -import java.text.*; -import java.util.*; -import java.util.Date; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.*; -import java.util.jar.*; -import java.util.logging.*; -import java.util.regex.*; -import java.util.zip.*; - -import static org.apache.ignite.IgniteSystemProperties.*; -import static org.apache.ignite.events.IgniteEventType.*; -import static org.apache.ignite.internal.GridNodeAttributes.*; - -/** - * Collection of utility methods used throughout the system. - */ -@SuppressWarnings({"UnusedReturnValue", "UnnecessaryFullyQualifiedName"}) -public abstract class GridUtils { - /** Unsafe. */ - private static final Unsafe UNSAFE = GridUnsafe.unsafe(); - - /** {@code True} if {@code unsafe} should be used for array copy. */ - private static final boolean UNSAFE_BYTE_ARR_CP = unsafeByteArrayCopyAvailable(); - - /** Offset. */ - private static final int BYTE_ARRAY_DATA_OFFSET = UNSAFE.arrayBaseOffset(byte[].class); - - /** Sun-specific JDK constructor factory for objects that don't have empty constructor. */ - private static final Method CTOR_FACTORY; - - /** Sun JDK reflection factory. */ - private static final Object SUN_REFLECT_FACTORY; - - /** Public {@code java.lang.Object} no-argument constructor. */ - private static final Constructor OBJECT_CTOR; - - /** All grid event names. */ - private static final Map<Integer, String> GRID_EVT_NAMES = new HashMap<>(); - - /** All grid events. */ - private static final int[] GRID_EVTS; - - /** Empty integers array. */ - private static final int[] EMPTY_INTS = new int[0]; - - /** Empty longs. */ - private static final long[] EMPTY_LONGS = new long[0]; - - /** System line separator. */ - private static final String NL = System.getProperty("line.separator"); - - /** Default user version. */ - public static final String DFLT_USER_VERSION = "0"; - - /** Cache for {@link GridPeerDeployAware} fields to speed up reflection. */ - private static final ConcurrentMap<String, IgniteBiTuple<Class<?>, Collection<Field>>> p2pFields = - new ConcurrentHashMap8<>(); - - /** Secure socket protocol to use. */ - private static final String HTTPS_PROTOCOL = "TLS"; - - /** Project home directory. */ - private static volatile GridTuple<String> ggHome; - - /** Project work directory. */ - private static volatile String ggWork; - - /** OS JDK string. */ - private static String osJdkStr; - - /** OS string. */ - private static String osStr; - - /** JDK string. */ - private static String jdkStr; - - /** Indicates whether current OS is Windows 95. */ - private static boolean win95; - - /** Indicates whether current OS is Windows 98. */ - private static boolean win98; - - /** Indicates whether current OS is Windows NT. */ - private static boolean winNt; - - /** Indicates whether current OS is Windows Vista. */ - private static boolean winVista; - - /** Indicates whether current OS is Windows 7. */ - private static boolean win7; - - /** Indicates whether current OS is Windows 8. */ - private static boolean win8; - - /** Indicates whether current OS is Windows 8.1. */ - private static boolean win81; - - /** Indicates whether current OS is some version of Windows. */ - private static boolean unknownWin; - - /** Indicates whether current OS is Windows 2000. */ - private static boolean win2k; - - /** Indicates whether current OS is Windows XP. */ - private static boolean winXp; - - /** Indicates whether current OS is Windows Server 2003. */ - private static boolean win2003; - - /** Indicates whether current OS is Windows Server 2008. */ - private static boolean win2008; - - /** Indicates whether current OS is UNIX flavor. */ - private static boolean unix; - - /** Indicates whether current OS is Solaris. */ - private static boolean solaris; - - /** Indicates whether current OS is Linux flavor. */ - private static boolean linux; - - /** Indicates whether current OS is NetWare. */ - private static boolean netware; - - /** Indicates whether current OS is Mac OS. */ - private static boolean mac; - - /** Indicates whether current OS architecture is Sun Sparc. */ - private static boolean sparc; - - /** Indicates whether current OS architecture is Intel X86. */ - private static boolean x86; - - /** Name of the underlying OS. */ - private static String osName; - - /** Version of the underlying OS. */ - private static String osVer; - - /** CPU architecture of the underlying OS. */ - private static String osArch; - - /** Name of the Java Runtime. */ - private static String javaRtName; - - /** Name of the Java Runtime version. */ - private static String javaRtVer; - - /** Name of the JDK vendor. */ - private static String jdkVendor; - - /** Name of the JDK. */ - private static String jdkName; - - /** Version of the JDK. */ - private static String jdkVer; - - /** Name of JVM specification. */ - private static String jvmSpecName; - - /** Version of JVM implementation. */ - private static String jvmImplVer; - - /** Vendor's name of JVM implementation. */ - private static String jvmImplVendor; - - /** Name of the JVM implementation. */ - private static String jvmImplName; - - /** JMX domain as 'xxx.gridgain'. */ - public static final String JMX_DOMAIN = GridUtils.class.getName().substring(0, GridUtils.class.getName(). - indexOf('.', GridUtils.class.getName().indexOf('.') + 1)); - - /** Network packet header. */ - public static final byte[] GG_HEADER = U.intToBytes(0x00004747); - - /** Default buffer size = 4K. */ - private static final int BUF_SIZE = 4096; - - /** Byte bit-mask. */ - private static final int MASK = 0xf; - - /** Long date format pattern for log messages. */ - private static final SimpleDateFormat LONG_DATE_FMT = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); - - /** - * Short date format pattern for log messages in "quiet" mode. - * Only time is included since we don't expect "quiet" mode to be used - * for longer runs. - */ - private static final SimpleDateFormat SHORT_DATE_FMT = new SimpleDateFormat("HH:mm:ss"); - - /** Debug date format. */ - private static final SimpleDateFormat DEBUG_DATE_FMT = new SimpleDateFormat("HH:mm:ss,SSS"); - - /** Cached local host address to make sure that every time the same local host is returned. */ - private static InetAddress locHost; - - /** */ - static volatile long curTimeMillis = System.currentTimeMillis(); - - /** Primitive class map. */ - private static final Map<String, Class<?>> primitiveMap = new HashMap<>(16, .5f); - - /** Boxed class map. */ - private static final Map<Class<?>, Class<?>> boxedClsMap = new HashMap<>(16, .5f); - - /** Class loader used to load GridGain. */ - private static final ClassLoader gridClassLoader = GridUtils.class.getClassLoader(); - - /** MAC OS invalid argument socket error message. */ - public static final String MAC_INVALID_ARG_MSG = "On MAC OS you may have too many file descriptors open " + - "(simple restart usually solves the issue)"; - - /** Default help pages. */ - public static final List<String> DFLT_HELP_LINKS = Arrays.asList( - "Troubleshooting: http://bit.ly/GridGain-Troubleshooting", - "Documentation Center: http://bit.ly/GridGain-Documentation"); - - /** Portable classes. */ - private static final Collection<Class<?>> PORTABLE_CLS = new HashSet<>(); - - /** GridGain Logging Directory. */ - public static final String GRIDGAIN_LOG_DIR = System.getenv(GG_LOG_DIR); - - /** GridGain Work Directory. */ - public static final String GRIDGAIN_WORK_DIR = System.getenv(GG_WORK_DIR); - - /** Clock timer. */ - private static Thread timer; - - /** Grid counter. */ - private static int gridCnt; - - /** Mutex. */ - private static final Object mux = new Object(); - - /** - * Initializes enterprise check. - */ - static { - String osName = System.getProperty("os.name"); - - String osLow = osName.toLowerCase(); - - // OS type detection. - if (osLow.contains("win")) { - if (osLow.contains("95")) - win95 = true; - else if (osLow.contains("98")) - win98 = true; - else if (osLow.contains("nt")) - winNt = true; - else if (osLow.contains("2000")) - win2k = true; - else if (osLow.contains("vista")) - winVista = true; - else if (osLow.contains("xp")) - winXp = true; - else if (osLow.contains("2003")) - win2003 = true; - else if (osLow.contains("2008")) - win2008 = true; - else if (osLow.contains("7")) - win7 = true; - else if (osLow.contains("8.1")) - win81 = true; - else if (osLow.contains("8")) - win8 = true; - else - unknownWin = true; - } - else if (osLow.contains("netware")) - netware = true; - else if (osLow.contains("mac os")) - mac = true; - else { - // UNIXs flavors tokens. - for (CharSequence os : new String[]{"ix", "inux", "olaris", "un", "ux", "sco", "bsd", "att"}) - if (osLow.contains(os)) { - unix = true; - - break; - } - - // UNIX name detection. - if (osLow.contains("olaris")) - solaris = true; - else if (osLow.contains("inux")) - linux = true; - } - - String osArch = System.getProperty("os.arch"); - - String archStr = osArch.toLowerCase(); - - // OS architecture detection. - if (archStr.contains("x86")) - x86 = true; - else if (archStr.contains("sparc")) - sparc = true; - - String javaRtName = System.getProperty("java.runtime.name"); - String javaRtVer = System.getProperty("java.runtime.version"); - String jdkVendor = System.getProperty("java.specification.vendor"); - String jdkName = System.getProperty("java.specification.name"); - String jdkVer = System.getProperty("java.specification.version"); - String osVer = System.getProperty("os.version"); - String jvmSpecName = System.getProperty("java.vm.specification.name"); - String jvmImplVer = System.getProperty("java.vm.version"); - String jvmImplVendor = System.getProperty("java.vm.vendor"); - String jvmImplName = System.getProperty("java.vm.name"); - - String jdkStr = javaRtName + ' ' + javaRtVer + ' ' + jvmImplVendor + ' ' + jvmImplName + ' ' + - jvmImplVer; - - osStr = osName + ' ' + osVer + ' ' + osArch; - osJdkStr = osLow + ", " + jdkStr; - - // Copy auto variables to static ones. - GridUtils.osName = osName; - GridUtils.jdkName = jdkName; - GridUtils.jdkVendor = jdkVendor; - GridUtils.jdkVer = jdkVer; - GridUtils.jdkStr = jdkStr; - GridUtils.osVer = osVer; - GridUtils.osArch = osArch; - GridUtils.jvmSpecName = jvmSpecName; - GridUtils.jvmImplVer = jvmImplVer; - GridUtils.jvmImplVendor = jvmImplVendor; - GridUtils.jvmImplName = jvmImplName; - GridUtils.javaRtName = javaRtName; - GridUtils.javaRtVer = javaRtVer; - - primitiveMap.put("byte", byte.class); - primitiveMap.put("short", short.class); - primitiveMap.put("int", int.class); - primitiveMap.put("long", long.class); - primitiveMap.put("float", float.class); - primitiveMap.put("double", double.class); - primitiveMap.put("char", char.class); - primitiveMap.put("boolean", boolean.class); - - boxedClsMap.put(byte.class, Byte.class); - boxedClsMap.put(short.class, Short.class); - boxedClsMap.put(int.class, Integer.class); - boxedClsMap.put(long.class, Long.class); - boxedClsMap.put(float.class, Float.class); - boxedClsMap.put(double.class, Double.class); - boxedClsMap.put(char.class, Character.class); - boxedClsMap.put(boolean.class, Boolean.class); - - try { - OBJECT_CTOR = Object.class.getConstructor(); - } - catch (NoSuchMethodException e) { - throw withCause(new AssertionError("Object class does not have empty constructor (is JDK corrupted?)."), e); - } - - // Constructor factory. - Method ctorFac = null; - Object refFac = null; - - try { - Class<?> refFactoryCls = Class.forName("sun.reflect.ReflectionFactory"); - - refFac = refFactoryCls.getMethod("getReflectionFactory").invoke(null); - - ctorFac = refFac.getClass().getMethod("newConstructorForSerialization", Class.class, - Constructor.class); - } - catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException ignored) { - // No-op. - } - - CTOR_FACTORY = ctorFac; - SUN_REFLECT_FACTORY = refFac; - - // Disable hostname SSL verification for development and testing with self-signed certificates. - if (Boolean.parseBoolean(System.getProperty(GG_DISABLE_HOSTNAME_VERIFIER))) { - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - @Override public boolean verify(String hostname, SSLSession sslSes) { - return true; - } - }); - } - - // Event names initialization. - for (Field field : IgniteEventType.class.getFields()) { - if (field.getType().equals(int.class)) { - try { - assert field.getName().startsWith("EVT_") : "Invalid event name (should start with 'EVT_': " + - field.getName(); - - int type = field.getInt(null); - - String prev = GRID_EVT_NAMES.put(type, field.getName().substring(4)); - - // Check for duplicate event types. - assert prev == null : "Duplicate event [type=" + type + ", name1=" + prev + - ", name2=" + field.getName() + ']'; - } - catch (IllegalAccessException e) { - throw new IgniteException(e); - } - } - } - - // Event array initialization. - GRID_EVTS = toIntArray(GRID_EVT_NAMES.keySet()); - - // Sort for fast event lookup. - Arrays.sort(GRID_EVTS); - - // We need to re-initialize EVTS_ALL and EVTS_ALL_MINUS_METRIC_UPDATE - // because they may have been initialized to null before GRID_EVTS were initialized. - if (EVTS_ALL == null || EVTS_ALL_MINUS_METRIC_UPDATE == null) { - try { - Field f1 = IgniteEventType.class.getDeclaredField("EVTS_ALL"); - Field f2 = IgniteEventType.class.getDeclaredField("EVTS_ALL_MINUS_METRIC_UPDATE"); - - assert f1 != null; - assert f2 != null; - - // We use unsafe operations to update static fields on interface because - // they are treated as static final and cannot be updated via standard reflection. - UNSAFE.putObjectVolatile(UNSAFE.staticFieldBase(f1), UNSAFE.staticFieldOffset(f1), gridEvents()); - UNSAFE.putObjectVolatile(UNSAFE.staticFieldBase(f2), UNSAFE.staticFieldOffset(f2), - gridEvents(EVT_NODE_METRICS_UPDATED)); - - assert EVTS_ALL != null; - assert EVTS_ALL.length == GRID_EVTS.length; - - assert EVTS_ALL_MINUS_METRIC_UPDATE != null; - assert EVTS_ALL_MINUS_METRIC_UPDATE.length == GRID_EVTS.length - 1; - - // Validate correctness. - for (int type : GRID_EVTS) { - assert containsIntArray(EVTS_ALL, type); - - if (type != EVT_NODE_METRICS_UPDATED) - assert containsIntArray(EVTS_ALL_MINUS_METRIC_UPDATE, type); - } - - assert !containsIntArray(EVTS_ALL_MINUS_METRIC_UPDATE, EVT_NODE_METRICS_UPDATED); - } - catch (NoSuchFieldException e) { - throw new IgniteException(e); - } - } - - PORTABLE_CLS.add(Byte.class); - PORTABLE_CLS.add(Short.class); - PORTABLE_CLS.add(Integer.class); - PORTABLE_CLS.add(Long.class); - PORTABLE_CLS.add(Float.class); - PORTABLE_CLS.add(Double.class); - PORTABLE_CLS.add(Character.class); - PORTABLE_CLS.add(Boolean.class); - PORTABLE_CLS.add(String.class); - PORTABLE_CLS.add(UUID.class); - PORTABLE_CLS.add(Date.class); - PORTABLE_CLS.add(Timestamp.class); - PORTABLE_CLS.add(byte[].class); - PORTABLE_CLS.add(short[].class); - PORTABLE_CLS.add(int[].class); - PORTABLE_CLS.add(long[].class); - PORTABLE_CLS.add(float[].class); - PORTABLE_CLS.add(double[].class); - PORTABLE_CLS.add(char[].class); - PORTABLE_CLS.add(boolean[].class); - PORTABLE_CLS.add(String[].class); - PORTABLE_CLS.add(UUID[].class); - PORTABLE_CLS.add(Date[].class); - PORTABLE_CLS.add(Timestamp[].class); - } - - /** - * @return System time approximated by 10 ms. - */ - public static long currentTimeMillis() { - return curTimeMillis; - } - - /** - * @return Value of {@link System#nanoTime()} in microseconds. - */ - public static long microTime() { - return System.nanoTime() / 1000; - } - - /** - * Gets nearest power of 2 larger or equal than v. - * - * @param v Value. - * @return Nearest power of 2. - */ - public static int ceilPow2(int v) { - v--; - - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - return ++v; - } - - /** - * @param i Value. - * @return {@code true} If the given value is power of 2 (0 is not power of 2). - */ - public static boolean isPow2(int i) { - return i > 0 && (i & (i - 1)) == 0; - } - - /** - * Return SUN specific constructor factory. - * - * @return SUN specific constructor factory. - */ - @Nullable public static Method ctorFactory() { - return CTOR_FACTORY; - } - - /** - * @return Empty constructor for object class. - */ - public static Constructor objectConstructor() { - return OBJECT_CTOR; - } - - /** - * SUN JDK specific reflection factory for objects without public constructor. - * - * @return Reflection factory for objects without public constructor. - */ - @Nullable public static Object sunReflectionFactory() { - return SUN_REFLECT_FACTORY; - } - - /** - * Gets name for given grid event type. - * - * @param type Event type. - * @return Event name. - */ - public static String gridEventName(int type) { - String name = GRID_EVT_NAMES.get(type); - - return name != null ? name : Integer.toString(type); - } - - /** - * Gets all event types. - * - * @param excl Optional exclude events. - * @return All events minus excluded ones. - */ - public static int[] gridEvents(final int... excl) { - if (F.isEmpty(excl)) - return GRID_EVTS; - - List<Integer> evts = toIntList(GRID_EVTS, new P1<Integer>() { - @Override - public boolean apply(Integer i) { - return !containsIntArray(excl, i); - } - }); - - return toIntArray(evts); - } - - /** - * @param discoSpi Discovery SPI. - * @return {@code True} if ordering is supported. - */ - public static boolean discoOrdered(DiscoverySpi discoSpi) { - DiscoverySpiOrderSupport ann = U.getAnnotation(discoSpi.getClass(), DiscoverySpiOrderSupport.class); - - return ann != null && ann.value(); - } - - /** - * @return Checks if disco ordering should be enforced. - */ - public static boolean relaxDiscoveryOrdered() { - return "true".equalsIgnoreCase(System.getProperty(GG_NO_DISCO_ORDER)); - } - - /** - * This method should be used for adding quick debug statements in code - * while debugging. Calls to this method should never be committed to master. - * - * @param msg Message to debug. - * @deprecated Calls to this method should never be committed to master. - */ - @Deprecated - public static void debug(Object msg) { - X.println(debugPrefix() + msg); - } - - /** - * This method should be used for adding quick debug statements in code - * while debugging. Calls to this method should never be committed to master. - * - * @param msg Message to debug. - * @deprecated Calls to this method should never be committed to master. - */ - @Deprecated - public static void debugx(String msg) { - X.printerrln(debugPrefix() + msg); - } - - /** - * This method should be used for adding quick debug statements in code - * while debugging. Calls to this method should never be committed to master. - * - * @param log Logger. - * @param msg Message to debug. - * - * @deprecated Calls to this method should never be committed to master. - */ - @Deprecated - public static void debug(IgniteLogger log, String msg) { - log.info(msg); - } - - /** - * Prints stack trace of the current thread to {@code System.out}. - * - * @deprecated Calls to this method should never be committed to master. - */ - @SuppressWarnings("deprecation") - @Deprecated - public static void dumpStack() { - dumpStack("Dumping stack."); - } - - /** - * Prints stack trace of the current thread to {@code System.out}. - * - * @param msg Message to print with the stack. - * - * @deprecated Calls to this method should never be committed to master. - */ - @Deprecated - public static void dumpStack(String msg) { - new Exception(debugPrefix() + msg).printStackTrace(System.out); - } - - /** - * @param log Logger. - * @param msg Message. - */ - public static void dumpStack(@Nullable IgniteLogger log, String msg) { - U.error(log, "Dumping stack.", new Exception(msg)); - } - - /** - * Prints stack trace of the current thread to provided output stream. - * - * @param msg Message to print with the stack. - * @param out Output to dump stack to. - * - * @deprecated Calls to this method should never be committed to master. - */ - @Deprecated - public static void dumpStack(String msg, PrintStream out) { - new Exception(msg).printStackTrace(out); - } - - /** - * Prints stack trace of the current thread to provided logger. - * - * @param log Logger. - * @param msg Message to print with the stack. - * - * @deprecated Calls to this method should never be committed to master. - */ - @Deprecated - public static void debugStack(IgniteLogger log, String msg) { - log.error(msg, new Exception(debugPrefix() + msg)); - } - - /** - * @return Common prefix for debug messages. - */ - private static String debugPrefix() { - return '<' + DEBUG_DATE_FMT.format(new Date(System.currentTimeMillis())) + "><DEBUG><" + - Thread.currentThread().getName() + '>' + ' '; - } - - /** - * Prints heap usage. - */ - public static void debugHeapUsage() { - System.gc(); - - Runtime runtime = Runtime.getRuntime(); - - X.println('<' + DEBUG_DATE_FMT.format(new Date(System.currentTimeMillis())) + "><DEBUG><" + - Thread.currentThread().getName() + "> Heap stats [free=" + runtime.freeMemory() / (1024 * 1024) + - "M, total=" + runtime.totalMemory() / (1024 * 1024) + "M]"); - } - - /** - * Gets heap size in GB rounded to specified precision. - * - * @param node Node. - * @param precision Precision. - * @return Heap size in GB. - */ - public static double heapSize(ClusterNode node, int precision) { - return heapSize(Collections.singleton(node), precision); - } - - /** - * Gets total heap size in GB rounded to specified precision. - * - * @param nodes Nodes. - * @param precision Precision. - * @return Total heap size in GB. - */ - public static double heapSize(Iterable<ClusterNode> nodes, int precision) { - // In bytes. - double heap = 0.0; - - for (ClusterNode n : nodesPerJvm(nodes)) { - ClusterMetrics m = n.metrics(); - - heap += Math.max(m.getHeapMemoryInitialized(), m.getHeapMemoryMaximum()); - } - - return roundedHeapSize(heap, precision); - } - - /** - * Returns one representative node for each JVM. - * - * @param nodes Nodes. - * @return Collection which contains only one representative node for each JVM. - */ - private static Iterable<ClusterNode> nodesPerJvm(Iterable<ClusterNode> nodes) { - Map<String, ClusterNode> grpMap = new HashMap<>(); - - // Group by mac addresses and pid. - for (ClusterNode node : nodes) { - String grpId = node.attribute(ATTR_MACS) + "|" + node.attribute(ATTR_JVM_PID); - - if (!grpMap.containsKey(grpId)) - grpMap.put(grpId, node); - } - - return grpMap.values(); - } - - /** - * Returns current JVM maxMemory in the same format as {@link #heapSize(org.apache.ignite.cluster.ClusterNode, int)}. - * - * @param precision Precision. - * @return Maximum memory size in GB. - */ - public static double heapSize(int precision) { - return roundedHeapSize(Runtime.getRuntime().maxMemory(), precision); - } - - /** - * Rounded heap size in gigabytes. - * - * @param heap Heap. - * @param precision Precision. - * @return Rounded heap size. - */ - private static double roundedHeapSize(double heap, int precision) { - double rounded = new BigDecimal(heap / (1024 * 1024 * 1024d)).round(new MathContext(precision)).doubleValue(); - - return rounded < 0.1 ? 0.1 : rounded; - } - - /** - * Performs thread dump and prints all available info to the given log. - * - * @param log Logger. - */ - public static void dumpThreads(@Nullable IgniteLogger log) { - ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); - - ThreadInfo[] threadInfos = - mxBean.dumpAllThreads(mxBean.isObjectMonitorUsageSupported(), mxBean.isSynchronizerUsageSupported()); - - GridStringBuilder sb = new GridStringBuilder("Thread dump at ") - .a(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z").format(new Date(U.currentTimeMillis()))).a(NL); - - for (ThreadInfo info : threadInfos) { - printThreadInfo(info, sb); - - sb.a(NL); - - if (info.getLockedSynchronizers() != null && info.getLockedSynchronizers().length > 0) { - printSynchronizersInfo(info.getLockedSynchronizers(), sb); - - sb.a(NL); - } - } - - sb.a(NL); - - warn(log, sb.toString()); - } - - /** - * Prints single thread info to a buffer. - * - * @param threadInfo Thread info. - * @param sb Buffer. - */ - private static void printThreadInfo(ThreadInfo threadInfo, GridStringBuilder sb) { - sb.a("Thread [name=\"").a(threadInfo.getThreadName()) - .a("\", id=").a(threadInfo.getThreadId()) - .a(", state=").a(threadInfo.getThreadState()) - .a(", blockCnt=").a(threadInfo.getBlockedCount()) - .a(", waitCnt=").a(threadInfo.getWaitedCount()).a("]").a(NL); - - LockInfo lockInfo = threadInfo.getLockInfo(); - - if (lockInfo != null) { - sb.a(" Lock [object=").a(lockInfo) - .a(", ownerName=").a(threadInfo.getLockOwnerName()) - .a(", ownerId=").a(threadInfo.getLockOwnerId()).a("]").a(NL); - } - - MonitorInfo[] monitors = threadInfo.getLockedMonitors(); - StackTraceElement[] elements = threadInfo.getStackTrace(); - - for (int i = 0; i < elements.length; i++) { - StackTraceElement e = elements[i]; - - sb.a(" at ").a(e.toString()); - - for (MonitorInfo monitor : monitors) { - if (monitor.getLockedStackDepth() == i) - sb.a(NL).a(" - locked ").a(monitor); - } - - sb.a(NL); - } - } - - /** - * Prints Synchronizers info to a buffer. - * - * @param syncs Synchronizers info. - * @param sb Buffer. - */ - private static void printSynchronizersInfo(LockInfo[] syncs, GridStringBuilder sb) { - sb.a(" Locked synchronizers:"); - - for (LockInfo info : syncs) - sb.a(NL).a(" ").a(info); - } - - /** - * Gets empty constructor for class even if the class does not have empty constructor - * declared. This method is guaranteed to work with SUN JDK and other JDKs still need - * to be tested. - * - * @param cls Class to get empty constructor for. - * @return Empty constructor if one could be found or {@code null} otherwise. - * @throws IgniteCheckedException If failed. - */ - @Nullable public static Constructor<?> forceEmptyConstructor(Class<?> cls) throws IgniteCheckedException { - Constructor<?> ctor = null; - - try { - return cls.getDeclaredConstructor(); - } - catch (Exception ignore) { - Method ctorFac = U.ctorFactory(); - Object sunRefFac = U.sunReflectionFactory(); - - if (ctorFac != null && sunRefFac != null) - try { - ctor = (Constructor)ctorFac.invoke(sunRefFac, cls, U.objectConstructor()); - } - catch (IllegalAccessException | InvocationTargetException e) { - throw new IgniteCheckedException("Failed to get object constructor for class: " + cls, e); - } - } - - return ctor; - } - - /** - * Creates new instance of a class only if it has an empty constructor (can be non-public). - * - * @param cls Class name. - * @return Instance. - * @throws IgniteCheckedException If failed. - */ - @Nullable public static <T> T newInstance(String cls) throws IgniteCheckedException { - Class<?> cls0; - - try { - cls0 = Class.forName(cls); - } - catch (Exception e) { - throw new IgniteCheckedException(e); - } - - return (T)newInstance(cls0); - } - - /** - * Creates new instance of a class only if it has an empty constructor (can be non-public). - * - * @param cls Class to instantiate. - * @return New instance of the class or {@code null} if empty constructor could not be assigned. - * @throws IgniteCheckedException If failed. - */ - @Nullable public static <T> T newInstance(Class<T> cls) throws IgniteCheckedException { - boolean set = false; - - Constructor<T> ctor = null; - - try { - ctor = cls.getDeclaredConstructor(); - - if (ctor == null) - return null; - - if (!ctor.isAccessible()) { - ctor.setAccessible(true); - - set = true; - } - - return ctor.newInstance(); - } - catch (NoSuchMethodException e) { - throw new IgniteCheckedException("Failed to find empty constructor for class: " + cls, e); - } - catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { - throw new IgniteCheckedException("Failed to create new instance for class: " + cls, e); - } finally { - if (ctor != null && set) - ctor.setAccessible(false); - } - } - - /** - * Creates new instance of a class even if it does not have public constructor. - * - * @param cls Class to instantiate. - * @return New instance of the class or {@code null} if empty constructor could not be assigned. - * @throws IgniteCheckedException If failed. - */ - @SuppressWarnings({"unchecked"}) - @Nullable public static <T> T forceNewInstance(Class<?> cls) throws IgniteCheckedException { - Constructor ctor = forceEmptyConstructor(cls); - - if (ctor == null) - return null; - - boolean set = false; - - try { - - if (!ctor.isAccessible()) { - ctor.setAccessible(true); - - set = true; - } - - return (T)ctor.newInstance(); - } - catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { - throw new IgniteCheckedException("Failed to create new instance for class: " + cls, e); - } finally { - if (set) - ctor.setAccessible(false); - } - } - - /** - * Pretty-formatting for minutes. - * - * @param mins Minutes to format. - * @return Formatted presentation of minutes. - */ - public static String formatMins(long mins) { - assert mins >= 0; - - if (mins == 0) - return "< 1 min"; - - SB sb = new SB(); - - long dd = mins / 1440; // 1440 mins = 60 mins * 24 hours - - if (dd > 0) - sb.a(dd).a(dd == 1 ? " day " : " days "); - - mins %= 1440; - - long hh = mins / 60; - - if (hh > 0) - sb.a(hh).a(hh == 1 ? " hour " : " hours "); - - mins %= 60; - - if (mins > 0) - sb.a(mins).a(mins == 1 ? " min " : " mins "); - - return sb.toString().trim(); - } - - /** - * Gets 8-character substring of UUID (for terse logging). - * - * @param id Input ID. - * @return 8-character ID substring. - */ - public static String id8(UUID id) { - return id.toString().substring(0, 8); - } - - /** - * Gets 8-character substring of {@link org.apache.ignite.lang.IgniteUuid} (for terse logging). - * The ID8 will be constructed as follows: - * <ul> - * <li>Take first 4 digits for global ID, i.e. {@code GridUuid.globalId()}.</li> - * <li>Take last 4 digits for local ID, i.e. {@code GridUuid.localId()}.</li> - * </ul> - * - * @param id Input ID. - * @return 8-character representation of {@code GridUuid}. - */ - public static String id8(IgniteUuid id) { - String s = id.toString(); - - return s.substring(0, 4) + s.substring(s.length() - 4); - } - - /** - * - * @param len Number of characters to fill in. - * @param ch Character to fill with. - * @return String. - */ - public static String filler(int len, char ch) { - char[] a = new char[len]; - - Arrays.fill(a, ch); - - return new String(a); - } - - /** - * Writes array to output stream. - * - * @param out Output stream. - * @param arr Array to write. - * @param <T> Array type. - * @throws IOException If failed. - */ - public static <T> void writeArray(ObjectOutput out, T[] arr) throws IOException { - int len = arr == null ? 0 : arr.length; - - out.writeInt(len); - - if (arr != null && arr.length > 0) - for (T t : arr) - out.writeObject(t); - } - - /** - * Reads array from input stream. - * - * @param in Input stream. - * @return Deserialized array. - * @throws IOException If failed. - * @throws ClassNotFoundException If class not found. - */ - @Nullable public static Object[] readArray(ObjectInput in) throws IOException, ClassNotFoundException { - int len = in.readInt(); - - Object[] arr = null; - - if (len > 0) { - arr = new Object[len]; - - for (int i = 0; i < len; i++) - arr[i] = in.readObject(); - } - - return arr; - } - - /** - * Reads array from input stream. - * - * @param in Input stream. - * @return Deserialized array. - * @throws IOException If failed. - * @throws ClassNotFoundException If class not found. - */ - @Nullable public static Class<?>[] readClassArray(ObjectInput in) throws IOException, ClassNotFoundException { - int len = in.readInt(); - - Class<?>[] arr = null; - - if (len > 0) { - arr = new Class<?>[len]; - - for (int i = 0; i < len; i++) - arr[i] = (Class<?>)in.readObject(); - } - - return arr; - } - - /** - * Reads array from input stream. - * - * @param in Input stream. - * @return Deserialized array. - * @throws IOException If failed. - * @throws ClassNotFoundException If class not found. - */ - @SuppressWarnings("unchecked") - @Nullable public static <K, V> IgnitePredicate<CacheEntry<K, V>>[] readEntryFilterArray(ObjectInput in) - throws IOException, ClassNotFoundException { - int len = in.readInt(); - - IgnitePredicate<CacheEntry<K, V>>[] arr = null; - - if (len > 0) { - arr = new IgnitePredicate[len]; - - for (int i = 0; i < len; i++) - arr[i] = (IgnitePredicate<CacheEntry<K, V>>)in.readObject(); - } - - return arr; - } - - /** - * - * @param out Output. - * @param col Set to write. - * @throws IOException If write failed. - */ - public static void writeCollection(ObjectOutput out, Collection<?> col) throws IOException { - if (col != null) { - out.writeInt(col.size()); - - for (Object o : col) - out.writeObject(o); - } - else - out.writeInt(-1); - } - - /** - * Writes collection of byte arrays to data output. - * - * @param out Output to write to. - * @param bytes Collection with byte arrays. - * @throws IOException If write failed. - */ - public static void writeBytesCollection(DataOutput out, Collection<byte[]> bytes) throws IOException { - if (bytes != null) { - out.writeInt(bytes.size()); - - for (byte[] b : bytes) - writeByteArray(out, b); - } - else - out.writeInt(-1); - } - - /** - * Reads collection of byte arrays from data input. - * - * @param in Data input to read from. - * @return List of byte arrays. - * @throws IOException If read failed. - */ - public static List<byte[]> readBytesList(DataInput in) throws IOException { - int size = in.readInt(); - - if (size < 0) - return null; - - List<byte[]> res = new ArrayList<>(size); - - for (int i = 0; i < size; i++) - res.add(readByteArray(in)); - - return res; - } - - /** - * - * @param out Output. - * @param col Set to write. - * @throws IOException If write failed. - */ - public static void writeIntCollection(DataOutput out, Collection<Integer> col) throws IOException { - if (col != null) { - out.writeInt(col.size()); - - for (Integer i : col) - out.writeInt(i); - } - else - out.writeInt(-1); - } - - /** - * @param in Input. - * @return Deserialized set. - * @throws IOException If deserialization failed. - * @throws ClassNotFoundException If deserialized class could not be found. - */ - @Nullable public static <E> Collection<E> readCollection(ObjectInput in) - throws IOException, ClassNotFoundException { - return readList(in); - } - - /** - * @param in Input. - * @return Deserialized set. - * @throws IOException If deserialization failed. - */ - @Nullable public static Collection<Integer> readIntCollection(DataInput in) throws IOException { - int size = in.readInt(); - - // Check null flag. - if (size == -1) - return null; - - Collection<Integer> col = new ArrayList<>(size); - - for (int i = 0; i < size; i++) - col.add(in.readInt()); - - return col; - } - - /** - * - * @param m Map to copy. - * @param <K> Key type. - * @param <V> Value type - * @return Copied map. - */ - public static <K, V> Map<K, V> copyMap(Map<K, V> m) { - return new HashMap<>(m); - } - - /** - * - * @param m Map to seal. - * @param <K> Key type. - * @param <V> Value type - * @return Sealed map. - */ - public static <K, V> Map<K, V> sealMap(Map<K, V> m) { - assert m != null; - - return Collections.unmodifiableMap(new HashMap<>(m)); - } - - /** - * Seal collection. - * - * @param c Collection to seal. - * @param <E> Entry type - * @return Sealed collection. - */ - public static <E> List<E> sealList(Collection<E> c) { - return Collections.unmodifiableList(new ArrayList<>(c)); - } - - /** - * Convert array to seal list. - * - * @param a Array for convert to seal list. - * @param <E> Entry type - * @return Sealed collection. - */ - public static <E> List<E> sealList(E... a) { - return Collections.unmodifiableList(Arrays.asList(a)); - } - - /** - * Gets display name of the network interface this IP address belongs to. - * - * @param addr IP address for which to find network interface name. - * @return Network interface name or {@code null} if can't be found. - */ - @Nullable public static String getNetworkInterfaceName(String addr) { - assert addr != null; - - try { - InetAddress inetAddr = InetAddress.getByName(addr); - - for (NetworkInterface itf : asIterable(NetworkInterface.getNetworkInterfaces())) - for (InetAddress itfAddr : asIterable(itf.getInetAddresses())) - if (itfAddr.equals(inetAddr)) - return itf.getDisplayName(); - } - catch (UnknownHostException ignore) { - return null; - } - catch (SocketException ignore) { - return null; - } - - return null; - } - - /** - * Tries to resolve host by name, returning local host if input is empty. - * This method reflects how {@link org.apache.ignite.configuration.IgniteConfiguration#getLocalHost()} should - * be handled in most places. - * - * @param hostName Hostname or {@code null} if local host should be returned. - * @return Address of given host or of localhost. - * @throws IOException If attempt to get local host failed. - */ - public static InetAddress resolveLocalHost(@Nullable String hostName) throws IOException { - return F.isEmpty(hostName) ? - // Should default to InetAddress#anyLocalAddress which is package-private. - new InetSocketAddress(0).getAddress() : - InetAddress.getByName(hostName); - } - - /** - * Determines whether current local host is different from previously cached. - * - * @return {@code true} or {@code false} depending on whether or not local host - * has changed from the cached value. - * @throws IOException If attempt to get local host failed. - */ - public static synchronized boolean isLocalHostChanged() throws IOException { - InetAddress locHost0 = locHost; - - return locHost0 != null && !resetLocalHost().equals(locHost0); - } - - /** - * Returns host names consistent with {@link #resolveLocalHost(String)}. So when it returns - * a common address this method returns single host name, and when a wildcard address passed - * this method tries to collect addresses of all available interfaces. - * - * @param locAddr Local address to resolve. - * @return Resolved available addresses of given local address. - * @throws IOException If failed. - * @throws IgniteCheckedException If no network interfaces found. - */ - public static IgniteBiTuple<Collection<String>, Collection<String>> resolveLocalAddresses(InetAddress locAddr) - throws IOException, IgniteCheckedException { - assert locAddr != null; - - Collection<String> addrs = new ArrayList<>(); - Collection<String> hostNames = new ArrayList<>(); - - if (locAddr.isAnyLocalAddress()) { - // It should not take longer than 2 seconds to reach - // local address on any network. - int reachTimeout = 2000; - - for (NetworkInterface itf : asIterable(NetworkInterface.getNetworkInterfaces())) { - for (InetAddress addr : asIterable(itf.getInetAddresses())) { - if (!addr.isLinkLocalAddress() && reachable(itf, addr, reachTimeout)) - addresses(addr, addrs, hostNames); - } - } - - if (F.isEmpty(addrs)) - throw new IgniteCheckedException("No network addresses found (is networking enabled?)."); - } - else - addresses(locAddr, addrs, hostNames); - - return F.t(addrs, hostNames); - } - - /** - * @param addr Address. - * @param addrs Addresses. - * @param hostNames Host names. - */ - private static void addresses(InetAddress addr, Collection<String> addrs, Collection<String> hostNames) { - String hostName = addr.getHostName(); - - String ipAddr = addr.getHostAddress(); - - hostName = F.isEmpty(hostName) || hostName.equals(ipAddr) || addr.isLoopbackAddress() ? "" : hostName; - - addrs.add(ipAddr); - hostNames.add(hostName); - } - - /** - * Gets local host. Implementation will first attempt to get a non-loopback - * address. If that fails, then loopback address will be returned. - * <p> - * Note that this method is synchronized to make sure that local host - * initialization happens only once. - * - * @return Address representing local host. - * @throws IOException If attempt to get local host failed. - */ - public static synchronized InetAddress getLocalHost() throws IOException { - if (locHost == null) - // Cache it. - resetLocalHost(); - - return locHost; - } - - /** - * @return Local host. - * @throws IOException If attempt to get local host failed. - */ - private static synchronized InetAddress resetLocalHost() throws IOException { - locHost = null; - - String sysLocHost = IgniteSystemProperties.getString(GG_LOCAL_HOST); - - if (sysLocHost != null) - sysLocHost = sysLocHost.trim(); - - if (!F.isEmpty(sysLocHost)) - locHost = InetAddress.getByName(sysLocHost); - else { - List<NetworkInterface> itfs = new ArrayList<>(); - - for (NetworkInterface itf : asIterable(NetworkInterface.getNetworkInterfaces())) - itfs.add(itf); - - Collections.sort(itfs, new Comparator<NetworkInterface>() { - @Override public int compare(NetworkInterface itf1, NetworkInterface itf2) { - // Interfaces whose name starts with 'e' should go first. - return itf1.getName().compareTo(itf2.getName()); - } - }); - - // It should not take longer than 2 seconds to reach - // local address on any network. - int reachTimeout = 2000; - - for (NetworkInterface itf : itfs) { - boolean found = false; - - for (InetAddress addr : asIterable(itf.getInetAddresses())) { - if (!addr.isLoopbackAddress() && !addr.isLinkLocalAddress() && reachable(itf, addr, reachTimeout)) { - locHost = addr; - - found = true; - - break; - } - } - - if (found) - break; - } - } - - if (locHost == null) - locHost = InetAddress.getLocalHost(); - - return locHost; - } - - /** - * Checks if address can be reached using three argument InetAddress.isReachable() version. - * - * @param itf Network interface to use for test. - * @param addr Address to check. - * @param reachTimeout Timeout for the check. - * @return {@code True} if address is reachable. - */ - public static boolean reachable(NetworkInterface itf, InetAddress addr, int reachTimeout) { - try { - return addr.isReachable(itf, 0, reachTimeout); - } - catch (IOException ignore) { - return false; - } - } - - /** - * Checks if address can be reached using one argument InetAddress.isReachable() version. - * - * @param addr Address to check. - * @param reachTimeout Timeout for the check. - * @return {@code True} if address is reachable. - */ - public static boolean reachable(InetAddress addr, int reachTimeout) { - try { - return addr.isReachable(reachTimeout); - } - catch (IOException ignore) { - return false; - } - } - - /** - * @param loc Local node. - * @param rmt Remote node. - * @return Whether given nodes have the same macs. - */ - public static boolean sameMacs(ClusterNode loc, ClusterNode rmt) { - assert loc != null; - assert rmt != null; - - String locMacs = loc.attribute(GridNodeAttributes.ATTR_MACS); - String rmtMacs = rmt.attribute(GridNodeAttributes.ATTR_MACS); - - return locMacs != null && locMacs.equals(rmtMacs); - } - - /** - * Gets a list of all local non-loopback IPs known to this JVM. - * Note that this will include both IPv4 and IPv6 addresses (even if one "resolves" - * into another). Loopbacks will be skipped. - * - * @return List of all known local IPs (empty list if no addresses available). - */ - public static synchronized Collection<String> allLocalIps() { - List<String> ips = new ArrayList<>(4); - - try { - Enumeration<NetworkInterface> itfs = NetworkInterface.getNetworkInterfaces(); - - if (itfs != null) { - for (NetworkInterface itf : asIterable(itfs)) { - if (!itf.isLoopback()) { - Enumeration<InetAddress> addrs = itf.getInetAddresses(); - - if (addrs != null) { - for (InetAddress addr : asIterable(addrs)) { - String hostAddr = addr.getHostAddress(); - - if (!addr.isLoopbackAddress() && !ips.contains(hostAddr)) - ips.add(hostAddr); - } - } - } - } - } - } - catch (SocketException ignore) { - return Collections.emptyList(); - } - - Collections.sort(ips); - - return ips; - } - - /** - * Gets a list of all local enabled MACs known to this JVM. It - * is using hardware address of the network interface that is not guaranteed to be - * MAC addresses (but in most cases it is). - * <p> - * Note that if network interface is disabled - its MAC won't be included. All - * local network interfaces are probed including loopbacks. Virtual interfaces - * (sub-interfaces) are skipped. - * <p> - * Note that on linux getHardwareAddress() can return null from time to time - * if NetworkInterface.getHardwareAddress() method is called from many threads. - * - * @return List of all known enabled local MACs or empty list - * if no MACs could be found. - */ - public static synchronized Collection<String> allLocalMACs() { - List<String> macs = new ArrayList<>(3); - - try { - Enumeration<NetworkInterface> itfs = NetworkInterface.getNetworkInterfaces(); - - if (itfs != null) { - for (NetworkInterface itf : asIterable(itfs)) { - byte[] hwAddr = itf.getHardwareAddress(); - - // Loopback produces empty MAC. - if (hwAddr != null && hwAddr.length > 0) { - String mac = byteArray2HexString(hwAddr); - - if (!macs.contains(mac)) - macs.add(mac); - } - } - } - } - catch (SocketException ignore) { - return Collections.emptyList(); - } - - Collections.sort(macs); - - return macs; - } - - /** - * Downloads resource by URL. - * - * @param url URL to download. - * @param file File where downloaded resource should be stored. - * @return File where downloaded resource should be stored. - * @throws IOException If error occurred. - */ - public static File downloadUrl(URL url, File file) throws IOException { - assert url != null; - assert file != null; - - InputStream in = null; - OutputStream out = null; - - try { - URLConnection conn = url.openConnection(); - - if (conn instanceof HttpsURLConnection) { - HttpsURLConnection https = (HttpsURLConnection)conn; - - https.setHostnameVerifier(new DeploymentHostnameVerifier()); - - SSLContext ctx = SSLContext.getInstance(HTTPS_PROTOCOL); - - ctx.init(null, getTrustManagers(), null); - - // Initialize socket factory. - https.setSSLSocketFactory(ctx.getSocketFactory()); - } - - in = conn.getInputStream(); - - if (in == null) - throw new IOException("Failed to open connection: " + url.toString()); - - out = new BufferedOutputStream(new FileOutputStream(file)); - - copy(in, out); - } - catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new IOException("Failed to open HTTPs connection [url=" + url.toString() + ", msg=" + e + ']', e); - } finally { - close(in, null); - close(out, null); - } - - return file; - } - - /** - * Construct array with one trust manager which don't reject input certificates. - * - * @return Array with one X509TrustManager implementation of trust manager. - */ - private static TrustManager[] getTrustManagers() { - return new TrustManager[]{ - new X509TrustManager() { - @Nullable @Override public X509Certificate[] getAcceptedIssuers() { - return null; - } - - @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { - /* No-op. */ - } - - @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { - /* No-op. */ - } - } - }; - } - - /** - * Replace password in URI string with a single '*' character. - * <p> - * Parses given URI by applying ".*://(.*:.*)@.*" - * regular expression pattern and than if URI matches it - * replaces password strings between '/' and '@' with '*'. - * - * @param uri URI which password should be replaced. - * @return Converted URI string - */ - @Nullable public static String hidePassword(@Nullable String uri) { - if (uri == null) - return null; - - if (Pattern.matches(".*://(.*:.*)@.*", uri)) { - int userInfoLastIdx = uri.indexOf('@'); - - assert userInfoLastIdx != -1; - - String str = uri.substring(0, userInfoLastIdx); - - int userInfoStartIdx = str.lastIndexOf('/'); - - str = str.substring(userInfoStartIdx + 1); - - String[] params = str.split(";"); - - StringBuilder builder = new StringBuilder(); - - for (int i = 0; i < params.length; i++) { - int idx; - - if ((idx = params[i].indexOf(':')) != -1) - params[i] = params[i].substring(0, idx + 1) + '*'; - - builder.append(params[i]); - - if (i != params.length - 1) - builder.append(';'); - } - - return new StringBuilder(uri).replace(userInfoStartIdx + 1, userInfoLastIdx, - builder.toString()).toString(); - } - - return uri; - } - - /** - * @return Class loader used to load GridGain itself. - */ - public static ClassLoader gridClassLoader() { - return gridClassLoader; - } - - /** - * @param parent Parent to find. - * @param ldr Loader to check. - * @return {@code True} if parent found. - */ - public static boolean hasParent(@Nullable ClassLoader parent, ClassLoader ldr) { - if (parent != null) { - for (; ldr != null; ldr = ldr.getParent()) { - if (ldr.equals(parent)) - return true; - } - - return false; - } - - return true; - } - - /** - * Verifier always returns successful result for any host. - */ - private static class DeploymentHostnameVerifier implements HostnameVerifier { - /** {@inheritDoc} */ - @Override public boolean verify(String hostname, SSLSession ses) { - // Remote host trusted by default. - return true; - } - } - - /** - * Makes a {@code '+---+'} dash line. - * - * @param len Length of the dash line to make. - * @return Dash line. - */ - public static String dash(int len) { - char[] dash = new char[len]; - - Arrays.fill(dash, '-'); - - dash[0] = dash[len - 1] = '+'; - - return new String(dash); - } - - /** - * Creates space filled string of given length. - * - * @param len Number of spaces. - * @return Space filled string of given length. - */ - public static String pad(int len) { - char[] dash = new char[len]; - - Arrays.fill(dash, ' '); - - return new String(dash); - } - - /** - * Formats system time in milliseconds for printing in logs. - * - * @param sysTime System time. - * @return Formatted time string. - */ - public static String format(long sysTime) { - return LONG_DATE_FMT.format(new java.util.Date(sysTime)); - } - - /** - * Takes given collection, shuffles it and returns iterable instance. - * - * @param <T> Type of elements to create iterator for. - * @param col Collection to shuffle. - * @return Iterable instance over randomly shuffled collection. - */ - public static <T> Iterable<T> randomIterable(Collection<T> col) { - List<T> list = new ArrayList<>(col); - - Collections.shuffle(list); - - return list; - } - - /** - * Converts enumeration to iterable so it can be used in {@code foreach} construct. - * - * @param <T> Types of instances for iteration. - * @param e Enumeration to convert. - * @return Iterable over the given enumeration. - */ - public static <T> Iterable<T> asIterable(final Enumeration<T> e) { - return new Iterable<T>() { - @Override public Iterator<T> iterator() { - return new Iterator<T>() { - @Override public boolean hasNext() { - return e.hasMoreElements(); - } - - @SuppressWarnings({"IteratorNextCanNotThrowNoSuchElementException"}) - @Override public T next() { - return e.nextElement(); - } - - @Override public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - }; - } - - /** - * Copy source file (or folder) to destination file (or folder). Supported source & destination: - * <ul> - * <li>File to File</li> - * <li>File to Folder</li> - * <li>Folder to Folder (Copy the content of the directory and not the directory itself)</li> - * </ul> - * - * @param src Source file or folder. - * @param dest Destination file or folder. - * @param overwrite Whether or not overwrite existing files and folders. - * @throws IOException Thrown if an I/O error occurs. - */ - public static void copy(File src, File dest, boolean overwrite) throws IOException { - assert src != null; - assert dest != null; - - /* - * Supported source & destination: - * =============================== - * 1. File -> File - * 2. File -> Directory - * 3. Directory -> Directory - */ - - // Source must exist. - if (!src.exists()) - throw new FileNotFoundException("Source can't be found: " + src); - - // Check that source and destination are not the same. - if (src.getAbsoluteFile().equals(dest.getAbsoluteFile())) - throw new IOException("Source and destination are the same [src=" + src + ", dest=" + dest + ']'); - - if (dest.exists()) { - if (!dest.isDirectory() && !overwrite) - throw new IOException("Destination already exists: " + dest); - - if (!dest.canWrite()) - throw new IOException("Destination is not writable:" + dest); - } - else { - File parent = dest.getParentFile(); - - if (parent != null && !parent.exists()) - // Ignore any errors here. - // We will get errors when we'll try to open the file stream. - //noinspection ResultOfMethodCallIgnored - parent.mkdirs(); - - // If source is a directory, we should create destination directory. - if (src.isDirectory()) - //noinspection ResultOfMethodCallIgnored - dest.mkdir(); - } - - if (src.isDirectory()) { - // In this case we have Directory -> Directory. - // Note that we copy the content of the directory and not the directory itself. - - File[] files = src.listFiles(); - - for (File file : files) { - if (file.isDirectory()) { - File dir = new File(dest, file.getName()); - - if (!dir.exists() && !dir.mkdirs()) - throw new IOException("Can't create directory: " + dir); - - copy(file, dir, overwrite); - } - else - copy(file, dest, overwrite); - } - } - else { - // In this case we have File -> File or File -> Directory. - File file = dest.exists() && dest.isDirectory() ? new File(dest, src.getName()) : dest; - - if (!overwrite && file.exists()) - throw new IOException("Destination already exists: " + file); - - FileInputStream in = null; - FileOutputStream out = null; - - try { - in = new FileInputStream(src); - out = new FileOutputStream(file); - - copy(in, out); - } - finally { - if (in != null) - in.close(); - - if (out != null) { - out.getFD().sync(); - - out.close(); - } - } - } - } - - /** - * Starts clock timer if grid is first. - */ - public static void onGridStart() { - synchronized (mux) { - if (gridCnt == 0) { - timer = new Thread(new Runnable() { - @SuppressWarnings({"BusyWait", "InfiniteLoopStatement"}) - @Override public void run() { - while (true) { - curTimeMillis = System.currentTimeMillis(); - - try { - Thread.sleep(10); - } - catch (InterruptedException ignored) { - U.log(null, "Timer thread has been interrupted."); - - break; - } - } - } - }, "gridgain-clock"); - - timer.setDaemon(true); - - timer.setPriority(10); - - timer.start(); - } - - ++gridCnt; - } - } - - /** - * Stops clock timer if all nodes into JVM were stopped. - */ - public static void onGridStop(){ - synchronized (mux) { - assert gridCnt > 0 : gridCnt; - - --gridCnt; - - if (gridCnt == 0 && timer != null) { - timer.interrupt(); - - timer = null; - } - } - } - - /** - * Copies input byte stream to output byte stream. - * - * @param in Input byte stream. - * @param out Output byte stream. - * @return Number of the copied bytes. - * @throws IOException Thrown if an I/O error occurs. - */ - public static int copy(InputStream in, OutputStream out) throws IOException { - assert in != null; - assert out != null; - - byte[] buf = new byte[BUF_SIZE]; - - int cnt = 0; - - for (int n; (n = in.read(buf)) > 0;) { - out.write(buf, 0, n); - - cnt += n; - } - - return cnt; - } - - /** - * Copies input character stream to output character stream. - * - * @param in Input character stream. - * @param out Output character stream. - * @return Number of the copied characters. - * @throws IOException Thrown if an I/O error occurs. - */ - public static int copy(Reader in, Writer out) throws IOException { - assert in != null; - assert out != null; - - char[] buf = new char[BUF_SIZE]; - - int cnt = 0; - - for (int n; (n = in.read(buf)) > 0;) { - out.write(buf, 0, n); - - cnt += n; - } - - return cnt; - } - - /** - * Writes string to file. - * - * @param file File. - * @param s String to write. - * @throws IOException Thrown if an I/O error occurs. - */ - public static void writeStringToFile(File file, String s) throws IOException { - writeStringToFile(file, s, Charset.defaultCharset().toString(), false); - } - - /** - * Writes string to file. - * - * @param file File. - * @param s String to write. - * @param charset Encoding. - * @throws IOException Thrown if an I/O error occurs. - */ - public static void writeStringToFile(File file, String s, String charset) throws IOException { - writeStringToFile(file, s, charset, false); - } - - /** - * Reads file to string using specified charset. - * - * @param fileName File name. - * @param charset File charset. - * @return File content. - * @throws IOException If error occurred. - */ - public static String readFileToString(String fileName, String charset) throws IOException { - Reader input = new InputStreamReader(new FileInputStream(fileName), charset); - - StringWriter output = new StringWriter(); - - char[] buf = new char[4096]; - - int n; - - while ((n = input.read(buf)) != -1) - output.write(buf, 0, n); - - return output.toString(); - } - - /** - * Writes string to file. - * - * @param file File. - * @param s String to write. - * @param charset Encoding. - * @param append If {@code true}, then specified string will be added to the end of the file. - * @throws IOException Thrown if an I/O error occurs. - */ - public static void writeStringToFile(File file, String s, String charset, boolean append) throws IOException { - if (s == null) - return; - - OutputStream out = null; - - try { - out = new FileOutputStream(file, append); - - if (s != null) - out.write(s.getBytes(charset)); - } finally { - closeQuiet(out); - } - } - - /** - * Utility method that sets cause into exception and returns it. - * - * @param e Exception to set cause to and return. - * @param cause Optional cause to set (if not {@code null}). - * @param <E> Type of the exception. - * @return Passed in exception with optionally set cause. - */ - public static <E extends Throwable> E withCause(E e, @Nullable Throwable cause) { - assert e != null; - - if (cause != null) - e.initCause(cause); - - return e; - } - - /** - * Deletes file or directory with all sub-directories and files. - * - * @param file File or directory to delete. - * @return {@code true} if and only if the file or directory is successfully deleted, - * {@code false} otherwise - */ - public static boolean delete(File file) { - assert file != null; - - boolean res = true; - - if (file.isDirectory()) { - File[] files = file.listFiles(); - - if (files != null && files.length > 0) - for (File file1 : files) - if (file1.isDirectory()) - res &= delete(file1); - else if (file1.getName().endsWith("jar")) - try { - // Why do we do this? - new JarFile(file1, false).close(); - - res &= file1.delete(); - } - catch (IOException ignore) { - // Ignore it here... - } - else - res &= file1.delete(); - - res &= file.delete(); - } - else - res = file.delete(); - - return res; - } - - /** - * @param dir Directory to create along with all non-existent parent directories. - * @return {@code True} if directory exists (has been created or already existed), - * {@code false} if has not been created and does not exist. - */ - public static boolean mkdirs(File dir) { - assert dir != null; - - return dir.mkdirs() || dir.exists(); - } - - /** - * Resolve project home directory based on source code base. - * - * @return Project home directory (or {@code null} if it cannot be resolved). - */ - @Nullable private static String resolveProjectHome() { - assert Thread.holdsLock(GridUtils.class); - - // Resolve GridGain home via environment variables. - String ggHome0 = IgniteSystemProperties.getString(GG_HOME); - - if (!F.isEmpty(ggHome0)) - return ggHome0; - - String appWorkDir = System.getProperty("user.dir"); - - if (appWorkDir != null) { - ggHome0 = findProjectHome(new File(appWorkDir)); - - if (ggHome0 != null) - return ggHome0; - } - - URI uri; - - Class<GridUtils> cls = GridUtils.class; - - try { - ProtectionDomain domain = cls.getProtectionDomain(); - - // Should not happen, but to make sure our code is not broken. - if (domain == null || domain.getCodeSource() == null || domain.getCodeSource().getLocation() == null) { - logResolveFailed(cls, null); - - return null; - } - - // Resolve path to class-file. - uri = domain.getCodeSource().getLocation().toURI(); - - // Overcome UNC path problem on Windows (http://www.tomergabel.com/JavaMishandlesUNCPathsOnWindows.aspx) - if (isWindows() && uri.getAuthority() != null) - uri = new URI(uri.toString().replace("file://", "file:/")); - } - catch (URISyntaxException | SecurityException e) { - logResolveFailed(cls, e); - - return null; - } - - return findProjectHome(new File(uri)); - } - - /** - * Tries to find project home starting from specified directory and moving to root. - * - * @param startDir First directory in search hierarchy. - * @return Project home path or {@code null} if it wasn't found. - */ - private static String findProjectHome(File startDir) { - for (File cur = startDir.getAbsoluteFile(); cur != null; cur = cur.getParentFile()) { - // Check 'cur' is project home directory. - if (!new File(cur, "bin").isDirectory() || - !new File(cur, "libs").isDirectory() || - !new File(cur, "config").isDirectory()) - continue; - - return cur.getPath(); - } - - return null; - } - - /** - * @param cls Class. - * @param e Exception. - */ - private static void logResolveFailed(Class cls, Exception e) { - warn(null, "Failed to resolve GRIDGAIN_HOME automatically for class codebase " + - "[class=" + cls + (e == null ? "" : ", e=" + e.getMessage()) + ']'); - } - - /** - * Retrieves {@code GRIDGAIN_HOME} property. The property is retrieved from system - * properties or from environment in that order. - * - * @return {@code GRIDGAIN_HOME} property. - */ - @Nullable public static String getGridGainHome() { - GridTuple<String> ggHomeTup = ggHome; - - String ggHome0; - - if (ggHomeTup == null) { - synchronized (GridUtils.class) { - // Double check. - ggHomeTup = ggHome; - - if (ggHomeTup == null) { - // Resolve GridGain installation home directory. - ggHome = F.t(ggHome0 = resolveProjectHome()); - - if (ggHome0 != null) - System.setProperty(GG_HOME, ggHome0); - } - else - ggHome0 = ggHomeTup.get(); - } - } - else - ggHome0 = ggHomeTup.get(); - - return ggHome0; - } - - /** - * @param path GridGain home. May be {@code null}. - */ - public static void setGridGainHome(@Nullable String path) { - GridTuple<String> ggHomeTup = ggHome; - - String ggHome0; - - if (ggHomeTup == null) { - synchronized (GridUtils.class) { - // Double check. - ggHomeTup = ggHome; - - if (ggHomeTup == null) { - if (F.isEmpty(path)) - System.clearProperty(GG_HOME); - else - System.setProperty(GG_HOME, path); - - ggHome = F.t(path); - - return; - } - else - ggHome0 = ggHomeTup.get(); - } - } - else - ggHome0 = ggHomeTup.get(); - - if (ggHome0 != null && !ggHome0.equals(path)) - throw new IgniteException("Failed to set GRIDGAIN_HOME after it has been already resolved " + - "[ggHome=" + ggHome0 + ", newGgHome=" + path + ']'); - } - - /** - * Gets file associated with path. - * <p> - * First check if path is relative to {@code GRIDGAIN_HOME}. - * If not, check if path is absolute. - * If all checks fail, then {@code null} is returned. - * <p> - * See {@link #getGridGainHome()} for information on how {@code GRIDGAIN_HOME} is retrieved. - * - * @param path Path to resolve. - * @return Resolved path as file, or {@code null} if path cannot be resolved. - */ - @Nullable public static File resolveGridGainPath(String path) { - assert path != null; - - /* - * 1. Check relative to GRIDGAIN_HOME specified in configuration, if any. - */ - - String home = getGridGainHome(); - - if (home != null) { - File file = new File(home, path); - - if (file.exists()) - return file; - } - - /* - * 2. Check given path as absolute. - */ - - File file = new File(path); - - if (file.exists()) - return file; - - /* - * 3. Check development path. - */ - - if (home != null) - file = new File(home, "os/" + path); - - return file.exists() ? file : null; - } - - /** - * Gets URL representing the path passed in. First the check is made if path is absolute. - * If not, then the check is made if path is relative to {@code META-INF} folder in classpath. - * If not, then the check is made if path is relative to ${GRIDGAIN_HOME}. - * If all checks fail, - * then {@code null} is returned, otherwise URL representing path is returned. - * <p> - * See {@link #getGridGainHome()} for information on how {@code GRIDGAIN_HOME} is retrieved. - * - * @param path Path to resolve. - * @return Resolved path as URL, or {@code null} if path cannot be resolved. - * @see #getGridGainHome() - */ - @Nullable public static URL resolveGridGainUrl(String path) { - return resolveGridGainUrl(path, true); - } - - /** - * Gets URL representing the path passed in. First the check is made if path is absolute. - * If not, then the check is made if path is relative to {@code META-INF} folder in classpath. - * If not, then the check is made if path is relative to ${GRIDGAIN_HOME}. - * If all checks fail, - * then {@code null} is returned, otherwise URL representing path is returned. - * <p> - * See {@link #getGridGainHome()} for information on how {@code GRIDGAIN_HOME} is retrieved. - * - * @param path Path to resolve. - * @param metaInf Flag to indicate whether META-INF folder should be checked or class path root. - * @return Resolved path as URL, or {@code null} if path cannot be resolved. - * @see #getGridGainHome() - */ - @SuppressWarnings({"UnusedCatchParameter"}) - @Nullable public static URL resolveGridGainUrl(String path, boolean metaInf) { - File f = resolveGridGainPath(path); - - if (f == null) - f = resolveGridGainPath("os/" + path); - - if (f != null) { - try { - // Note: we use that method's chain instead of File.getURL() with due - // Sun bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6179468 - return f.toURI().toURL(); - } - catch (MalformedURLException e) { - // No-op. - } - } - - String locPath = (metaInf ? "META-INF/" : "") + path.replaceAll("\\\\", "/"); - - return Thread.currentThread().getContextClassLoader().getResource(locPath); - } - - /** - * Join byte arrays into single one. - * - * @param bufs list of byte arrays to concatenate. - * @return Concatenated byte's array. - */ - public static byte[] join(byte[]... bufs) { - int size = 0; - for (byte[] buf : bufs) { - size += buf.length; - } - - byte[] res = new byte[size]; - int position = 0; - for (byte[] buf : bufs) { - arrayCopy(buf, 0, res, position, buf.length); - position += buf.length; - } - - return res; - } - - /** - * Converts byte array to formatted string. If calling: - * <pre name="code" class="java"> - * ... - * byte[] data = {10, 20, 30, 40, 50, 60, 70, 80, 90}; - * - * U.byteArray2String(data, "0x%02X", ",0x%02X") - * ... - * </pre> - * the result will be: - * <pre name="code" class="java"> - * ... - * 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50, 0x5A - * ... - * </pre> - * - * @param arr Array of byte. - * @param hdrFmt C-style string format for the first element. - * @param bodyFmt C-style string format for second and following elements, if any. - * @return String with converted bytes. - */ - public static String byteArray2String(byte[] arr, String hdrFmt, String bodyFmt) { - assert arr != null; - assert hdrFmt != null; - assert bodyFmt != null; - - SB sb = new SB(); - - sb.a('{'); - - boolean first = true; - - for (byte b : arr) - if (first) { - sb.a(String.format(hdrFmt, b)); - - first = false; - } - else - sb.a(String.format(bodyFmt, b)); - - sb.a('}'); - - return sb.toString(); - } - - /** - * Converts byte array to hex string. - * - * @param arr Array of bytes. - * @return Hex string. - */ - public static String byteArray2HexString(byte[] arr) { - SB sb = new SB(arr.length << 1); - - for (byte b : arr) - sb.a(Integer.toHexString(MASK & b >>> 4)).a(Integer.toHexString(MASK & b)); - - return sb.toString().toUpperCase(); - } - - /** - * Convert string with hex values to byte array. - * - * @param hex Hexadecimal string to convert. - * @return array of bytes defined as hex in string. - * @throws IllegalArgumentException If input character differs from certain hex characters. - */ - public static byte[] hexString2ByteArray(String hex) throws IllegalArgumentException { - // If Hex string has odd character length. - if (hex.length() % 2 != 0) - hex = '0' + hex; - - char[] chars = hex.toCharArray(); - - byte[] bytes = new byte[chars.length / 2]; - - int byteCnt = 0; - - for (int i = 0; i < chars.length; i += 2) { - int newByte = 0; - - newByte |= hexCharToByte(chars[i]); - - newByte <<= 4; - - newByte |= hexCharToByte(chars[i + 1]); - - bytes[byteCnt] = (byte)newByte; - - byteCnt++; - } - - return bytes; - } - - /** - * Return byte value for certain character. - * - * @param ch Character - * @return Byte value. - * @throws IllegalArgumentException If input character differ from certain hex characters. - */ - @SuppressWarnings({"UnnecessaryFullyQualifiedName", "fallthrough"}) - private static byte hexCharToByte(char ch) throws IllegalArgumentException { - switch (ch) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return (byte)(ch - '0'); - - case 'a': - case 'A': - return 0xa; - - case 'b': - case 'B': - return 0xb; - - case 'c': - case 'C': - return 0xc; - - case 'd': - case 'D': - return 0xd; - - case 'e': - case 'E': - return 0xe; - - case 'f': - case 'F': - return 0xf; - - default: - throw new IllegalArgumentException("Hex decoding wrong input character [character=" + ch + ']'); - } - } - - /** - * Converts primitive double to byte array. - * - * @param d Double to convert. - * @return Byte array. - */ - public static byte[] doubleToBytes(double d) { - return longToBytes(Double.doubleToLongBits(d)); - } - - /** - * Converts primitive {@code double} type to byte array and stores - * it in the specified byte array. - * - * @param d Double to convert. - * @param bytes Array of bytes. - * @param off Offset. - * @return New offset. - */ - public static int doubleToBytes(double d, byte[] bytes, int off) { - return longToBytes(Double.doubleToLongBits(d), bytes, off); - } - - /** - * Converts primitive float to byte array. - * - * @param f Float to convert. - * @return Array of bytes. - */ - public static byte[] floatToBytes(float f) { - return intToBytes(Float.floatToIntBits(f)); - } - - /** - * Converts primitive float to byte array. - * - * @param f Float to convert. - * @param bytes Array of bytes. - * @param off Offset. - * @return New offset. - */ - public static int floatToBytes(float f, byte[] bytes, int off) { - return intToBytes(Float.floatToIntBits(f), bytes, off); - } - - /** - * Converts primitive {@code long} type to byte array. - * - * @param l Long value. - * @return Array of bytes. - */ - public static byte[] longToBytes(long l) { - return GridClientByteUtils.longToBytes(l); - } - - /** - * Converts primitive {@code long} type to byte array and stores it in specified - * byte array. - * - * @param l Long value. - * @param bytes Array of bytes. - * @param off Offset in {@code bytes} array. - * @return Number of bytes overwritten in {@code bytes} array. -
<TRUNCATED>