summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2022-12-07 13:08:29 +0100
committerjonmv <venstad@gmail.com>2022-12-07 13:08:29 +0100
commit529f447bbeaf707a4976b8ec9c45491278ec4857 (patch)
tree71a91dfe51a08fdbd7b768bfe3e5d35fa00afe24
parent304816b9d4876fe33c66cdd8da4f084d32c8df67 (diff)
Store and display reindexing cause
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/Reindexing.java3
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/ClusterControllerTestCase.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationReindexing.java22
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/response/ReindexingResponse.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainer.java5
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabaseTest.java8
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationReindexingTest.java12
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java144
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainerTest.java24
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationReindexing.java21
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java6
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggerer.java3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggererTest.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java2
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java7
20 files changed, 174 insertions, 108 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/Reindexing.java b/config-model-api/src/main/java/com/yahoo/config/model/api/Reindexing.java
index 74b63a56ea6..b1164709bfc 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/Reindexing.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/Reindexing.java
@@ -26,6 +26,9 @@ public interface Reindexing {
/** The relative speed with which to reindex. */
double speed();
+ /** The cause of reindexing for this document type. */
+ String cause();
+
}
Reindexing DISABLED_INSTANCE = new Reindexing() {};
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/ClusterControllerTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/ClusterControllerTestCase.java
index eb77187014f..155d81aabf9 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/ClusterControllerTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/ClusterControllerTestCase.java
@@ -544,5 +544,7 @@ public class ClusterControllerTestCase extends DomBuilderTest {
@Override public boolean enabled() { return true; }
@Override public Instant ready() { return Instant.EPOCH; }
@Override public double speed() { return 1; }
+ @Override public String cause() { return "cause"; }
+
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java
index 34fe8a2159d..438ac7dc9a8 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java
@@ -174,6 +174,7 @@ public class ApplicationCuratorDatabase {
private static final String GENERATION = "generation";
private static final String EPOCH_MILLIS = "epochMillis";
private static final String SPEED = "speed";
+ private static final String CAUSE = "cause";
private static byte[] toBytes(ApplicationReindexing reindexing) {
Cursor root = new Slime().setObject();
@@ -204,6 +205,7 @@ public class ApplicationCuratorDatabase {
private static void setStatus(Cursor statusObject, Status status) {
statusObject.setLong(EPOCH_MILLIS, status.ready().toEpochMilli());
statusObject.setDouble(SPEED, status.speed());
+ statusObject.setString(CAUSE, status.cause());
}
private static ApplicationReindexing fromBytes(byte[] data) {
@@ -225,7 +227,8 @@ public class ApplicationCuratorDatabase {
private static Status getStatus(Inspector statusObject) {
return new Status(Instant.ofEpochMilli(statusObject.field(EPOCH_MILLIS).asLong()),
- statusObject.field(SPEED).valid() ? statusObject.field(SPEED).asDouble() : 0.2);
+ statusObject.field(SPEED).valid() ? statusObject.field(SPEED).asDouble() : 0.2,
+ statusObject.field(CAUSE).asString());
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationReindexing.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationReindexing.java
index 19395b10b2b..f4e1918e6e3 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationReindexing.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationReindexing.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.config.server.application;
import com.yahoo.config.model.api.Reindexing;
+import com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@@ -37,10 +38,10 @@ public class ApplicationReindexing implements Reindexing {
}
/** Returns a copy of this with reindexing for the given document type in the given cluster ready at the given instant. */
- public ApplicationReindexing withReady(String cluster, String documentType, Instant readyAt, double speed) {
+ public ApplicationReindexing withReady(String cluster, String documentType, Instant readyAt, double speed, String cause) {
Cluster current = clusters.getOrDefault(cluster, Cluster.empty());
Cluster modified = new Cluster(current.pending,
- with(documentType, new Status(readyAt, speed), current.ready));
+ with(documentType, new Status(readyAt, speed, cause), current.ready));
return new ApplicationReindexing(enabled, with(cluster, modified, clusters));
}
@@ -172,13 +173,17 @@ public class ApplicationReindexing implements Reindexing {
private final Instant ready;
private final double speed;
+ private final String cause;
- Status(Instant ready, double speed) {
+ Status(Instant ready, double speed, String cause) {
if (speed <= 0 || 10 < speed)
throw new IllegalArgumentException("Reindexing speed must be in (0, 10], but was " + speed);
this.ready = ready.truncatedTo(ChronoUnit.MILLIS);
this.speed = speed;
+ this.cause = cause.isBlank() ? speed < ReindexingMaintainer.SPEED ? "background reindexing, to account for changes in built-in linguistics components"
+ : "reindexing due to a schema change"
+ : cause;
}
@Override
@@ -190,21 +195,26 @@ public class ApplicationReindexing implements Reindexing {
}
@Override
+ public String cause() {
+ return cause;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Status status = (Status) o;
- return Double.compare(status.speed, speed) == 0 && ready.equals(status.ready);
+ return Double.compare(status.speed, speed) == 0 && ready.equals(status.ready) && cause.equals(status.cause);
}
@Override
public int hashCode() {
- return Objects.hash(ready, speed);
+ return Objects.hash(ready, speed, cause);
}
@Override
public String toString() {
- return "ready at " + ready + ", with relative speed " + speed;
+ return cause + ", ready at " + ready + ", with relative speed " + speed;
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
index 8afffd93a29..4d28b58beb3 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
@@ -252,6 +252,7 @@ public class ApplicationHandler extends HttpHandler {
Set<String> clusters = StringUtilities.split(request.getProperty("clusterId"));
Set<String> types = StringUtilities.split(request.getProperty("documentType"));
double speed = Double.parseDouble(Objects.requireNonNullElse(request.getProperty("speed"), "1"));
+ String cause = Objects.requireNonNullElse(request.getProperty("cause"), "reindexing for an unknown reason");
Map<String, Set<String>> reindexed = new TreeMap<>();
Instant now = applicationRepository.clock().instant();
@@ -267,7 +268,7 @@ public class ApplicationHandler extends HttpHandler {
String.join(", ", documentTypes.get(cluster)));
if ( ! indexedOnly || indexedDocumentTypes.get(cluster).contains(type)) {
- reindexing = reindexing.withReady(cluster, type, now, speed);
+ reindexing = reindexing.withReady(cluster, type, now, speed, cause);
reindexed.computeIfAbsent(cluster, __ -> new TreeSet<>()).add(type);
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/response/ReindexingResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/response/ReindexingResponse.java
index 1844b204a63..3ad09ea6345 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/response/ReindexingResponse.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/response/ReindexingResponse.java
@@ -40,6 +40,7 @@ public class ReindexingResponse extends JSONResponse {
private static void setStatus(Cursor object, ApplicationReindexing.Status readyStatus) {
object.setLong("readyMillis", readyStatus.ready().toEpochMilli());
object.setDouble("speed", readyStatus.speed());
+ object.setString("cause", readyStatus.cause());
}
private static void setStatus(Cursor object, ClusterReindexing.Status status) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainer.java
index 99c3ecae62a..05f3f2c6483 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainer.java
@@ -40,7 +40,8 @@ public class ReindexingMaintainer extends ConfigServerMaintainer {
private static final Duration timeout = Duration.ofSeconds(10);
/** Relative reindexing speed. */
- static final double SPEED = 1;
+ public static final double SPEED = 1;
+ static final String CAUSE = "reindexing due to a schema change";
private final ConfigConvergenceChecker convergence;
private final Clock clock;
@@ -96,7 +97,7 @@ public class ReindexingMaintainer extends ConfigServerMaintainer {
for (var cluster : reindexing.clusters().entrySet())
for (var pending : cluster.getValue().pending().entrySet())
if (pending.getValue() <= oldestGeneration.get()) {
- reindexing = reindexing.withReady(cluster.getKey(), pending.getKey(), now, SPEED)
+ reindexing = reindexing.withReady(cluster.getKey(), pending.getKey(), now, SPEED, CAUSE)
.withoutPending(cluster.getKey(), pending.getKey());
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabaseTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabaseTest.java
index eb66e7abd88..cbdb462c35e 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabaseTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabaseTest.java
@@ -9,6 +9,7 @@ import java.time.Instant;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
/**
* @author jonmv
@@ -23,8 +24,11 @@ public class ApplicationCuratorDatabaseTest {
assertEquals(Optional.empty(), db.readReindexingStatus(id));
ApplicationReindexing reindexing = ApplicationReindexing.empty()
- .withPending("one", "a", 10).withReady("two", "b", Instant.ofEpochMilli(2), 0.2)
- .withPending("two", "b", 20).withReady("one", "a", Instant.ofEpochMilli(1), 0.2).withReady("two", "c", Instant.ofEpochMilli(3), 0.2)
+ .withPending("one", "a", 10)
+ .withReady("two", "b", Instant.ofEpochMilli(2), 0.2, "test reindexing")
+ .withPending("two", "b", 20)
+ .withReady("one", "a", Instant.ofEpochMilli(1), 0.2, "test reindexing")
+ .withReady("two", "c", Instant.ofEpochMilli(3), 0.2, "test reindexing")
.enabled(false);
db.writeReindexingStatus(id, reindexing);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationReindexingTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationReindexingTest.java
index 3a19cee6675..80ac28e9dbc 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationReindexingTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationReindexingTest.java
@@ -22,10 +22,10 @@ public class ApplicationReindexingTest {
public void test() {
ApplicationReindexing reindexing = ApplicationReindexing.empty()
.withPending("one", "a", 10)
- .withReady("two", "b", Instant.ofEpochMilli(2), 3)
+ .withReady("two", "b", Instant.ofEpochMilli(2), 3, "test reindexing")
.withPending("two", "b", 20)
- .withReady("one", "a", Instant.ofEpochMilli(1), 1)
- .withReady("two", "a", Instant.ofEpochMilli(3), 2)
+ .withReady("one", "a", Instant.ofEpochMilli(1), 1, "test reindexing")
+ .withReady("two", "a", Instant.ofEpochMilli(3), 2, "test reindexing")
.withoutPending("one", "a");
assertEquals(Instant.ofEpochMilli(1),
@@ -51,14 +51,14 @@ public class ApplicationReindexingTest {
assertEquals(Set.of("one", "two"),
reindexing.clusters().keySet());
- assertEquals(Map.of("a", new Status(Instant.ofEpochMilli(1), 1)),
+ assertEquals(Map.of("a", new Status(Instant.ofEpochMilli(1), 1, "test reindexing")),
reindexing.clusters().get("one").ready());
assertEquals(Map.of(),
reindexing.clusters().get("one").pending());
- assertEquals(Map.of("a", new Status(Instant.ofEpochMilli(3), 2),
- "b", new Status(Instant.ofEpochMilli(2), 3)),
+ assertEquals(Map.of("a", new Status(Instant.ofEpochMilli(3), 2, "test reindexing"),
+ "b", new Status(Instant.ofEpochMilli(2), 3, "test reindexing")),
reindexing.clusters().get("two").ready());
assertEquals(Map.of("b", 20L),
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
index d543820fc68..b24d37f29fd 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
@@ -241,37 +241,48 @@ public class ApplicationHandlerTest {
clock.advance(Duration.ofSeconds(1));
reindex(applicationId, "", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar, bax, baz] in 'foo' of application default.default\"}");
- expected = expected.withReady("boo", "bar", clock.instant(), 1).withReady("foo", "bar", clock.instant(), 1).withReady("foo", "baz", clock.instant(), 1).withReady("foo", "bax", clock.instant(), 1);
+ expected = expected.withReady("boo", "bar", clock.instant(), 1, "reindexing for an unknown reason")
+ .withReady("foo", "bar", clock.instant(), 1, "reindexing for an unknown reason")
+ .withReady("foo", "baz", clock.instant(), 1, "reindexing for an unknown reason")
+ .withReady("foo", "bax", clock.instant(), 1, "reindexing for an unknown reason");
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- reindex(applicationId, "?indexedOnly=true", "{\"message\":\"Reindexing document types [bar] in 'foo' of application default.default\"}");
- expected = expected.withReady("foo", "bar", clock.instant(), 1);
+ reindex(applicationId, "?indexedOnly=true&cause=test%20reindexing", "{\"message\":\"Reindexing document types [bar] in 'foo' of application default.default\"}");
+ expected = expected.withReady("foo", "bar", clock.instant(), 1, "test reindexing");
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- expected = expected.withReady("boo", "bar", clock.instant(), 1).withReady("foo", "bar", clock.instant(), 1).withReady("foo", "baz", clock.instant(), 1).withReady("foo", "bax", clock.instant(), 1);
- reindex(applicationId, "?clusterId=", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar, bax, baz] in 'foo' of application default.default\"}");
+ expected = expected.withReady("boo", "bar", clock.instant(), 1, "reindexing")
+ .withReady("foo", "bar", clock.instant(), 1, "reindexing")
+ .withReady("foo", "baz", clock.instant(), 1, "reindexing")
+ .withReady("foo", "bax", clock.instant(), 1, "reindexing");
+ reindex(applicationId, "?clusterId=&cause=reindexing", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar, bax, baz] in 'foo' of application default.default\"}");
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- expected = expected.withReady("boo", "bar", clock.instant(), 1).withReady("foo", "bar", clock.instant(), 1);
- reindex(applicationId, "?documentType=bar", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar] in 'foo' of application default.default\"}");
+ expected = expected.withReady("boo", "bar", clock.instant(), 1, "reindexing")
+ .withReady("foo", "bar", clock.instant(), 1, "reindexing");
+ reindex(applicationId, "?documentType=bar&cause=reindexing", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar] in 'foo' of application default.default\"}");
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- reindex(applicationId, "?clusterId=foo,boo", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar, bax, baz] in 'foo' of application default.default\"}");
- expected = expected.withReady("boo", "bar", clock.instant(), 1).withReady("foo", "bar", clock.instant(), 1).withReady("foo", "baz", clock.instant(), 1).withReady("foo", "bax", clock.instant(), 1);
+ reindex(applicationId, "?clusterId=foo,boo&cause=reindexing", "{\"message\":\"Reindexing document types [bar] in 'boo', [bar, bax, baz] in 'foo' of application default.default\"}");
+ expected = expected.withReady("boo", "bar", clock.instant(), 1, "reindexing")
+ .withReady("foo", "bar", clock.instant(), 1, "reindexing")
+ .withReady("foo", "baz", clock.instant(), 1, "reindexing")
+ .withReady("foo", "bax", clock.instant(), 1, "reindexing");
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- reindex(applicationId, "?clusterId=foo&documentType=bar,baz&speed=0.1", "{\"message\":\"Reindexing document types [bar, baz] in 'foo' of application default.default\"}");
- expected = expected.withReady("foo", "bar", clock.instant(), 0.1).withReady("foo", "baz", clock.instant(), 0.1);
+ reindex(applicationId, "?clusterId=foo&documentType=bar,baz&speed=0.1&cause=reindexing", "{\"message\":\"Reindexing document types [bar, baz] in 'foo' of application default.default\"}");
+ expected = expected.withReady("foo", "bar", clock.instant(), 0.1, "reindexing")
+ .withReady("foo", "baz", clock.instant(), 0.1, "reindexing");
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
@@ -298,7 +309,8 @@ public class ApplicationHandlerTest {
" \"ready\": {" +
" \"bar\": {" +
" \"readyMillis\": " + (now - 1000) + ", " +
- " \"speed\": 1.0" +
+ " \"speed\": 1.0," +
+ " \"cause\": \"reindexing\"" +
" }" +
" }" +
" }," +
@@ -307,15 +319,18 @@ public class ApplicationHandlerTest {
" \"ready\": {" +
" \"bar\": {" +
" \"readyMillis\": " + now + ", " +
- " \"speed\": 0.1" +
+ " \"speed\": 0.1," +
+ " \"cause\": \"reindexing\"" +
" }," +
" \"bax\": {" +
" \"readyMillis\": " + (now - 1000) + ", " +
- " \"speed\": 1.0" +
+ " \"speed\": 1.0," +
+ " \"cause\": \"reindexing\"" +
" }," +
" \"baz\": {" +
" \"readyMillis\": " + now + ", " +
- " \"speed\": 0.1" +
+ " \"speed\": 0.1," +
+ " \"cause\": \"reindexing\"" +
" }" +
" }" +
" }" +
@@ -499,7 +514,7 @@ public class ApplicationHandlerTest {
public void testReindexingSerialization() throws IOException {
Instant now = Instant.ofEpochMilli(123456);
ApplicationReindexing applicationReindexing = ApplicationReindexing.empty()
- .withPending("foo", "bar", 123L).withReady("moo", "baz", now, 1);
+ .withPending("foo", "bar", 123L).withReady("moo", "baz", now, 1, "reindexing");
ClusterReindexing clusterReindexing = new ClusterReindexing(Map.of("bax", new Status(now, null, null, null, null),
"baz", new Status(now.plusSeconds(1),
now.plusSeconds(2),
@@ -514,53 +529,56 @@ public class ApplicationHandlerTest {
applicationReindexing,
Map.of("boo", clusterReindexing,
"moo", clusterReindexing))),
- "{\n" +
- " \"enabled\": true,\n" +
- " \"clusters\": {\n" +
- " \"boo\": {\n" +
- " \"pending\": {},\n" +
- " \"ready\": {\n" +
- " \"bar\": {},\n" +
- " \"bax\": {\n" +
- " \"startedMillis\": 123456\n" +
- " },\n" +
- " \"baz\": {\n" +
- " \"startedMillis\": 124456,\n" +
- " \"endedMillis\": 125456,\n" +
- " \"state\": \"failed\",\n" +
- " \"message\": \"message\",\n" +
- " \"progress\": 0.1\n" +
- " }\n" +
- " }\n" +
- " },\n" +
- " \"foo\": {\n" +
- " \"pending\": {\n" +
- " \"bar\": 123\n" +
- " },\n" +
- " \"ready\": {\n" +
- " \"bar\": {},\n" +
- " \"hax\": {}\n" +
- " }\n" +
- " },\n" +
- " \"moo\": {\n" +
- " \"pending\": {},\n" +
- " \"ready\": {\n" +
- " \"bax\": {\n" +
- " \"startedMillis\": 123456\n" +
- " },\n" +
- " \"baz\": {\n" +
- " \"readyMillis\": 123456,\n" +
- " \"speed\": 1.0,\n" +
- " \"startedMillis\": 124456,\n" +
- " \"endedMillis\": 125456,\n" +
- " \"state\": \"failed\",\n" +
- " \"message\": \"message\",\n" +
- " \"progress\": 0.1\n" +
- " }\n" +
- " }\n" +
- " }\n" +
- " }\n" +
- "}\n");
+ """
+ {
+ "enabled": true,
+ "clusters": {
+ "boo": {
+ "pending": {},
+ "ready": {
+ "bar": {},
+ "bax": {
+ "startedMillis": 123456
+ },
+ "baz": {
+ "startedMillis": 124456,
+ "endedMillis": 125456,
+ "state": "failed",
+ "message": "message",
+ "progress": 0.1
+ }
+ }
+ },
+ "foo": {
+ "pending": {
+ "bar": 123
+ },
+ "ready": {
+ "bar": {},
+ "hax": {}
+ }
+ },
+ "moo": {
+ "pending": {},
+ "ready": {
+ "bax": {
+ "startedMillis": 123456
+ },
+ "baz": {
+ "readyMillis": 123456,
+ "speed": 1.0,
+ "cause": "reindexing",
+ "startedMillis": 124456,
+ "endedMillis": 125456,
+ "state": "failed",
+ "message": "message",
+ "progress": 0.1
+ }
+ }
+ }
+ }
+ }
+ """);
}
@Test
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainerTest.java
index 26edc5d0f71..5a78d81e508 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainerTest.java
@@ -8,6 +8,7 @@ import java.time.Instant;
import java.util.List;
import java.util.Map;
+import static com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer.CAUSE;
import static com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer.SPEED;
import static com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer.withNewReady;
import static com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer.withOnlyCurrentData;
@@ -22,7 +23,10 @@ public class ReindexingMaintainerTest {
public void testReadyComputation() {
ApplicationReindexing reindexing = ApplicationReindexing.empty()
.withPending("one", "a", 10)
- .withPending("two", "b", 20).withReady("one", "a", Instant.ofEpochMilli(3), SPEED).withReady("two", "b", Instant.ofEpochMilli(2), SPEED).withReady("two", "c", Instant.ofEpochMilli(3), SPEED);
+ .withPending("two", "b", 20)
+ .withReady("one", "a", Instant.ofEpochMilli(3), SPEED, CAUSE)
+ .withReady("two", "b", Instant.ofEpochMilli(2), SPEED, CAUSE)
+ .withReady("two", "c", Instant.ofEpochMilli(3), SPEED, CAUSE);
// Nothing happens without convergence.
assertEquals(reindexing,
@@ -31,13 +35,13 @@ public class ReindexingMaintainerTest {
// Status for (one, a) changes, but not (two, b).
Instant later = Instant.ofEpochMilli(3 << 10);
// Converged, no longer pending.
- assertEquals(reindexing.withoutPending("one", "a").withReady("one", "a", later, SPEED), // Converged, now ready.
+ assertEquals(reindexing.withoutPending("one", "a").withReady("one", "a", later, SPEED, CAUSE), // Converged, now ready.
withNewReady(reindexing, () -> 19L, later));
// Converged, no longer pending.
// Converged, no Longer pending.
- assertEquals(reindexing.withoutPending("one", "a").withReady("one", "a", later, SPEED)
- .withoutPending("two", "b").withReady("two", "b", later, SPEED),
+ assertEquals(reindexing.withoutPending("one", "a").withReady("one", "a", later, SPEED, CAUSE)
+ .withoutPending("two", "b").withReady("two", "b", later, SPEED, CAUSE),
withNewReady(reindexing, () -> 20L, later));
// Verify generation supplier isn't called when no pending document types.
@@ -50,7 +54,10 @@ public class ReindexingMaintainerTest {
public void testGarbageRemoval() {
ApplicationReindexing reindexing = ApplicationReindexing.empty()
.withPending("one", "a", 10)
- .withPending("two", "b", 20).withReady("one", "a", Instant.ofEpochMilli(3), SPEED).withReady("two", "b", Instant.ofEpochMilli(2), SPEED).withReady("two", "c", Instant.ofEpochMilli(3), SPEED);
+ .withPending("two", "b", 20)
+ .withReady("one", "a", Instant.ofEpochMilli(3), SPEED, CAUSE)
+ .withReady("two", "b", Instant.ofEpochMilli(2), SPEED, CAUSE)
+ .withReady("two", "c", Instant.ofEpochMilli(3), SPEED, CAUSE);
assertEquals(reindexing,
withOnlyCurrentData(reindexing, Map.of("one", List.of("a", "b", "c", "d"),
@@ -62,10 +69,13 @@ public class ReindexingMaintainerTest {
"two", List.of("b", "c"))));
assertEquals(ApplicationReindexing.empty()
- .withPending("two", "b", 20).withReady("two", "b", Instant.ofEpochMilli(2), SPEED),
+ .withPending("two", "b", 20).withReady("two", "b", Instant.ofEpochMilli(2), SPEED, CAUSE),
withOnlyCurrentData(reindexing, Map.of("two", List.of("a", "b"))));
- assertEquals(ApplicationReindexing.empty().withReady("one", "a", Instant.EPOCH, SPEED).without("one", "a").withReady("two", "c", Instant.ofEpochMilli(3), SPEED),
+ assertEquals(ApplicationReindexing.empty()
+ .withReady("one", "a", Instant.EPOCH, SPEED, CAUSE)
+ .without("one", "a")
+ .withReady("two", "c", Instant.ofEpochMilli(3), SPEED, CAUSE),
withOnlyCurrentData(reindexing, Map.of("one", List.of("c"),
"two", List.of("c"))));
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationReindexing.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationReindexing.java
index 305cd4c802e..d1ecae63f79 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationReindexing.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationReindexing.java
@@ -87,7 +87,7 @@ public class ApplicationReindexing {
@Override
public String toString() {
return "Cluster{" +
- ", pending=" + pending +
+ "pending=" + pending +
", ready=" + ready +
'}';
}
@@ -104,8 +104,9 @@ public class ApplicationReindexing {
private final String message;
private final Double progress;
private final Double speed;
+ private final String cause;
- public Status(Instant readyAt, Instant startedAt, Instant endedAt, State state, String message, Double progress, Double speed) {
+ public Status(Instant readyAt, Instant startedAt, Instant endedAt, State state, String message, Double progress, Double speed, String cause) {
this.readyAt = readyAt;
this.startedAt = startedAt;
this.endedAt = endedAt;
@@ -113,10 +114,11 @@ public class ApplicationReindexing {
this.message = message;
this.progress = progress;
this.speed = speed;
+ this.cause = cause;
}
public Status(Instant readyAt) {
- this(readyAt, null, null, null, null, null, 1.0);
+ this(readyAt, null, null, null, null, null, 1.0, null);
}
public Optional<Instant> readyAt() { return Optional.ofNullable(readyAt); }
@@ -126,18 +128,26 @@ public class ApplicationReindexing {
public Optional<String> message() { return Optional.ofNullable(message); }
public Optional<Double> progress() { return Optional.ofNullable(progress); }
public Optional<Double> speed() { return Optional.ofNullable(speed); }
+ public Optional<String> cause() { return Optional.ofNullable(cause); }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Status status = (Status) o;
- return Objects.equals(readyAt, status.readyAt) && Objects.equals(startedAt, status.startedAt) && Objects.equals(endedAt, status.endedAt) && state == status.state && Objects.equals(message, status.message) && Objects.equals(progress, status.progress) && Objects.equals(speed, status.speed);
+ return Objects.equals(readyAt, status.readyAt) &&
+ Objects.equals(startedAt, status.startedAt) &&
+ Objects.equals(endedAt, status.endedAt) &&
+ state == status.state &&
+ Objects.equals(message, status.message) &&
+ Objects.equals(progress, status.progress) &&
+ Objects.equals(speed, status.speed) &&
+ Objects.equals(cause, status.cause);
}
@Override
public int hashCode() {
- return Objects.hash(readyAt, startedAt, endedAt, state, message, progress, speed);
+ return Objects.hash(readyAt, startedAt, endedAt, state, message, progress, speed, cause);
}
@Override
@@ -150,6 +160,7 @@ public class ApplicationReindexing {
", message='" + message + '\'' +
", progress=" + progress +
", speed=" + speed +
+ ", cause='" + cause + '\'' +
'}';
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
index 119e6794e6c..cc05bc01d99 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
@@ -38,7 +38,7 @@ public interface ConfigServer {
PreparedApplication deploy(DeploymentData deployment);
- void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly, Double speed);
+ void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly, Double speed, String cause);
ApplicationReindexing getReindexing(DeploymentId deployment);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
index 602a53035a6..444a0ea5ac1 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
@@ -210,13 +210,13 @@ public class ApplicationController {
/**
* Triggers reindexing for the given document types in the given clusters, for the given application.
- *
+ * <p>
* If no clusters are given, reindexing is triggered for the entire application; otherwise
* if no documents types are given, reindexing is triggered for all given clusters; otherwise
* reindexing is triggered for the cartesian product of the given clusters and document types.
*/
- public void reindex(ApplicationId id, ZoneId zoneId, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly, Double speed) {
- configServer.reindex(new DeploymentId(id, zoneId), clusterNames, documentTypes, indexedOnly, speed);
+ public void reindex(ApplicationId id, ZoneId zoneId, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly, Double speed, String cause) {
+ configServer.reindex(new DeploymentId(id, zoneId), clusterNames, documentTypes, indexedOnly, speed, cause);
}
/** Returns the reindexing status for the given application in the given zone. */
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggerer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggerer.java
index 1ee13bbd0c0..400673bfd0c 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggerer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggerer.java
@@ -50,7 +50,8 @@ public class ReindexingTriggerer extends ControllerMaintainer {
for (Deployment deployment : deployments)
if ( inWindowOfOpportunity(now, id, deployment.zone())
&& reindexingIsReady(controller().applications().applicationReindexing(id, deployment.zone()), now))
- controller().applications().reindex(id, deployment.zone(), List.of(), List.of(), true, speed);
+ controller().applications().reindex(id, deployment.zone(), List.of(), List.of(), true, speed,
+ "bakground reindexing, to account for changes in built-in linguistics components");
});
return 1.0;
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 001c0b8e522..a10f79d1727 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -2229,7 +2229,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
Double speed = request.hasProperty("speed") ? Double.parseDouble(request.getProperty("speed")) : null;
boolean indexedOnly = request.getBooleanProperty("indexedOnly");
- controller.applications().reindex(id, zone, clusterNames, documentTypes, indexedOnly, speed);
+ controller.applications().reindex(id, zone, clusterNames, documentTypes, indexedOnly, speed, "reindexing triggered by " + requireUserPrincipal(request).getName());
return new MessageResponse("Requested reindexing of " + id + " in " + zone +
(clusterNames.isEmpty() ? "" : ", on clusters " + String.join(", ", clusterNames)) +
(documentTypes.isEmpty() ? "" : ", for types " + String.join(", ", documentTypes)) +
@@ -2281,6 +2281,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
status.message().ifPresent(message -> statusObject.setString("message", message));
status.progress().ifPresent(progress -> statusObject.setDouble("progress", progress));
status.speed().ifPresent(speed -> statusObject.setDouble("speed", speed));
+ status.cause().ifPresent(cause -> statusObject.setString("cause", cause));
}
private static String toString(ApplicationReindexing.State state) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
index c76ed8e8c46..21f76ac4303 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java
@@ -440,7 +440,7 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
}
@Override
- public void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly, Double speed) { }
+ public void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly, Double speed, String cause) { }
@Override
public ApplicationReindexing getReindexing(DeploymentId deployment) {
@@ -453,7 +453,8 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
ApplicationReindexing.State.FAILED,
"(#`д´)ノ",
0.1,
- 1.0)))));
+ 1.0,
+ "test reindexing")))));
}
@Override
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggererTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggererTest.java
index b0601dcd880..ecb5bf167d0 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggererTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggererTest.java
@@ -68,7 +68,7 @@ public class ReindexingTriggererTest {
Map.of("cluster",
new Cluster(Map.of(),
Map.of("type",
- new Status(then, then, null, null, null, null, 1.0)))));
+ new Status(then, then, null, null, null, null, 1.0, null)))));
assertFalse(reindexingIsReady(reindexing, now),
"Should not be ready when reindexing is already running");
@@ -76,7 +76,7 @@ public class ReindexingTriggererTest {
Map.of("cluster",
new Cluster(Map.of("type", 123L),
Map.of("type",
- new Status(then, then, now, null, null, null, 1.0)))));
+ new Status(then, then, now, null, null, null, 1.0, null)))));
assertTrue(reindexingIsReady(reindexing, now),
"Should be ready when reindexing is no longer running");
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 40d96f716ae..f1381ead221 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -630,7 +630,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET to get reindexing status
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindexing", GET)
.userIdentity(USER_ID),
- "{\"enabled\":true,\"clusters\":[{\"name\":\"cluster\",\"pending\":[{\"type\":\"type\",\"requiredGeneration\":100}],\"ready\":[{\"type\":\"type\",\"readyAtMillis\":345,\"startedAtMillis\":456,\"endedAtMillis\":567,\"state\":\"failed\",\"message\":\"(#`д´)ノ\",\"progress\":0.1,\"speed\":1.0}]}]}");
+ "{\"enabled\":true,\"clusters\":[{\"name\":\"cluster\",\"pending\":[{\"type\":\"type\",\"requiredGeneration\":100}],\"ready\":[{\"type\":\"type\",\"readyAtMillis\":345,\"startedAtMillis\":456,\"endedAtMillis\":567,\"state\":\"failed\",\"message\":\"(#`д´)ノ\",\"progress\":0.1,\"speed\":1.0,\"cause\":\"test reindexing\"}]}]}");
// POST to request a service dump
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/node/host-tenant1.application1.instance1-prod.us-central-1/service-dump", POST)
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java
index 06cdccd17fc..10040ab6d0f 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java
@@ -1110,10 +1110,9 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
private void updateRemoveMetrics(Outcome outcome) {
switch (outcome) {
- case SUCCESS:
- case NOT_FOUND: metric.add(MetricNames.SUCCEEDED, 1, null); break;
- case CONDITION_FAILED: metric.add(MetricNames.CONDITION_NOT_MET, 1, null); break;
- default: metric.add(MetricNames.FAILED, 1, null); break;
+ case SUCCESS, NOT_FOUND -> metric.add(MetricNames.SUCCEEDED, 1, null);
+ case CONDITION_FAILED -> metric.add(MetricNames.CONDITION_NOT_MET, 1, null);
+ case INSUFFICIENT_STORAGE, TIMEOUT, ERROR -> metric.add(MetricNames.FAILED, 1, null);
}
}