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

zipkin2.DependencyLink Maven / Gradle / Ivy

There is a newer version: 3.4.2
Show newest version
/*
 * Copyright The OpenZipkin Authors
 * SPDX-License-Identifier: Apache-2.0
 */
package zipkin2;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.util.Locale;
import zipkin2.codec.DependencyLinkBytesDecoder;
import zipkin2.codec.DependencyLinkBytesEncoder;

import static java.nio.charset.StandardCharsets.UTF_8;

/** A dependency link is an edge between two services. */
//@Immutable
public final class DependencyLink implements Serializable { // for Spark and Flink jobs
  private static final long serialVersionUID = 0L;

  public static Builder newBuilder() {
    return new Builder();
  }

  /** The parent service name (caller), {@link Span#localServiceName()} if instrumented. */
  public String parent() {
    return parent;
  }

  /** The chold service name (callee), {@link Span#localServiceName()} if instrumented. */
  public String child() {
    return child;
  }

  /** Total traced calls made from {@link #parent} to {@link #child} */
  public long callCount() {
    return callCount;
  }

  /**
   * {@linkplain #callCount Count of calls} known to be errors (having one {@linkplain Span#tags()
   * tag} named "error").
   */
  public long errorCount() {
    return errorCount;
  }

  public Builder toBuilder() {
    return new Builder(this);
  }

  public static final class Builder {
    String parent, child;
    long callCount, errorCount;

    Builder() {
    }

    Builder(DependencyLink source) {
      this.parent = source.parent;
      this.child = source.child;
      this.callCount = source.callCount;
      this.errorCount = source.errorCount;
    }

    /** @see #parent() */
    public Builder parent(String parent) {
      if (parent == null) throw new NullPointerException("parent == null");
      this.parent = parent.toLowerCase(Locale.ROOT);
      return this;
    }

    /** @see #child() */
    public Builder child(String child) {
      if (child == null) throw new NullPointerException("child == null");
      this.child = child.toLowerCase(Locale.ROOT);
      return this;
    }

    /** @see #callCount() */
    public Builder callCount(long callCount) {
      this.callCount = callCount;
      return this;
    }

    /** @see #errorCount() */
    public Builder errorCount(long errorCount) {
      this.errorCount = errorCount;
      return this;
    }

    public DependencyLink build() {
      String missing = "";
      if (parent == null) missing += " parent";
      if (child == null) missing += " child";
      if (!missing.isEmpty()) throw new IllegalStateException("Missing :" + missing);
      return new DependencyLink(this);
    }
  }

  @Override public String toString() {
    return new String(DependencyLinkBytesEncoder.JSON_V1.encode(this), UTF_8);
  }

  // clutter below mainly due to difficulty working with Kryo which cannot handle AutoValue subclass
  // See https://github.com/openzipkin/zipkin/issues/1879
  final String parent, child;
  final long callCount, errorCount;

  DependencyLink(Builder builder) {
    parent = builder.parent;
    child = builder.child;
    callCount = builder.callCount;
    errorCount = builder.errorCount;
  }

  @Override public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof DependencyLink)) return false;
    DependencyLink that = (DependencyLink) o;
    return parent.equals(that.parent)
      && child.equals(that.child)
      && callCount == that.callCount
      && errorCount == that.errorCount;
  }

  @Override public int hashCode() {
    int h = 1;
    h *= 1000003;
    h ^= parent.hashCode();
    h *= 1000003;
    h ^= child.hashCode();
    h *= 1000003;
    h ^= (int) ((callCount >>> 32) ^ callCount);
    h *= 1000003;
    h ^= (int) ((errorCount >>> 32) ^ errorCount);
    return h;
  }

  // This is an immutable object, and our encoder is faster than java's: use a serialization proxy.
  Object writeReplace() throws ObjectStreamException {
    return new SerializedForm(DependencyLinkBytesEncoder.JSON_V1.encode(this));
  }

  private static final class SerializedForm implements Serializable {
    private static final long serialVersionUID = 0L;

    final byte[] bytes;

    SerializedForm(byte[] bytes) {
      this.bytes = bytes;
    }

    Object readResolve() throws ObjectStreamException {
      try {
        return DependencyLinkBytesDecoder.JSON_V1.decodeOne(bytes);
      } catch (IllegalArgumentException e) {
        throw new StreamCorruptedException(e.getMessage());
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy