diff options
author | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2019-04-15 14:53:15 +0200 |
---|---|---|
committer | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2019-06-06 13:03:27 +0200 |
commit | 5e326ad275e3f45ebae1e137271f63cb3bdaabe9 (patch) | |
tree | 980ff8021c0b7fd2f2aa09b3f661d03329e2490c /tenant-cd | |
parent | df757401715013727123f58f3b9e1aac6dae7f87 (diff) |
Initial dump
Diffstat (limited to 'tenant-cd')
22 files changed, 596 insertions, 1 deletions
diff --git a/tenant-cd/pom.xml b/tenant-cd/pom.xml index 8907e56762c..99350c332c2 100644 --- a/tenant-cd/pom.xml +++ b/tenant-cd/pom.xml @@ -20,6 +20,12 @@ <dependencies> <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>vespajlib</artifactId> + <version>7-SNAPSHOT</version> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> diff --git a/tenant-cd/src/main/java/ai/vespa/hosted/cd/ProductionTest.java b/tenant-cd/src/main/java/ai/vespa/hosted/cd/ProductionTest.java index a756b665c1a..6cf5fb07f58 100644 --- a/tenant-cd/src/main/java/ai/vespa/hosted/cd/ProductionTest.java +++ b/tenant-cd/src/main/java/ai/vespa/hosted/cd/ProductionTest.java @@ -1,6 +1,23 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.hosted.cd; -public class ProductionTest { +/** + * Tests that verify the health of production deployments of Vespa applications. + * + * These tests are typically run some time after deployment to a production zone, to ensure + * the deployment is still healthy and working as expected. When these tests fail, deployment + * of the tested change is halted until it succeeds, or is superseded by a remedying change. + * + * A typical production test is to verify that a set of metrics, measured by the Vespa + * deployment itself, are within specified parameters, or that some higher-level measure + * of quality, such as engagement among end users of the application, is as expected. + * + * @author jonmv + */ +public interface ProductionTest { + + // Want to verify metrics (Vespa). + // Want to verify external metrics (YAMAS, other). + // May want to verify search gives expected results. } diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Deployment.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Deployment.java new file mode 100644 index 00000000000..02627ae7c9e --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Deployment.java @@ -0,0 +1,16 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * A deployment of a Vespa application, which contains endpoints for document and metrics retrieval. + * + * @author jonmv + */ +public interface Deployment { + + /** Returns an Endpoint in the cluster with the "default" id. */ + Endpoint endpoint(); + + /** Returns an Endpoint in the cluster with the given id. */ + Endpoint endpoint(String id); + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Digest.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Digest.java new file mode 100644 index 00000000000..73b804dc33c --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Digest.java @@ -0,0 +1,28 @@ +package com.yahoo.vespa.tenant.cd; + +import java.util.Set; + +/** + * An immutable report of the outcome of a {@link Feed} sent to a {@link TestEndpoint}. + * + * @author jonmv + */ +public class Digest { + + public Set<DocumentId> created() { + return null; + } + + public Set<DocumentId> updated() { + return null; + } + + public Set<DocumentId> deleted() { + return null; + } + + public Set<DocumentId> failed() { + return null; + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Document.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Document.java new file mode 100644 index 00000000000..acb1ea08623 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Document.java @@ -0,0 +1,16 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * A schema-less representation of a generic Vespa document. + * + * @author jonmv + */ +public class Document { + + + /** Returns a copy of this document, updated with the data in the given document. */ + public Document updatedBy(Document update) { + return null; + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/DocumentId.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/DocumentId.java new file mode 100644 index 00000000000..c4fc7103b05 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/DocumentId.java @@ -0,0 +1,71 @@ +package com.yahoo.vespa.tenant.cd; + +import java.util.Arrays; +import java.util.List; + +/** + * Unique, immutable ID of a Vespa document, which contains information pertinent to its storage. + * + * @author jonmv + */ +public class DocumentId { + + private final String namespace; + private final String documentType; + private final String group; + private final Long number; + private final String userDefined; + + private DocumentId(String namespace, String documentType, String group, Long number, String userDefined) { + this.namespace = namespace; + this.documentType = documentType; + this.group = group; + this.number = number; + this.userDefined = userDefined; + } + + public static DocumentId of(String namespace, String documentType, String id) { + return new DocumentId(requireNonEmpty(namespace), requireNonEmpty(documentType), null, null, requireNonEmpty(id)); + } + + public static DocumentId of(String namespace, String documentType, String group, String id) { + return new DocumentId(requireNonEmpty(namespace), requireNonEmpty(documentType), requireNonEmpty(group), null, requireNonEmpty(id)); + } + + public static DocumentId of(String namespace, String documentType, long number, String id) { + return new DocumentId(requireNonEmpty(namespace), requireNonEmpty(documentType), null, number, requireNonEmpty(id)); + } + + public static DocumentId ofValue(String value) { + List<String> parts = Arrays.asList(value.split(":")); + String id = String.join(":", parts.subList(4, parts.size())); + if ( parts.size() < 5 + || ! parts.get(0).equals("id") + || id.isEmpty() + || ! parts.get(3).matches("((n=\\d+)|(g=\\w+))?")) + throw new IllegalArgumentException("Document id must be on the form" + + " 'id:<namespace>:<document type>:n=<integer>|g=<name>|<empty>:<user defined id>'," + + " but was '" + value + "'."); + + if (parts.get(3).matches("n=\\d+")) + return of(parts.get(1), parts.get(2), Long.parseLong(parts.get(3).substring(2)), id); + if (parts.get(3).matches("g=\\w+")) + return of(parts.get(1), parts.get(2), parts.get(3).substring(2), id); + return of(parts.get(1), parts.get(2), id); + } + + public String asValue() { + return "id:" + namespace + ":" + documentType + ":" + grouper() + ":" + userDefined; + } + + private String grouper() { + return group != null ? group : number != null ? number.toString() : ""; + } + + private static String requireNonEmpty(String string) { + if (string.isEmpty()) + throw new IllegalArgumentException("The empty string is not allowed."); + return string; + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Endpoint.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Endpoint.java new file mode 100644 index 00000000000..e238d38112b --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Endpoint.java @@ -0,0 +1,21 @@ +package com.yahoo.vespa.tenant.cd; + +import com.yahoo.vespa.tenant.cd.metrics.Metrics; + +/** + * An endpoint in a Vespa application {@link Deployment}, which allows document and metrics retrieval. + * + * The endpoint translates {@link Query}s to {@link Search}s, and {@link Selection}s to {@link Visit}s. + * It also supplies {@link Metrics}. + * + * @author jonmv + */ +public interface Endpoint { + + Search search(Query query); + + Visit visit(Selection selection); + + Metrics metrics(); + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Feed.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Feed.java new file mode 100644 index 00000000000..0b6b1702c80 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Feed.java @@ -0,0 +1,25 @@ +package com.yahoo.vespa.tenant.cd; + +import java.util.Map; +import java.util.Set; + +/** + * An immutable set of document feed / update / delete operations, which can be sent to a Vespa {@link TestEndpoint}. + * + * @author jonmv + */ +public class Feed { + + Map<DocumentId, Document> creations() { + return null; + } + + Map<DocumentId, Document> updates() { + return null; + } + + Set<DocumentId> deletions() { + return null; + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/FunctionalTest.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/FunctionalTest.java new file mode 100644 index 00000000000..3c48e2d32f0 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/FunctionalTest.java @@ -0,0 +1,31 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * Tests that compare the behaviour of a Vespa application deployment against a fixed specification. + * + * These tests are run whenever a change is pushed to a Vespa application, and whenever the Vespa platform + * is upgraded, and before any deployments to production zones. When these tests fails, the tested change to + * the Vespa application is not rolled out. + * + * A typical functional test is to feed some documents, optionally verifying that the documents have been processed + * as expected, and then to see that queries give the expected results. Another common use is to verify integration + * with external services. + * + * @author jonmv + */ +public interface FunctionalTest { + + // Want to feed some documents. + // Want to verify document processing and routing is as expected. + // Want to check recall on those documents. + // Want to verify queries give expected documents. + // Want to verify searchers. + // Want to verify updates. + // Want to verify deletion. + // May want to verify reprocessing. + // Must likely delete documents between tests. + // Must be able to feed documents, setting route. + // Must be able to search. + // Must be able to visit. + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Query.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Query.java new file mode 100644 index 00000000000..e7b6baa1406 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Query.java @@ -0,0 +1,10 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * An immutable query to send to a Vespa {@link Endpoint}, to receive a {@link Search}. + * + * @author jonmv + */ +public class Query { + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Search.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Search.java new file mode 100644 index 00000000000..c53553628d9 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Search.java @@ -0,0 +1,24 @@ +package com.yahoo.vespa.tenant.cd; + +import java.util.SortedMap; + +/** + * The immutable result of sending a {@link Query} to a Vespa {@link Endpoint}. + * + * @author jonmv + */ +public class Search { + + // hits + // coverage + // searched + // full? + // results? + // resultsFull? + + /** Returns the documents that were returned as the result, with an iteration order of decreasing relevance. */ + SortedMap<DocumentId, Document> documents() { + return null; + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Selection.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Selection.java new file mode 100644 index 00000000000..b06ac67950a --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Selection.java @@ -0,0 +1,10 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * A document selection expression, used for streaming search and visit against a {@link Endpoint}. + * + * @author jonmv + */ +public class Selection { + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/TestDeployment.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/TestDeployment.java new file mode 100644 index 00000000000..21bae8545e4 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/TestDeployment.java @@ -0,0 +1,14 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * A deployment of a Vespa application, which also contains endpoints for document manipulation. + * + * @author jonmv + */ +public interface TestDeployment extends Deployment { + + TestEndpoint endpoint(); + + TestEndpoint endpoint(String id); + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/TestEndpoint.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/TestEndpoint.java new file mode 100644 index 00000000000..479ae1d17d2 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/TestEndpoint.java @@ -0,0 +1,15 @@ +package com.yahoo.vespa.tenant.cd; + +import java.util.concurrent.Future; + +/** + * An endpoint in a Vespa application {@link TestDeployment}, which also translates {@link Feed}s to {@link Digest}s. + * + * @author jonmv + */ +public interface TestEndpoint extends Endpoint { + + /** Sends the given Feed to this TestEndpoint, blocking until it is digested, and returns a feed report. */ + Digest digest(Feed feed); + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/UpgradeTest.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/UpgradeTest.java new file mode 100644 index 00000000000..329e58b5a89 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/UpgradeTest.java @@ -0,0 +1,23 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * Tests that assert continuity of behaviour for Vespa application deployments, through upgrades. + * + * These tests are run whenever a change is pushed to a Vespa application, and whenever the Vespa platform + * is upgraded, and before any deployments to production zones. When these tests fails, the tested change to + * the Vespa application is not rolled out. + * + * A typical upgrade test is to do some operations against a test deployment prior to upgrade, like feed and + * search for some documents, perhaps recording some metrics from the deployment, and then to upgrade it, + * repeat the exercise, and compare the results from pre and post upgrade. + * + * TODO Split in platform upgrades and application upgrades? + * + * @author jonmv + */ +public interface UpgradeTest { + + // Want to verify documents are not damaged by upgrade. + // May want to verify metrics during upgrade. + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Visit.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Visit.java new file mode 100644 index 00000000000..3e36b9434aa --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/Visit.java @@ -0,0 +1,17 @@ +package com.yahoo.vespa.tenant.cd; + +import java.util.Map; + +/** + * A stateful visit operation against a {@link Endpoint}. + * + * @author jonmv + */ +public class Visit { + + // Delegate to a blocking iterator, which can be used for iteration as visit is ongoing. + public Map<DocumentId, Document> documents() { + return null; + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/VisitEndpoint.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/VisitEndpoint.java new file mode 100644 index 00000000000..6eb4df625aa --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/VisitEndpoint.java @@ -0,0 +1,10 @@ +package com.yahoo.vespa.tenant.cd; + +/** + * A remote endpoint in a Vespa application {@link Deployment}, which translates {@link Selection}s to {@link Visit}s. + * + * @author jonmv + */ +public interface VisitEndpoint { + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/http/HttpEndpoint.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/http/HttpEndpoint.java new file mode 100644 index 00000000000..c736244e7a8 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/http/HttpEndpoint.java @@ -0,0 +1,9 @@ +package com.yahoo.vespa.tenant.cd.http; + +import java.net.http.HttpClient; + +public class HttpEndpoint { + + HttpClient client = HttpClient.newBuilder().build(); + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Metric.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Metric.java new file mode 100644 index 00000000000..5da4c3fb750 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Metric.java @@ -0,0 +1,74 @@ +package com.yahoo.vespa.tenant.cd.metrics; + +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.StringJoiner; + +import static java.util.Map.copyOf; +import static java.util.stream.Collectors.toUnmodifiableMap; + +/** + * A set of statistics for a metric, for points over a String-indexed space. + * + * @author jonmv + */ +public class Metric { + + private final Map<Map<String, ?>, Statistic> statistics; + + private Metric(Map<Map<String, ?>, Statistic> statistics) { + this.statistics = copyOf(statistics); + } + + /** Creates a new Metric with a copy of the given data. */ + public static Metric of(Map<Map<String, ?>, Statistic> data) { + if (data.isEmpty()) + throw new IllegalArgumentException("No data given."); + + Set<String> dimensions = data.keySet().iterator().next().keySet(); + for (Map<String, ?> point : data.keySet()) { + if (point.keySet().contains(null)) + throw new IllegalArgumentException("Dimensions may not be null: '" + point.keySet() + "'."); + + if ( ! point.keySet().equals(dimensions)) + throw new IllegalArgumentException("Given data has inconsistent dimensions: '" + dimensions + "' vs '" + point.keySet() + "'."); + + if (point.values().contains(null)) + throw new IllegalArgumentException("Position along a dimension may not be null: '" + point + "'."); + } + + return new Metric(data); + } + + /** Returns a Metric view of the subset of points in the given hyperplane; its dimensions must be a subset of those of this Metric. */ + public Metric at(Map<String, ?> hyperplane) { + return new Metric(statistics.keySet().stream() + .filter(point -> point.entrySet().containsAll(hyperplane.entrySet())) + .collect(toUnmodifiableMap(point -> point, statistics::get))); + } + + /** If this Metric contains a single point, returns the Statistic of that point; otherwise, throws an exception. */ + public Statistic statistic() { + if (statistics.size() == 1) + return statistics.values().iterator().next(); + + if (statistics.isEmpty()) + throw new NoSuchElementException("This Metric has no data."); + + throw new IllegalStateException("This Metric has more than one point of data."); + } + + /** Returns the underlying, unmodifiable Map. */ + public Map<Map<String, ?>, Statistic> asMap() { + return statistics; + } + + @Override + public String toString() { + return new StringJoiner(", ", Metric.class.getSimpleName() + "[", "]") + .add("statistics=" + statistics) + .toString(); + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Metrics.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Metrics.java new file mode 100644 index 00000000000..c080d82a343 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Metrics.java @@ -0,0 +1,76 @@ +package com.yahoo.vespa.tenant.cd.metrics; + +import com.yahoo.vespa.tenant.cd.Endpoint; + +import java.time.Instant; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.StringJoiner; + +import static java.util.Map.copyOf; + +/** + * Metrics from a Vespa application {@link Endpoint}, indexed by their names, and optionally by a set of custom dimensions. + * + * Metrics are collected from the <a href="https://docs.vespa.ai/documentation/reference/metrics-health-format.html>metrics</a> + * API of a Vespa endpoint, and contain the current health status of the endpoint, values for all configured metrics in + * that endpoint, and the time interval from which these metrics were sampled. + * + * Each metric is indexed by a name, and, optionally, along a custom set of dimensions, given by a {@code Map<String, String>}. + * + * @author jonmv + */ +public class Metrics { + + private final Instant start, end; + private final Map<String, Metric> metrics; + + private Metrics(Instant start, Instant end, Map<String, Metric> metrics) { + this.start = start; + this.end = end; + this.metrics = copyOf(metrics); + } + + public static Metrics of(Instant start, Instant end, Map<String, Metric> metrics) { + if (metrics.containsKey(null) || metrics.containsValue(null)) + throw new IllegalArgumentException("Metrics may not contain null keys or values: '" + metrics + "'."); + + if ( ! start.isBefore(end)) + throw new IllegalArgumentException("Given time interval must be positive: '" + start + "' to '" + end + "'."); + + return new Metrics(start, end, metrics); + } + + /** Returns the start of the time window from which these metrics were sampled, or throws if the status is {@code Status.down}. */ + public Instant start() { + return start; + } + + /** Returns the end of the time window from which these metrics were sampled, or throws if the status is {@code Status.down}. */ + public Instant end() { + return end; + } + + /** Returns the metric with the given name, or throws a NoSuchElementException if no such Metric is known. */ + public Metric get(String name) { + if ( ! metrics.containsKey(name)) + throw new NoSuchElementException("No metric with name '" + name + "'."); + + return metrics.get(name); + } + + /** Returns the underlying, unmodifiable Map. */ + public Map<String, Metric> asMap() { + return metrics; + } + + @Override + public String toString() { + return new StringJoiner(", ", Metrics.class.getSimpleName() + "[", "]") + .add("start=" + start) + .add("end=" + end) + .add("metrics=" + metrics) + .toString(); + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Statistic.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Statistic.java new file mode 100644 index 00000000000..65c6dc3ed3f --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Statistic.java @@ -0,0 +1,50 @@ +package com.yahoo.vespa.tenant.cd.metrics; + +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.StringJoiner; + +import static java.util.Map.copyOf; + +/** + * Known statistic about a metric, at a certain point. + * + * @author jonmv + */ +public class Statistic { + + private final Map<Type, Double> data; + + /** Creates a new Statistic with a copy of the given data. */ + private Statistic(Map<Type, Double> data) { + this.data = copyOf(data); + } + + public static Statistic of(Map<Type, Double> data) { + if (data.containsKey(null) || data.containsValue(null)) + throw new IllegalArgumentException("Data may not contain null keys or values: '" + data + "'."); + + return new Statistic(data); + } + + /** Returns the value of the given type, or throws a NoSuchElementException if this isn't known. */ + public double get(Type key) { + if ( ! data.containsKey(key)) + throw new NoSuchElementException("No value with key '" + key + "' is known."); + + return data.get(key); + } + + /** Returns the underlying, unmodifiable Map. */ + public Map<Type, Double> asMap() { + return data; + } + + @Override + public String toString() { + return new StringJoiner(", ", Statistic.class.getSimpleName() + "[", "]") + .add("data=" + data) + .toString(); + } + +} diff --git a/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Type.java b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Type.java new file mode 100644 index 00000000000..b8b168cc649 --- /dev/null +++ b/tenant-cd/src/main/java/com/yahoo/vespa/tenant/cd/metrics/Type.java @@ -0,0 +1,32 @@ +package com.yahoo.vespa.tenant.cd.metrics; + +/** + * Known statistic types. + */ +public enum Type { + + /** 95th percentile measurement. */ + percentile95, + + /** 99th percentile measurement. */ + percentile99, + + /** Average over all measurements. */ + average, + + /** Number of measurements. */ + count, + + /** Last measurement. */ + last, + + /** Maximum measurement. */ + max, + + /** Minimum measurement. */ + min, + + /** Number of measurements per second. */ + rate; + +} |