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

zipkin2.storage.cassandra.CassandraStorageBuilder 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.storage.cassandra;

import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
import com.datastax.oss.driver.api.core.config.DriverOption;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import zipkin2.internal.Nullable;
import zipkin2.storage.QueryRequest;
import zipkin2.storage.StorageComponent;

import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_MAX_REQUESTS;
import static com.datastax.oss.driver.api.core.config.DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE;

abstract class CassandraStorageBuilder>
  extends StorageComponent.Builder {

  CassandraStorage.SessionFactory sessionFactory = CassandraStorage.SessionFactory.DEFAULT;
  boolean strictTraceId = true, searchEnabled = true;
  Set autocompleteKeys = Set.of();
  int autocompleteTtl = (int) TimeUnit.HOURS.toMillis(1);
  int autocompleteCardinality = 5 * 4000; // Ex. 5 site tags with cardinality 4000 each

  String contactPoints = "localhost";
  // Driver v4 requires this, so take a guess! When we are wrong, the user can override anyway
  String localDc = "datacenter1";
  @Nullable String username, password;
  boolean useSsl = false;
  boolean sslHostnameValidation = true;

  String keyspace;
  BiFunction ensureSchema = Schema::ensure;

  int maxTraceCols = 100_000;
  int indexFetchMultiplier = 3;

  // Zipkin collectors can create out a lot of async requests in bursts, so we
  // increase some properties beyond the norm.
  /** @see DefaultDriverOption#CONNECTION_POOL_LOCAL_SIZE */
  // Ported from java-driver v3 PoolingOptions.setMaxConnectionsPerHost(HostDistance.LOCAL, 8)
  int poolLocalSize = 8;
  /** @see DefaultDriverOption#CONNECTION_MAX_REQUESTS */
  // Ported from java-driver v3 PoolingOptions.setMaxQueueSize(40960)
  final int maxRequestsPerConnection = 40960 / poolLocalSize;

  Map poolingOptions() {
    Map result = new LinkedHashMap<>();
    result.put(CONNECTION_POOL_LOCAL_SIZE, poolLocalSize);
    result.put(CONNECTION_MAX_REQUESTS, maxRequestsPerConnection);
    return result;
  }

  CassandraStorageBuilder(String defaultKeyspace) {
    keyspace = defaultKeyspace;
  }

  @Override public B strictTraceId(boolean strictTraceId) {
    this.strictTraceId = strictTraceId;
    return (B) this;
  }

  @Override public B searchEnabled(boolean searchEnabled) {
    this.searchEnabled = searchEnabled;
    return (B) this;
  }

  @Override public B autocompleteKeys(List keys) {
    if (keys == null) throw new NullPointerException("keys == null");
    this.autocompleteKeys = Set.copyOf(keys);
    return (B) this;
  }

  @Override public B autocompleteTtl(int autocompleteTtl) {
    if (autocompleteTtl <= 0) throw new IllegalArgumentException("autocompleteTtl <= 0");
    this.autocompleteTtl = autocompleteTtl;
    return (B) this;
  }

  @Override public B autocompleteCardinality(int autocompleteCardinality) {
    if (autocompleteCardinality <= 0) {
      throw new IllegalArgumentException("autocompleteCardinality <= 0");
    }
    this.autocompleteCardinality = autocompleteCardinality;
    return (B) this;
  }

  /**
   * Comma separated list of host addresses part of Cassandra cluster. You can also specify a custom
   * port with 'host:port'. Defaults to localhost on port 9042 *
   */
  public B contactPoints(String contactPoints) {
    if (contactPoints == null) throw new NullPointerException("contactPoints == null");
    this.contactPoints = contactPoints;
    return (B) this;
  }

  /**
   * Name of the datacenter that will be considered "local" for latency load balancing. When unset,
   * load-balancing is round-robin.
   */
  public B localDc(String localDc) {
    if (localDc == null) throw new NullPointerException("localDc == null");
    this.localDc = localDc;
    return (B) this;
  }

  /** Max pooled connections per datacenter-local host. Defaults to 8 */
  public B maxConnections(int maxConnections) {
    if (maxConnections <= 0) throw new IllegalArgumentException("maxConnections <= 0");
    this.poolLocalSize = maxConnections;
    return (B) this;
  }

  /** Will throw an exception on startup if authentication fails. No default. */
  public B username(@Nullable String username) {
    this.username = username;
    return (B) this;
  }

  /** Will throw an exception on startup if authentication fails. No default. */
  public B password(@Nullable String password) {
    this.password = password;
    return (B) this;
  }

  /** Use ssl for connection. Defaults to false. */
  public B useSsl(boolean useSsl) {
    this.useSsl = useSsl;
    return (B) this;
  }

  /** Controls validation of Cassandra server hostname. Defaults to true. */
  public B sslHostnameValidation(boolean sslHostnameValidation) {
    this.sslHostnameValidation = sslHostnameValidation;
    return (B) this;
  }

  /** Keyspace to store span and index data. Defaults to "zipkin3" */
  public B keyspace(String keyspace) {
    if (keyspace == null) throw new NullPointerException("keyspace == null");
    this.keyspace = keyspace;
    return (B) this;
  }

  /** Override to control how sessions are created. */
  public B sessionFactory(CassandraStorage.SessionFactory sessionFactory) {
    if (sessionFactory == null) throw new NullPointerException("sessionFactory == null");
    this.sessionFactory = sessionFactory;
    return (B) this;
  }

  public B ensureSchema(boolean ensureSchema) {
    if (ensureSchema) {
      this.ensureSchema = Schema::ensure;
    } else {
      this.ensureSchema = Schema::validate;
    }
    return (B) this;
  }

  /**
   * Spans have multiple values for the same id. For example, a client and server contribute to the
   * same span id. When searching for spans by id, the amount of results may be larger than the ids.
   * This defines a threshold which accommodates this situation, without looking for an unbounded
   * number of results.
   */
  public B maxTraceCols(int maxTraceCols) {
    if (maxTraceCols <= 0) throw new IllegalArgumentException("maxTraceCols <= 0");
    this.maxTraceCols = maxTraceCols;
    return (B) this;
  }

  /**
   * How many more index rows to fetch than the user-supplied query limit. Defaults to 3.
   *
   * 

Backend requests will request {@link QueryRequest#limit()} times this factor rows from * Cassandra indexes in attempts to return {@link QueryRequest#limit()} traces. * *

Indexing in cassandra will usually have more rows than trace identifiers due to factors * including table design and collection implementation. As there's no way to DISTINCT out * duplicates server-side, this over-fetches client-side when {@code indexFetchMultiplier} > * 1. */ public B indexFetchMultiplier(int indexFetchMultiplier) { if (indexFetchMultiplier <= 0) throw new IllegalArgumentException("indexFetchMultiplier <= 0"); this.indexFetchMultiplier = indexFetchMultiplier; return (B) this; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy