All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wavefront.common.Utils Maven / Gradle / Ivy

package com.wavefront.common;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.*;
import java.util.function.Supplier;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.ws.rs.core.Response;
import org.apache.commons.lang.StringUtils;

/**
 * A placeholder class for miscellaneous utility methods.
 *
 * @author [email protected]
 */
public abstract class Utils {

  private static final ObjectMapper JSON_PARSER = new ObjectMapper();
  private static final ResourceBundle buildProps = ResourceBundle.getBundle("build");
  private static final List UUID_SEGMENTS = ImmutableList.of(8, 4, 4, 4, 12);

  private static final Logger log = Logger.getLogger(Utils.class.getCanonicalName());

  /**
   * A lazy initialization wrapper for {@code Supplier}
   *
   * @param supplier {@code Supplier} to lazy-initialize
   * @return lazy wrapped supplier
   */
  public static  Supplier lazySupplier(Supplier supplier) {
    return new Supplier() {
      private volatile T value = null;

      @Override
      public T get() {
        if (value == null) {
          synchronized (this) {
            if (value == null) {
              value = supplier.get();
            }
          }
        }
        return value;
      }
    };
  }

  /**
   * Requires an input uuid string Encoded as 32 hex characters. For example {@code
   * cced093a76eea418ffdc9bb9a6453df3}
   *
   * @param uuid string encoded as 32 hex characters.
   * @return uuid string encoded in 8-4-4-4-12 (rfc4122) format.
   */
  public static String addHyphensToUuid(String uuid) {
    if (uuid.length() != 32) {
      return uuid;
    }
    StringBuilder result = new StringBuilder();
    int startOffset = 0;
    for (Integer segmentLength : UUID_SEGMENTS) {
      result.append(uuid, startOffset, startOffset + segmentLength);
      if (result.length() < 36) {
        result.append('-');
      }
      startOffset += segmentLength;
    }
    return result.toString();
  }

  /**
   * Method converts a string Id to {@code UUID}. This Method specifically converts id's with less
   * than 32 digit hex characters into UUID format (See RFC 4122: A Universally Unique IDentifier
   * (UUID) URN Namespace) by left padding id with Zeroes and adding hyphens. It assumes
   * that if the input id contains hyphens it is already an UUID. Please don't use this method to
   * validate/guarantee your id as an UUID.
   *
   * @param id a string encoded in hex characters.
   * @return a UUID string.
   */
  @Nullable
  public static String convertToUuidString(@Nullable String id) {
    if (id == null || id.contains("-")) {
      return id;
    }
    return addHyphensToUuid(StringUtils.leftPad(id, 32, '0'));
  }

  /**
   * Creates an iterator over values a comma-delimited string.
   *
   * @param inputString input string
   * @return iterator
   */
  @Nonnull
  public static List csvToList(@Nullable String inputString) {
    return inputString == null
        ? Collections.emptyList()
        : Splitter.on(",").omitEmptyStrings().trimResults().splitToList(inputString);
  }

  /**
   * Attempts to retrieve build.version from system build properties.
   *
   * @return build version as string
   */
  public static String getBuildVersion() {
    try {
      return buildProps.getString("build.version");
    } catch (MissingResourceException ex) {
      return "unknown";
    }
  }

  /**
   * Attempts to retrieve build.package from system build properties.
   *
   * @return package as string
   */
  public static String getPackage() {
    try {
      return buildProps.getString("build.package");
    } catch (MissingResourceException ex) {
      return "unknown";
    }
  }

  /**
   * Returns current java runtime version information (name/vendor/version) as a string.
   *
   * @return java runtime version as string
   */
  public static String getJavaVersion() {
    return System.getProperty("java.runtime.name", "(unknown runtime)")
        + " ("
        + System.getProperty("java.vendor", "")
        + ") "
        + System.getProperty("java.version", "(unknown version)");
  }

  /**
   * Makes a best-effort attempt to resolve the hostname for the local host.
   *
   * @return name for localhost
   */
  public static String getLocalHostName() {
    for (String env : Arrays.asList("COMPUTERNAME", "HOSTNAME", "PROXY_HOSTNAME")) {
      String hostname = System.getenv(env);
      if (StringUtils.isNotBlank(hostname)) {
        log.info("Hostname: '" + hostname + "' (detected using '" + env + "' env variable)");
        return hostname;
      }
    }

    try {
      String hostname =
          new BufferedReader(
                  new InputStreamReader(Runtime.getRuntime().exec("hostname").getInputStream()))
              .readLine();
      if (StringUtils.isNotBlank(hostname)) {
        log.info("Hostname: '" + hostname + "' (detected using 'hostname' command)");
        return hostname;
      }
    } catch (IOException e) {
      log.fine("Error running 'hostname' command. " + e.getMessage());
    }

    InetAddress localAddress = null;
    try {
      Enumeration nics = NetworkInterface.getNetworkInterfaces();
      while (nics.hasMoreElements()) {
        NetworkInterface network = nics.nextElement();
        if (!network.isUp() || network.isLoopback()) {
          continue;
        }
        for (Enumeration addresses = network.getInetAddresses();
            addresses.hasMoreElements(); ) {
          InetAddress address = addresses.nextElement();
          if (address.isAnyLocalAddress()
              || address.isLoopbackAddress()
              || address.isMulticastAddress()) {
            continue;
          }
          if (address instanceof Inet4Address) { // prefer ipv4
            localAddress = address;
            break;
          }
          if (localAddress == null) {
            localAddress = address;
          }
        }
      }
    } catch (SocketException ex) {
      // ignore
    }
    if (localAddress != null) {
      String hostname = localAddress.getCanonicalHostName();
      log.info("Hostname: '" + hostname + "' (detected using network interfaces)");
      return hostname;
    }

    log.info("Hostname not detected, using 'localhost')");
    return "localhost";
  }

  /**
   * Check if the HTTP 407/408 response was actually received from Wavefront - if it's a JSON object
   * containing "code" key, with value equal to the HTTP response code, it's most likely from us.
   *
   * @param response Response object.
   * @return whether we consider it a Wavefront response
   */
  public static boolean isWavefrontResponse(@Nonnull Response response) {
    try {
      Status res = JSON_PARSER.readValue(response.readEntity(String.class), Status.class);
      if (res.code == response.getStatus()) {
        return true;
      }
    } catch (Exception ex) {
      // ignore
    }
    return false;
  }

  /**
   * Use this to throw checked exceptions from iterator methods that do not declare that they throw
   * checked exceptions.
   */
  @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
  public static  E throwAny(Throwable t) throws E {
    throw (E) t;
  }

  @JsonIgnoreProperties(ignoreUnknown = true)
  private static class Status {
    @JsonProperty String message;
    @JsonProperty int code;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy