summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/Model.java13
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java9
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java19
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java20
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java18
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java7
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationReindexing.java65
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java57
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainer.java33
-rw-r--r--configserver/src/test/apps/app-with-multiple-clusters/hosts.xml7
-rw-r--r--configserver/src/test/apps/app-with-multiple-clusters/schemas/bar.sd14
-rw-r--r--configserver/src/test/apps/app-with-multiple-clusters/schemas/bax.sd10
-rw-r--r--configserver/src/test/apps/app-with-multiple-clusters/schemas/baz.sd10
-rw-r--r--configserver/src/test/apps/app-with-multiple-clusters/services.xml33
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ModelStub.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/MockModel.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java68
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/ReindexingMaintainerTest.java33
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ApplicationReindexing.java28
-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.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggerer.java10
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ReindexingTriggererTest.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java2
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostsModel.java6
35 files changed, 324 insertions, 213 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java b/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java
index 6481c4cb2c7..36479c7504a 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/Model.java
@@ -27,18 +27,7 @@ public interface Model {
* @param configKey the key to resolve
* @param configDefinition the config definition to use for the schema
*/
- @Deprecated // TODO: Return after December 2020
- ConfigPayload getConfig(ConfigKey<?> configKey, ConfigDefinition configDefinition);
-
- /**
- * Resolves config for a given key and config definition
- *
- * @param configKey the key to resolve
- * @param configDefinition the config definition to use for the schema
- */
- default ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition configDefinition) {
- return null; // TODO: Remove this default implementation after December 2020
- }
+ ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition configDefinition);
/** Produces a set of the valid config keys for this model. */
Set<ConfigKey<?>> allConfigsProduced();
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
index df9f72b2182..38d831a0b28 100644
--- a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
+++ b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
@@ -34,15 +34,14 @@ public final class NewDocumentType extends StructuredDataType implements DataTyp
public static final class Name {
- // TODO: privatize
- final String name;
- final int id;
+ private final String name;
+ private final int id;
public Name(String name) {
- this(name.hashCode(),name);
+ this(name.hashCode(), name);
}
- public Name(int id,String name) {
+ public Name(int id, String name) {
this.id = id;
this.name = name;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
index 9f9c5def406..acb4f58655d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
@@ -404,25 +404,6 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
/**
* Resolve config for a given key and config definition
*
- * @param configKey The key to resolve.
- * @param targetDef The config definition to use for the schema
- * @return The payload as a list of strings
- */
- @Deprecated // TODO: Remove after December 2020
- @Override
- public ConfigPayload getConfig(ConfigKey<?> configKey, com.yahoo.vespa.config.buildergen.ConfigDefinition targetDef) {
- Objects.requireNonNull(targetDef, "config definition cannot be null");
-
- ConfigInstance.Builder builder = resolveToBuilder(configKey);
- log.log(Level.FINE, () -> "Found builder for " + configKey);
- InnerCNode innerCNode = targetDef.getCNode();
- ConfigPayload payload = getConfigFromBuilder(builder, innerCNode);
- return (innerCNode != null) ? payload.applyDefaultsFromDef(innerCNode) : payload;
- }
-
- /**
- * Resolve config for a given key and config definition
- *
* @param configKey the key to resolve.
* @param targetDef the config definition to use for the schema
* @return the resolved config instance
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java
index 58cea8c23e5..2fbf4359121 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java
@@ -32,23 +32,19 @@ public class IndexedSearchClusterChangeValidator implements ChangeValidator {
for (Map.Entry<String, ContentCluster> currentEntry : current.getContentClusters().entrySet()) {
ContentCluster nextCluster = next.getContentClusters().get(currentEntry.getKey());
if (nextCluster != null && nextCluster.getSearch().hasIndexedCluster()) {
- result.addAll(validateContentCluster(currentEntry.getValue(), nextCluster, overrides, now));
+ result.addAll(validateContentCluster(currentEntry.getValue(), nextCluster));
}
}
return result;
}
private static List<ConfigChangeAction> validateContentCluster(ContentCluster currentCluster,
- ContentCluster nextCluster,
- ValidationOverrides overrides,
- Instant now) {
- return validateDocumentDatabases(currentCluster, nextCluster, overrides, now);
+ ContentCluster nextCluster) {
+ return validateDocumentDatabases(currentCluster, nextCluster);
}
private static List<ConfigChangeAction> validateDocumentDatabases(ContentCluster currentCluster,
- ContentCluster nextCluster,
- ValidationOverrides overrides,
- Instant now) {
+ ContentCluster nextCluster) {
List<ConfigChangeAction> result = new ArrayList<>();
for (DocumentDatabase currentDb : getDocumentDbs(currentCluster.getSearch())) {
String docTypeName = currentDb.getName();
@@ -56,7 +52,7 @@ public class IndexedSearchClusterChangeValidator implements ChangeValidator {
filter(db -> db.getName().equals(docTypeName)).findFirst();
if (nextDb.isPresent()) {
result.addAll(validateDocumentDatabase(currentCluster, nextCluster, docTypeName,
- currentDb, nextDb.get(), overrides, now));
+ currentDb, nextDb.get()));
}
}
return result;
@@ -66,13 +62,11 @@ public class IndexedSearchClusterChangeValidator implements ChangeValidator {
ContentCluster nextCluster,
String docTypeName,
DocumentDatabase currentDb,
- DocumentDatabase nextDb,
- ValidationOverrides overrides,
- Instant now) {
+ DocumentDatabase nextDb) {
NewDocumentType currentDocType = currentCluster.getDocumentDefinitions().get(docTypeName);
NewDocumentType nextDocType = nextCluster.getDocumentDefinitions().get(docTypeName);
List<VespaConfigChangeAction> result =
- new DocumentDatabaseChangeValidator(currentCluster.id(), currentDb, currentDocType, nextDb, nextDocType).validate(overrides, now);
+ new DocumentDatabaseChangeValidator(currentCluster.id(), currentDb, currentDocType, nextDb, nextDocType).validate();
return modifyActions(result, getSearchNodeServices(nextCluster.getSearch().getIndexed()), docTypeName);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java
index 385a678d452..b83c345efd3 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java
@@ -35,13 +35,12 @@ public class IndexingModeChangeValidator implements ChangeValidator {
for (Map.Entry<String, ContentCluster> currentEntry : currentModel.getContentClusters().entrySet()) {
ContentCluster nextCluster = nextModel.getContentClusters().get(currentEntry.getKey());
if (nextCluster == null) continue;
- actions.addAll(validateContentCluster(currentEntry.getValue(), nextCluster, overrides, now));
+ actions.addAll(validateContentCluster(currentEntry.getValue(), nextCluster));
}
return actions;
}
- private static List<ConfigChangeAction> validateContentCluster(
- ContentCluster currentCluster, ContentCluster nextCluster, ValidationOverrides overrides, Instant now) {
+ private static List<ConfigChangeAction> validateContentCluster(ContentCluster currentCluster, ContentCluster nextCluster) {
List<ConfigChangeAction> actions = new ArrayList<>();
ContentSearchCluster currentSearchCluster = currentCluster.getSearch();
ContentSearchCluster nextSearchCluster = nextCluster.getSearch();
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java
index ce435a4c157..5596169958a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java
@@ -36,12 +36,12 @@ public class DocumentDatabaseChangeValidator {
this.nextDocType = nextDocType;
}
- public List<VespaConfigChangeAction> validate(ValidationOverrides overrides, Instant now) {
+ public List<VespaConfigChangeAction> validate() {
List<VespaConfigChangeAction> result = new ArrayList<>();
result.addAll(validateAttributeChanges());
- result.addAll(validateStructFieldAttributeChanges(overrides, now));
- result.addAll(validateIndexingScriptChanges(overrides, now));
- result.addAll(validateDocumentTypeChanges(overrides, now));
+ result.addAll(validateStructFieldAttributeChanges());
+ result.addAll(validateIndexingScriptChanges());
+ result.addAll(validateDocumentTypeChanges());
return result;
}
@@ -54,23 +54,23 @@ public class DocumentDatabaseChangeValidator {
.validate();
}
- private List<VespaConfigChangeAction> validateStructFieldAttributeChanges(ValidationOverrides overrides, Instant now) {
+ private List<VespaConfigChangeAction> validateStructFieldAttributeChanges() {
return new StructFieldAttributeChangeValidator(id,
currentDocType,
currentDatabase.getDerivedConfiguration().getAttributeFields(),
nextDocType,
nextDatabase.getDerivedConfiguration().getAttributeFields())
- .validate(overrides, now);
+ .validate();
}
- private List<VespaConfigChangeAction> validateIndexingScriptChanges(ValidationOverrides overrides, Instant now) {
+ private List<VespaConfigChangeAction> validateIndexingScriptChanges() {
return new IndexingScriptChangeValidator(id,
currentDatabase.getDerivedConfiguration().getSearch(),
nextDatabase.getDerivedConfiguration().getSearch())
- .validate(overrides, now);
+ .validate();
}
- private List<VespaConfigChangeAction> validateDocumentTypeChanges(ValidationOverrides overrides, Instant now) {
+ private List<VespaConfigChangeAction> validateDocumentTypeChanges() {
return new DocumentTypeChangeValidator(id, currentDocType, nextDocType)
.validate();
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
index e3f3abf0747..91e370211f1 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
@@ -35,7 +35,7 @@ public class IndexingScriptChangeValidator {
this.nextSearch = nextSearch;
}
- public List<VespaConfigChangeAction> validate(ValidationOverrides overrides, Instant now) {
+ public List<VespaConfigChangeAction> validate() {
List<VespaConfigChangeAction> result = new ArrayList<>();
for (ImmutableSDField nextField : nextSearch.allConcreteFields()) {
String fieldName = nextField.getName();
@@ -68,8 +68,8 @@ public class IndexingScriptChangeValidator {
return removeOutputExpressions(currentScript).equals(removeOutputExpressions(nextScript));
}
- private static ScriptExpression removeOutputExpressions(ScriptExpression script) {
- return (ScriptExpression) new OutputExpressionRemover().convert(script);
+ private static Expression removeOutputExpressions(ScriptExpression script) {
+ return new OutputExpressionRemover().convert(script);
}
private static class OutputExpressionRemover extends ExpressionConverter {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
index e8b2d593de6..a86277dded8 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
@@ -52,20 +52,19 @@ public class StructFieldAttributeChangeValidator {
this.nextAttributes = nextAttributes;
}
- public List<VespaConfigChangeAction> validate(ValidationOverrides overrides, Instant now) {
+ public List<VespaConfigChangeAction> validate() {
List<VespaConfigChangeAction> result = new ArrayList();
for (Field currentField : currentDocType.getAllFields()) {
Field nextField = nextDocType.getField(currentField.getName());
if (nextField != null) {
result.addAll(validateAddAttributeAspect(new Context(currentField, currentAttributes),
- new Context(nextField, nextAttributes),
- overrides, now));
+ new Context(nextField, nextAttributes)));
}
}
return result;
}
- private List<VespaConfigChangeAction> validateAddAttributeAspect(Context current, Context next, ValidationOverrides overrides, Instant now) {
+ private List<VespaConfigChangeAction> validateAddAttributeAspect(Context current, Context next) {
return next.structFieldAttributes.stream()
.filter(nextAttr -> current.hasFieldForStructFieldAttribute(nextAttr) &&
!current.hasStructFieldAttribute(nextAttr))
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java
index 1f64d41e371..27a32f3e754 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java
@@ -31,7 +31,7 @@ public class DocumentDatabaseChangeValidatorTest {
@Override
public List<VespaConfigChangeAction> validate() {
- return validator.validate(ValidationOverrides.empty, Instant.now());
+ return validator.validate();
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java
index 2e1ec53f886..20f5a9c841c 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java
@@ -29,7 +29,7 @@ public class IndexingScriptChangeValidatorTest {
@Override
public List<VespaConfigChangeAction> validate() {
- return validator.validate(ValidationOverrides.empty, Instant.now());
+ return validator.validate();
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
index 0bc4ecbfdfd..d37ab8be9a2 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
@@ -35,7 +35,7 @@ public class StructFieldAttributeChangeValidatorTestCase {
@Override
public List<VespaConfigChangeAction> validate() {
List<VespaConfigChangeAction> result = new ArrayList<>();
- result.addAll(structFieldAttributeValidator.validate(ValidationOverrides.empty, Instant.now()));
+ result.addAll(structFieldAttributeValidator.validate());
result.addAll(docTypeValidator.validate());
return result;
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
index e77592dc011..57eac2a1a7b 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
@@ -135,12 +135,7 @@ public class Application implements ModelResult {
boolean applyOnRestart = false;
try {
builder = model.getConfigInstance(configKey, def);
- if (builder == null) { // TODO: Remove this condition after December 2020
- payload = model.getConfig(configKey, def);
- if (def.getCNode() != null)
- payload.applyDefaultsFromDef(def.getCNode());
- }
- else if (builder instanceof GenericConfig.GenericConfigBuilder) {
+ if (builder instanceof GenericConfig.GenericConfigBuilder) {
payload = ((GenericConfig.GenericConfigBuilder) builder).getPayload();
applyOnRestart = builder.getApplyOnRestart();
}
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 cb81bed155e..1736b23012d 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,17 +2,28 @@
package com.yahoo.vespa.config.server.application;
import com.yahoo.config.model.api.Reindexing;
+import com.yahoo.searchdefinition.Search;
+import com.yahoo.searchdefinition.document.SDField;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.content.cluster.ContentCluster;
+import com.yahoo.vespa.model.search.AbstractSearchCluster;
+import com.yahoo.vespa.model.search.DocumentDatabase;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
+import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
import static java.util.stream.Collectors.toUnmodifiableMap;
+import static java.util.stream.Collectors.toUnmodifiableSet;
/**
* Pending and ready reindexing per document type. Each document type can have either a pending or a ready reindexing.
@@ -39,6 +50,40 @@ public class ApplicationReindexing implements Reindexing {
return new ApplicationReindexing(true, new Status(now), Map.of());
}
+ /** Returns the set of document types in each content cluster, in the given application */
+ public static Map<String, Set<String>> documentTypes(Application application) {
+ Map<String, ContentCluster> contentClusters = ((VespaModel) application.getModel()).getContentClusters();
+ return contentClusters.entrySet().stream()
+ .collect(toMap(cluster -> cluster.getKey(),
+ cluster -> cluster.getValue().getDocumentDefinitions().keySet()));
+ }
+
+ /** Returns the set of document types in each cluster, in the given application, that have an index for one of more fields. */
+ public static Map<String, Set<String>> documentTypesWithIndex(Application application) {
+ Map<String, ContentCluster> contentClusters = ((VespaModel) application.getModel()).getContentClusters();
+ return contentClusters.entrySet().stream()
+ .collect(toUnmodifiableMap(cluster -> cluster.getKey(),
+ cluster -> documentTypesWithIndex(cluster.getValue())));
+ }
+
+ private static Set<String> documentTypesWithIndex(ContentCluster content) {
+ Set<String> typesWithIndexMode = content.getSearch().getDocumentTypesWithIndexedCluster().stream()
+ .map(type -> type.getFullName().getName())
+ .collect(toSet());
+
+ Set<String> typesWithIndexedFields = content.getSearch().getIndexed() == null
+ ? Set.of()
+ : content.getSearch().getIndexed().getDocumentDbs().stream()
+ .filter(database -> database.getDerivedConfiguration()
+ .getSearch()
+ .allConcreteFields()
+ .stream().anyMatch(SDField::doesIndexing))
+ .map(database -> database.getInputDocType())
+ .collect(toSet());
+
+ return typesWithIndexMode.stream().filter(typesWithIndexedFields::contains).collect(toUnmodifiableSet());
+ }
+
/** Returns a copy of this with reindexing for the whole application ready at the given instant. */
public ApplicationReindexing withReady(Instant readyAt) {
return new ApplicationReindexing(enabled,
@@ -79,12 +124,32 @@ public class ApplicationReindexing implements Reindexing {
/** Returns a copy of this with no pending reindexing for the given document type. */
public ApplicationReindexing withoutPending(String cluster, String documentType) {
Cluster current = clusters.getOrDefault(cluster, Cluster.ready(common));
+ if (current == null)
+ return this;
+
Cluster modified = new Cluster(current.common,
without(documentType, current.pending),
current.ready);
return new ApplicationReindexing(enabled, common, with(cluster, modified, clusters));
}
+ /** Returns a copy of this without the given cluster. */
+ public ApplicationReindexing without(String cluster) {
+ return new ApplicationReindexing(enabled, common, without(cluster, clusters));
+ }
+
+ /** Returns a copy of this without the given document type in the given cluster. */
+ public ApplicationReindexing without(String cluster, String documentType) {
+ Cluster current = clusters.get(cluster);
+ if (current == null)
+ return this;
+
+ Cluster modified = new Cluster(current.common,
+ current.pending,
+ without(documentType, current.ready));
+ return new ApplicationReindexing(enabled, common, with(cluster, modified, clusters));
+ }
+
/** Returns a copy of this with the enabled-state set to the given value. */
public ApplicationReindexing enabled(boolean enabled) {
return new ApplicationReindexing(enabled, common, clusters);
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 7ea53a66697..401823aa6cd 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
@@ -18,6 +18,7 @@ import com.yahoo.jdisc.application.UriPattern;
import com.yahoo.slime.Cursor;
import com.yahoo.text.StringUtilities;
import com.yahoo.vespa.config.server.ApplicationRepository;
+import com.yahoo.vespa.config.server.application.Application;
import com.yahoo.vespa.config.server.application.ApplicationReindexing;
import com.yahoo.vespa.config.server.application.ClusterReindexing;
import com.yahoo.vespa.config.server.http.ContentHandler;
@@ -38,6 +39,9 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.StringJoiner;
+import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.stream.Stream;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -227,29 +231,46 @@ public class ApplicationHandler extends HttpHandler {
}
private HttpResponse triggerReindexing(HttpRequest request, ApplicationId applicationId) {
+ Application application = applicationRepository.getActiveApplicationSet(applicationId)
+ .orElseThrow(() -> new NotFoundException(applicationId + " not found"))
+ .getForVersionOrLatest(Optional.empty(), applicationRepository.clock().instant());
+ Map<String, Set<String>> documentTypes = ApplicationReindexing.documentTypes(application);
+ Map<String, Set<String>> indexedDocumentTypes = ApplicationReindexing.documentTypesWithIndex(application);
+
+ boolean indexedOnly = request.getBooleanProperty("indexedOnly");
Set<String> clusters = StringUtilities.split(request.getProperty("clusterId"));
Set<String> types = StringUtilities.split(request.getProperty("documentType"));
+
+ Map<String, Set<String>> reindexed = new TreeMap<>();
Instant now = applicationRepository.clock().instant();
applicationRepository.modifyReindexing(applicationId, reindexing -> {
- if (clusters.isEmpty())
- reindexing = reindexing.withReady(now);
- else
- for (String cluster : clusters)
- if (types.isEmpty())
- reindexing = reindexing.withReady(cluster, now);
- else
- for (String type : types)
- reindexing = reindexing.withReady(cluster, type, now);
+ for (String cluster : clusters.isEmpty() ? documentTypes.keySet() : clusters) {
+ if ( ! documentTypes.containsKey(cluster))
+ throw new IllegalArgumentException("No content cluster '" + cluster + "' in application — only: " +
+ String.join(", ", documentTypes.keySet()));
+
+ for (String type : types.isEmpty() ? documentTypes.get(cluster) : types) {
+ if ( ! documentTypes.get(cluster).contains(type))
+ throw new IllegalArgumentException("No document type '" + type + "' in cluster '" + cluster + "' — only: " +
+ String.join(", ", documentTypes.get(cluster)));
+
+ if ( ! indexedOnly || indexedDocumentTypes.get(cluster).contains(type)) {
+ reindexing = reindexing.withReady(cluster, type, now);
+ reindexed.computeIfAbsent(cluster, __ -> new TreeSet<>()).add(type);
+ }
+ }
+ }
return reindexing;
});
- String message = "Reindexing " +
- (clusters.isEmpty() ? ""
- : (types.isEmpty() ? ""
- : "document types " + String.join(", ", types) + " in ") +
- "clusters " + String.join(", ", clusters) + " of ") +
- "application " + applicationId;
- return createMessageResponse(message);
+ return createMessageResponse(reindexed.entrySet().stream()
+ .filter(cluster -> ! cluster.getValue().isEmpty())
+ .map(cluster -> "[" + String.join(", ", cluster.getValue()) + "] in '" + cluster.getKey() + "'")
+ .reduce(new StringJoiner(", ", "Reindexing document types ", " of application " + applicationId)
+ .setEmptyValue("Not reindexing any document types of application " + applicationId),
+ StringJoiner::add,
+ StringJoiner::merge)
+ .toString());
}
private HttpResponse getReindexingStatus(ApplicationId applicationId) {
@@ -452,8 +473,6 @@ public class ApplicationHandler extends HttpHandler {
ReindexingResponse(ApplicationReindexing reindexing, Map<String, ClusterReindexing> clusters) {
super(Response.Status.OK);
object.setBool("enabled", reindexing.enabled());
- setStatus(object.setObject("status"), reindexing.common());
-
Cursor clustersObject = object.setObject("clusters");
Stream<String> clusterNames = Stream.concat(clusters.keySet().stream(), reindexing.clusters().keySet().stream());
clusterNames.sorted()
@@ -464,8 +483,6 @@ public class ApplicationHandler extends HttpHandler {
Map<String, Cursor> statuses = new HashMap<>();
if (reindexing.clusters().containsKey(clusterName)) {
- setStatus(clusterObject.setObject("status"), reindexing.clusters().get(clusterName).common());
-
reindexing.clusters().get(clusterName).pending().entrySet().stream().sorted(comparingByKey())
.forEach(pending -> pendingObject.setLong(pending.getKey(), pending.getValue()));
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 22eb95261bd..34e4a5becfb 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
@@ -6,6 +6,7 @@ import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.application.Application;
import com.yahoo.vespa.config.server.application.ApplicationCuratorDatabase;
import com.yahoo.vespa.config.server.application.ApplicationReindexing;
+import com.yahoo.vespa.config.server.application.ApplicationReindexing.Cluster;
import com.yahoo.vespa.config.server.application.ConfigConvergenceChecker;
import com.yahoo.vespa.config.server.tenant.Tenant;
import com.yahoo.vespa.curator.Curator;
@@ -15,7 +16,9 @@ import com.yahoo.yolean.Exceptions;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
+import java.util.Collection;
import java.util.Comparator;
+import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
@@ -25,6 +28,7 @@ import java.util.logging.Logger;
/**
* Watches pending reindexing, and sets these to ready when config convergence is observed.
+ * Also removes data for clusters or document types which no longer exist.
*
* @author jonmv
*/
@@ -55,8 +59,11 @@ public class ReindexingMaintainer extends ConfigServerMaintainer {
.map(application -> application.getForVersionOrLatest(Optional.empty(), clock.instant()))
.ifPresent(application -> {
try {
- applicationRepository.modifyReindexing(id, reindexing ->
- withNewReady(reindexing, lazyGeneration(application), clock.instant()));
+ applicationRepository.modifyReindexing(id, reindexing -> {
+ reindexing = withNewReady(reindexing, lazyGeneration(application), clock.instant());
+ reindexing = withOnlyCurrentData(reindexing, application);
+ return reindexing;
+ });
}
catch (RuntimeException e) {
log.log(Level.INFO, "Failed to update reindexing status for " + id + ": " + Exceptions.toMessageString(e));
@@ -90,4 +97,26 @@ public class ReindexingMaintainer extends ConfigServerMaintainer {
return reindexing;
}
+ static ApplicationReindexing withOnlyCurrentData(ApplicationReindexing reindexing, Application application) {
+ return withOnlyCurrentData(reindexing, ApplicationReindexing.documentTypes(application));
+ }
+
+ static ApplicationReindexing withOnlyCurrentData(ApplicationReindexing reindexing, Map<String, ? extends Collection<String>> clusterDocumentTypes) {
+ for (String clusterId : reindexing.clusters().keySet()) {
+ if ( ! clusterDocumentTypes.containsKey(clusterId))
+ reindexing = reindexing.without(clusterId);
+ else {
+ Cluster cluster = reindexing.clusters().get(clusterId);
+ Collection<String> documentTypes = clusterDocumentTypes.get(clusterId);
+ for (String pending : cluster.pending().keySet())
+ if ( ! documentTypes.contains(pending))
+ reindexing = reindexing.withoutPending(clusterId, pending);
+ for (String ready : cluster.ready().keySet())
+ if ( ! documentTypes.contains(ready))
+ reindexing = reindexing.without(clusterId, ready);
+ }
+ }
+ return reindexing;
+ }
+
}
diff --git a/configserver/src/test/apps/app-with-multiple-clusters/hosts.xml b/configserver/src/test/apps/app-with-multiple-clusters/hosts.xml
new file mode 100644
index 00000000000..f4256c9fc81
--- /dev/null
+++ b/configserver/src/test/apps/app-with-multiple-clusters/hosts.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<hosts>
+ <host name="mytesthost">
+ <alias>node1</alias>
+ </host>
+</hosts>
diff --git a/configserver/src/test/apps/app-with-multiple-clusters/schemas/bar.sd b/configserver/src/test/apps/app-with-multiple-clusters/schemas/bar.sd
new file mode 100644
index 00000000000..b66695b17df
--- /dev/null
+++ b/configserver/src/test/apps/app-with-multiple-clusters/schemas/bar.sd
@@ -0,0 +1,14 @@
+# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+search bar {
+
+ field zoo type string {
+ indexing: input moo | index | summary
+ }
+
+ document bar {
+ field moo type string {
+ indexing: summary | attribute
+ }
+ }
+
+} \ No newline at end of file
diff --git a/configserver/src/test/apps/app-with-multiple-clusters/schemas/bax.sd b/configserver/src/test/apps/app-with-multiple-clusters/schemas/bax.sd
new file mode 100644
index 00000000000..f9f6aba766e
--- /dev/null
+++ b/configserver/src/test/apps/app-with-multiple-clusters/schemas/bax.sd
@@ -0,0 +1,10 @@
+# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+search bax {
+
+ document bax {
+ field moo type string {
+ indexing: summary | attribute
+ }
+ }
+
+} \ No newline at end of file
diff --git a/configserver/src/test/apps/app-with-multiple-clusters/schemas/baz.sd b/configserver/src/test/apps/app-with-multiple-clusters/schemas/baz.sd
new file mode 100644
index 00000000000..58f0aa16fd0
--- /dev/null
+++ b/configserver/src/test/apps/app-with-multiple-clusters/schemas/baz.sd
@@ -0,0 +1,10 @@
+# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+search baz {
+
+ document baz {
+ field moo type string {
+ indexing: summary | attribute
+ }
+ }
+
+} \ No newline at end of file
diff --git a/configserver/src/test/apps/app-with-multiple-clusters/services.xml b/configserver/src/test/apps/app-with-multiple-clusters/services.xml
new file mode 100644
index 00000000000..735bd04b2f9
--- /dev/null
+++ b/configserver/src/test/apps/app-with-multiple-clusters/services.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2020 Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<services version="1.0">
+
+ <content id="foo" version="1.0">
+ <redundancy>2</redundancy>
+ <documents>
+ <document type="bar" mode="index"/>
+ <document type="baz" mode="streaming"/>
+ <document type="bax" mode="index"/>
+ </documents>
+ <nodes>
+ <node hostalias="node1" distribution-key="0"/>
+ </nodes>
+ </content>
+
+ <content id="boo" version="1.0">
+ <redundancy>2</redundancy>
+ <documents>
+ <document type="bar" mode="store-only"/>
+ </documents>
+ <nodes>
+ <node hostalias="node1" distribution-key="1"/>
+ </nodes>
+ </content>
+
+ <container version="1.0">
+ <nodes>
+ <node hostalias="node1" />
+ </nodes>
+ </container>
+
+</services>
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelStub.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelStub.java
index 88f7d352ad7..ed12f4dbbe1 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelStub.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelStub.java
@@ -21,12 +21,6 @@ import java.util.Set;
public class ModelStub implements Model {
@Override
- @SuppressWarnings("deprecation")
- public ConfigPayload getConfig(ConfigKey<?> configKey, ConfigDefinition targetDef) {
- return null;
- }
-
- @Override
public ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition targetDef) {
throw new UnsupportedOperationException();
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/MockModel.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/MockModel.java
index 0288a551cd3..7e57eea74d6 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/MockModel.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/MockModel.java
@@ -74,12 +74,6 @@ public class MockModel implements Model {
}
@Override
- @SuppressWarnings("deprecation")
- public ConfigPayload getConfig(ConfigKey<?> configKey, ConfigDefinition targetDef) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition targetDef) {
throw new UnsupportedOperationException();
}
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 f9b33791a36..714526b24d4 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
@@ -77,6 +77,7 @@ import static org.mockito.Mockito.when;
public class ApplicationHandlerTest {
private static final File testApp = new File("src/test/apps/app");
+ private static final File testAppMultipleClusters = new File("src/test/apps/app-with-multiple-clusters");
private static final File testAppJdiscOnly = new File("src/test/apps/app-jdisc-only");
private final static TenantName mytenantName = TenantName.from("mytenant");
@@ -215,42 +216,55 @@ public class ApplicationHandlerTest {
ApplicationCuratorDatabase database = applicationRepository.getTenant(applicationId).getApplicationRepo().database();
reindexing(applicationId, GET, "{\"error-code\": \"NOT_FOUND\", \"message\": \"Reindexing status not found for default.default\"}", 404);
- applicationRepository.deploy(testApp, prepareParams(applicationId));
+ applicationRepository.deploy(testAppMultipleClusters, prepareParams(applicationId));
ApplicationReindexing expected = ApplicationReindexing.ready(clock.instant());
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- reindex(applicationId, "", "{\"message\":\"Reindexing application default.default\"}");
- expected = expected.withReady(clock.instant());
+ 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())
+ .withReady("foo", "bar", clock.instant())
+ .withReady("foo", "baz", clock.instant())
+ .withReady("foo", "bax", clock.instant());
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- expected = expected.withReady(clock.instant());
- reindex(applicationId, "?clusterId=", "{\"message\":\"Reindexing application default.default\"}");
+ reindex(applicationId, "?indexedOnly=true", "{\"message\":\"Reindexing document types [bar] in 'foo' of application default.default\"}");
+ expected = expected.withReady("foo", "bar", clock.instant());
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
clock.advance(Duration.ofSeconds(1));
- expected = expected.withReady(clock.instant());
- reindex(applicationId, "?documentType=moo", "{\"message\":\"Reindexing application default.default\"}");
+ expected = expected.withReady("boo", "bar", clock.instant())
+ .withReady("foo", "bar", clock.instant())
+ .withReady("foo", "baz", clock.instant())
+ .withReady("foo", "bax", clock.instant());
+ reindex(applicationId, "?clusterId=", "{\"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));
- reindex(applicationId, "?clusterId=foo,boo", "{\"message\":\"Reindexing clusters foo, boo of application default.default\"}");
- expected = expected.withReady("foo", clock.instant())
- .withReady("boo", clock.instant());
+ expected = expected.withReady("boo", "bar", clock.instant())
+ .withReady("foo", "bar", clock.instant());
+ reindex(applicationId, "?documentType=bar", "{\"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&documentType=bar,baz", "{\"message\":\"Reindexing document types bar, baz in clusters foo, boo of application default.default\"}");
- expected = expected.withReady("foo", "bar", clock.instant())
+ 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())
+ .withReady("foo", "bar", clock.instant())
.withReady("foo", "baz", clock.instant())
- .withReady("boo", "bar", clock.instant())
- .withReady("boo", "baz", clock.instant());
+ .withReady("foo", "bax", clock.instant());
+ assertEquals(expected,
+ database.readReindexingStatus(applicationId).orElseThrow());
+
+ clock.advance(Duration.ofSeconds(1));
+ reindex(applicationId, "?clusterId=foo&documentType=bar,baz", "{\"message\":\"Reindexing document types [bar, baz] in 'foo' of application default.default\"}");
+ expected = expected.withReady("foo", "bar", clock.instant())
+ .withReady("foo", "baz", clock.instant());
assertEquals(expected,
database.readReindexingStatus(applicationId).orElseThrow());
@@ -269,35 +283,26 @@ public class ApplicationHandlerTest {
long now = clock.instant().toEpochMilli();
reindexing(applicationId, GET, "{" +
" \"enabled\": true," +
- " \"status\": {" +
- " \"readyMillis\": " + (now - 2000) +
- " }," +
" \"clusters\": {" +
" \"boo\": {" +
- " \"status\": {" +
- " \"readyMillis\": " + (now - 1000) +
- " }," +
" \"pending\": {" +
" \"bar\": 123" +
" }," +
" \"ready\": {" +
" \"bar\": {" +
- " \"readyMillis\": " + now +
+ " \"readyMillis\": " + (now - 1000) +
" }," +
- " \"baz\": {" +
- " \"readyMillis\": " + now +
- " }" +
" }" +
" }," +
" \"foo\": {" +
- " \"status\": {" +
- " \"readyMillis\": " + (now - 1000) +
- " }," +
" \"pending\": {}," +
" \"ready\": {" +
" \"bar\": {" +
" \"readyMillis\": " + now +
" }," +
+ " \"bax\": {" +
+ " \"readyMillis\": " + (now - 1000) +
+ " }," +
" \"baz\": {" +
" \"readyMillis\": " + now +
" }" +
@@ -463,9 +468,6 @@ public class ApplicationHandlerTest {
"moo", clusterReindexing))),
"{\n" +
" \"enabled\": true,\n" +
- " \"status\": {\n" +
- " \"readyMillis\": 113456\n" +
- " },\n" +
" \"clusters\": {\n" +
" \"boo\": {\n" +
" \"pending\": {},\n" +
@@ -487,9 +489,6 @@ public class ApplicationHandlerTest {
" \"bar\": 123\n" +
" },\n" +
" \"ready\": {},\n" +
- " \"status\": {\n" +
- " \"readyMillis\": 113456\n" +
- " }\n" +
" },\n" +
" \"moo\": {\n" +
" \"pending\": {},\n" +
@@ -505,9 +504,6 @@ public class ApplicationHandlerTest {
" \"bax\": {\n" +
" \"startedMillis\": 123456\n" +
" }\n" +
- " },\n" +
- " \"status\": {\n" +
- " \"readyMillis\": 122456\n" +
" }\n" +
" }\n" +
" }\n" +
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 d75b91f45e3..d0a4cd59dbd 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
@@ -5,8 +5,11 @@ import com.yahoo.vespa.config.server.application.ApplicationReindexing;
import org.junit.Test;
import java.time.Instant;
+import java.util.List;
+import java.util.Map;
import static com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer.withNewReady;
+import static com.yahoo.vespa.config.server.maintenance.ReindexingMaintainer.withOnlyCurrentData;
import static org.junit.Assert.assertEquals;
/**
@@ -46,4 +49,34 @@ public class ReindexingMaintainerTest {
later);
}
+ @Test
+ public void testGarbageRemoval() {
+ ApplicationReindexing reindexing = ApplicationReindexing.ready(Instant.EPOCH)
+ .withPending("one", "a", 10)
+ .withPending("two", "b", 20)
+ .withReady("one", "a", Instant.ofEpochMilli(3))
+ .withReady("two", "b", Instant.ofEpochMilli(2))
+ .withReady("two", "c", Instant.ofEpochMilli(3));
+
+ assertEquals(reindexing,
+ withOnlyCurrentData(reindexing, Map.of("one", List.of("a", "b", "c", "d"),
+ "two", List.of("b", "c"),
+ "three", List.of("a", "b"))));
+
+ assertEquals(reindexing,
+ withOnlyCurrentData(reindexing, Map.of("one", List.of("a"),
+ "two", List.of("b", "c"))));
+
+ assertEquals(ApplicationReindexing.ready(Instant.EPOCH)
+ .withPending("two", "b", 20)
+ .withReady("two", "b", Instant.ofEpochMilli(2)),
+ withOnlyCurrentData(reindexing, Map.of("two", List.of("a", "b"))));
+
+ assertEquals(ApplicationReindexing.ready(Instant.EPOCH)
+ .withReady("one", Instant.EPOCH)
+ .withReady("two", "c", Instant.ofEpochMilli(3)),
+ withOnlyCurrentData(reindexing, Map.of("one", List.of("c"),
+ "two", List.of("c"))));
+ }
+
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java
index b5cdfa8eda2..865d3b71b6e 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java
@@ -84,12 +84,6 @@ public class DeploymentMetricsRetrieverTest {
}
@Override
- @SuppressWarnings("deprecation")
- public ConfigPayload getConfig(ConfigKey<?> configKey, ConfigDefinition targetDef) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition targetDef) {
throw new UnsupportedOperationException();
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java
index 7fab01faf3d..5aada44b573 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java
@@ -77,12 +77,6 @@ public class ProtonMetricsRetrieverTest {
}
@Override
- @SuppressWarnings("deprecation")
- public ConfigPayload getConfig(ConfigKey<?> configKey, ConfigDefinition targetDef) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition targetDef) {
throw new UnsupportedOperationException();
}
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 e143cdd6d9e..f94a91dc0c6 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
@@ -6,8 +6,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import static java.util.Objects.requireNonNull;
-
/**
* Reindexing status for a single Vespa application.
*
@@ -16,12 +14,10 @@ import static java.util.Objects.requireNonNull;
public class ApplicationReindexing {
private final boolean enabled;
- private final Status common;
private final Map<String, Cluster> clusters;
- public ApplicationReindexing(boolean enabled, Status common, Map<String, Cluster> clusters) {
+ public ApplicationReindexing(boolean enabled, Map<String, Cluster> clusters) {
this.enabled = enabled;
- this.common = requireNonNull(common);
this.clusters = Map.copyOf(clusters);
}
@@ -29,10 +25,6 @@ public class ApplicationReindexing {
return enabled;
}
- public Status common() {
- return common;
- }
-
public Map<String, Cluster> clusters() {
return clusters;
}
@@ -43,20 +35,18 @@ public class ApplicationReindexing {
if (o == null || getClass() != o.getClass()) return false;
ApplicationReindexing that = (ApplicationReindexing) o;
return enabled == that.enabled &&
- common.equals(that.common) &&
clusters.equals(that.clusters);
}
@Override
public int hashCode() {
- return Objects.hash(enabled, common, clusters);
+ return Objects.hash(enabled, clusters);
}
@Override
public String toString() {
return "ApplicationReindexing{" +
"enabled=" + enabled +
- ", common=" + common +
", clusters=" + clusters +
'}';
}
@@ -64,20 +54,14 @@ public class ApplicationReindexing {
public static class Cluster {
- private final Optional<Status> common;
private final Map<String, Long> pending;
private final Map<String, Status> ready;
- public Cluster(Status common, Map<String, Long> pending, Map<String, Status> ready) {
- this.common = Optional.ofNullable(common);
+ public Cluster(Map<String, Long> pending, Map<String, Status> ready) {
this.pending = Map.copyOf(pending);
this.ready = Map.copyOf(ready);
}
- public Optional<Status> common() {
- return common;
- }
-
public Map<String, Long> pending() {
return pending;
}
@@ -91,20 +75,18 @@ public class ApplicationReindexing {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cluster cluster = (Cluster) o;
- return common.equals(cluster.common) &&
- pending.equals(cluster.pending) &&
+ return pending.equals(cluster.pending) &&
ready.equals(cluster.ready);
}
@Override
public int hashCode() {
- return Objects.hash(common, pending, ready);
+ return Objects.hash(pending, ready);
}
@Override
public String toString() {
return "Cluster{" +
- "common=" + common +
", pending=" + pending +
", ready=" + ready +
'}';
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 11940b30ac1..a90155d4e3e 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
@@ -35,7 +35,7 @@ public interface ConfigServer {
PreparedApplication deploy(DeploymentData deployment);
- void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes);
+ void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly);
Optional<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 e071221dd05..8447353a869 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
@@ -189,8 +189,8 @@ public class ApplicationController {
* 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) {
- configServer.reindex(new DeploymentId(id, zoneId), clusterNames, documentTypes);
+ public void reindex(ApplicationId id, ZoneId zoneId, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly) {
+ configServer.reindex(new DeploymentId(id, zoneId), clusterNames, documentTypes, indexedOnly);
}
/** 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 f787c5d62e7..263a33cf266 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
@@ -49,7 +49,7 @@ 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());
+ controller().applications().reindex(id, deployment.zone(), List.of(), List.of(), true);
});
return true;
}
@@ -74,11 +74,9 @@ public class ReindexingTriggerer extends ControllerMaintainer {
}
static boolean reindexingIsReady(ApplicationReindexing reindexing, Instant now) {
- if (reindexing.clusters().values().stream().flatMap(cluster -> cluster.ready().values().stream())
- .anyMatch(status -> status.startedAt().isPresent() && status.endedAt().isEmpty()))
- return false;
-
- return reindexing.common().readyAt().orElse(Instant.EPOCH).isBefore(now.minus(reindexingPeriod.dividedBy(2)));
+ return reindexing.clusters().values().stream().flatMap(cluster -> cluster.ready().values().stream())
+ .allMatch(status -> status.readyAt().map(now.minus(reindexingPeriod.dividedBy(2))::isAfter).orElse(true)
+ && (status.startedAt().isEmpty() || status.endedAt().isPresent()));
}
}
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 be4372af526..8378b914fe4 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
@@ -1561,7 +1561,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
.filter(type -> ! type.isBlank())
.collect(toUnmodifiableList());
- controller.applications().reindex(id, zone, clusterNames, documentTypes);
+ controller.applications().reindex(id, zone, clusterNames, documentTypes, request.getBooleanProperty("indexedOnly"));
return new MessageResponse("Requested reindexing of " + id + " in " + zone +
(clusterNames.isEmpty() ? "" : ", on clusters " + String.join(", ", clusterNames) +
(documentTypes.isEmpty() ? "" : ", for types " + String.join(", ", documentTypes))));
@@ -1577,14 +1577,12 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
Cursor root = slime.setObject();
root.setBool("enabled", reindexing.enabled());
- setStatus(root.setObject("status"), reindexing.common());
Cursor clustersArray = root.setArray("clusters");
reindexing.clusters().entrySet().stream().sorted(comparingByKey())
.forEach(cluster -> {
Cursor clusterObject = clustersArray.addObject();
clusterObject.setString("name", cluster.getKey());
- cluster.getValue().common().ifPresent(common -> setStatus(clusterObject.setObject("status"), common));
Cursor pendingArray = clusterObject.setArray("pending");
cluster.getValue().pending().entrySet().stream().sorted(comparingByKey())
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 7753570b72d..ee3c523a497 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
@@ -422,15 +422,13 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
}
@Override
- public void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes) { }
+ public void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly) { }
@Override
public Optional<ApplicationReindexing> getReindexing(DeploymentId deployment) {
return Optional.of(new ApplicationReindexing(true,
- new Status(Instant.ofEpochMilli(123)),
Map.of("cluster",
- new ApplicationReindexing.Cluster(new Status(Instant.ofEpochMilli(234)),
- Map.of("type", 100L),
+ new ApplicationReindexing.Cluster(Map.of("type", 100L),
Map.of("type", new Status(Instant.ofEpochMilli(345),
Instant.ofEpochMilli(456),
Instant.ofEpochMilli(567),
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 848426b6581..3c22ee3f4c3 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
@@ -50,8 +50,7 @@ public class ReindexingTriggererTest {
public void testReindexingIsReady() {
Instant then = Instant.now();
ApplicationReindexing reindexing = new ApplicationReindexing(true,
- new Status(then),
- Map.of());
+ Map.of("c", new Cluster(Map.of(), Map.of("d", new Status(then)))));
Instant now = then;
assertFalse("Should not be ready less than one half-period after last triggering",
@@ -66,20 +65,16 @@ public class ReindexingTriggererTest {
reindexingIsReady(reindexing, now));
reindexing = new ApplicationReindexing(true,
- new Status(then),
Map.of("cluster",
- new Cluster(new Status(then),
- Map.of(),
+ new Cluster(Map.of(),
Map.of("type",
new Status(then, then, null, null, null, null)))));
assertFalse("Should not be ready when reindexing is already running",
reindexingIsReady(reindexing, now));
reindexing = new ApplicationReindexing(true,
- new Status(then),
Map.of("cluster",
- new Cluster(new Status(then),
- Map.of("type", 123L),
+ new Cluster(Map.of("type", 123L),
Map.of("type",
new Status(then, then, now, null, null, null)))));
assertTrue("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 84b6ec2b263..e5f11beb9a2 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
@@ -615,7 +615,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,\"status\":{\"readyAtMillis\":123},\"clusters\":[{\"name\":\"cluster\",\"status\":{\"readyAtMillis\":234},\"pending\":[{\"type\":\"type\",\"requiredGeneration\":100}],\"ready\":[{\"type\":\"type\",\"readyAtMillis\":345,\"startedAtMillis\":456,\"endedAtMillis\":567,\"state\":\"failed\",\"message\":\"(#`д´)ノ\",\"progress\":0.1}]}]}");
+ "{\"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}]}]}");
// POST a 'restart application' command
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/restart", POST)
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostsModel.java b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostsModel.java
index 97b9313a06a..10820ccc508 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostsModel.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/duper/HostsModel.java
@@ -36,12 +36,6 @@ public class HostsModel implements Model {
}
@Override
- @SuppressWarnings("deprecation") // yes, this is needed
- public ConfigPayload getConfig(ConfigKey<?> configKey, ConfigDefinition configDefinition) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public ConfigInstance.Builder getConfigInstance(ConfigKey<?> configKey, ConfigDefinition configDefinition) {
throw new UnsupportedOperationException();
}