summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java34
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java2
-rw-r--r--config-model/src/main/java/com/yahoo/schema/derived/SummaryClass.java6
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java5
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java8
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/SDField.java9
-rw-r--r--config-model/src/main/java/com/yahoo/schema/processing/AddExtraFieldsToDocument.java1
-rw-r--r--config-model/src/main/java/com/yahoo/schema/processing/Processing.java1
-rw-r--r--config-model/src/main/java/com/yahoo/schema/processing/RankingExpressionTypeResolver.java6
-rw-r--r--config-model/src/main/java/com/yahoo/schema/processing/SummaryTransformForDocumentId.java32
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java13
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldAttributesValidator.java (renamed from config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java)4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java72
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java4
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/docproc/ContainerDocproc.java48
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocprocOptionsBuilder.java55
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/routing/DocumentProtocol.java79
-rw-r--r--config-model/src/main/resources/schema/docproc.rnc9
-rw-r--r--config-model/src/test/derived/imported_struct_fields/summarymap.cfg3
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/schema/derived/SummaryMapTestCase.java25
-rw-r--r--config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionTypeResolverTestCase.java2
-rw-r--r--config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionWithOnnxTestCase.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexFieldsValidatorTestCase.java (renamed from config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java)26
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/DocprocBuilderTest.java9
30 files changed, 291 insertions, 181 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
index abd7ba3be9f..9ee279c68d3 100644
--- a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
+++ b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
@@ -1,22 +1,22 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.model.test;
+import com.yahoo.component.Version;
+import com.yahoo.config.application.api.ApplicationFile;
import com.yahoo.config.application.api.ApplicationMetaData;
+import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.application.api.ComponentInfo;
import com.yahoo.config.application.api.UnparsedConfigDefinition;
-import com.yahoo.config.application.api.ApplicationFile;
-import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.io.IOUtils;
-import com.yahoo.path.Path;
import com.yahoo.io.reader.NamedReader;
+import com.yahoo.path.Path;
import com.yahoo.search.query.profile.QueryProfileRegistry;
import com.yahoo.search.query.profile.config.QueryProfileXMLReader;
import com.yahoo.vespa.config.ConfigDefinitionKey;
-import com.yahoo.config.application.api.ApplicationPackage;
import java.io.BufferedInputStream;
import java.io.File;
@@ -46,7 +46,6 @@ import java.util.stream.Collectors;
*/
public class MockApplicationPackage implements ApplicationPackage {
- public static final String DEPLOYED_BY_USER = "user";
public static final String APPLICATION_NAME = "application";
public static final long APPLICATION_GENERATION = 1L;
public static final String MUSIC_SCHEMA = createSchema("music", "foo");
@@ -80,8 +79,7 @@ public class MockApplicationPackage implements ApplicationPackage {
this.failOnValidateXml = failOnValidateXml;
queryProfileRegistry = new QueryProfileXMLReader().read(asNamedReaderList(queryProfileType),
asNamedReaderList(queryProfile));
- applicationMetaData = new ApplicationMetaData(DEPLOYED_BY_USER,
- "dir",
+ applicationMetaData = new ApplicationMetaData("dir",
0L,
false,
ApplicationId.from(TenantName.defaultName(),
@@ -165,7 +163,7 @@ public class MockApplicationPackage implements ApplicationPackage {
@Override
public ApplicationFile getFile(Path file) {
if (files.containsKey(file)) return files.get(file);
- return new MockApplicationFile(file, Path.fromString(root.toString()));
+ return new MockApplicationFile(file, root);
}
@Override
@@ -288,7 +286,7 @@ public class MockApplicationPackage implements ApplicationPackage {
Map<Path, MockApplicationFile> mockFiles = new HashMap<>();
for (var file : files.entrySet())
mockFiles.put(file.getKey(), new MockApplicationFile(file.getKey(),
- Path.fromString(root.toString()), file.getValue()));
+ root, file.getValue()));
this.files = mockFiles;
return this;
}
@@ -374,8 +372,8 @@ public class MockApplicationPackage implements ApplicationPackage {
public static class MockApplicationFile extends ApplicationFile {
- /** The path to the application package root */
- private final Path root;
+ /** The application package root */
+ private final File root;
/** The File pointing to the actual file represented by this */
private final File file;
@@ -383,14 +381,14 @@ public class MockApplicationPackage implements ApplicationPackage {
/** The content of this file, or null to read it from the file system. */
private final String content;
- public MockApplicationFile(Path filePath, Path applicationPackagePath) {
- this(filePath, applicationPackagePath, null);
+ public MockApplicationFile(Path relativeFile, File root) {
+ this(relativeFile, root, null);
}
- private MockApplicationFile(Path filePath, Path applicationPackagePath, String content) {
- super(filePath);
- this.root = applicationPackagePath;
- file = applicationPackagePath.append(filePath).toFile();
+ private MockApplicationFile(Path relativeFile, File root, String content) {
+ super(relativeFile);
+ this.root = root;
+ this.file = root.toPath().resolve(relativeFile.toString()).toFile();
this.content = content;
}
@@ -491,7 +489,7 @@ public class MockApplicationPackage implements ApplicationPackage {
Iterator<String> pathIterator = path.iterator();
// Skip the path elements this shares with the root
- for (Iterator<String> rootIterator = root.iterator(); rootIterator.hasNext(); ) {
+ for (Iterator<String> rootIterator = Path.fromString(root.toString()).iterator(); rootIterator.hasNext(); ) {
String rootElement = rootIterator.next();
String pathElement = pathIterator.next();
if ( ! rootElement.equals(pathElement)) throw new RuntimeException("Assumption broken");
diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java b/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java
index 7e2953e6606..74a5e92d2ba 100644
--- a/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java
+++ b/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java
@@ -61,7 +61,7 @@ public class MockRoot extends AbstractConfigProducerRoot {
public MockRoot(String rootConfigId, DeployState deployState) {
super(rootConfigId);
- hostSystem = new HostSystem(this, "hostsystem", deployState.getProvisioner(), deployState.getDeployLogger());
+ hostSystem = new HostSystem(this, "hostsystem", deployState.getProvisioner(), deployState.getDeployLogger(), deployState.isHosted());
this.deployState = deployState;
fileReferencesRepository = new FileReferencesRepository(deployState.getFileRegistry());
}
diff --git a/config-model/src/main/java/com/yahoo/schema/derived/SummaryClass.java b/config-model/src/main/java/com/yahoo/schema/derived/SummaryClass.java
index 193c6893203..efc64a5aa40 100644
--- a/config-model/src/main/java/com/yahoo/schema/derived/SummaryClass.java
+++ b/config-model/src/main/java/com/yahoo/schema/derived/SummaryClass.java
@@ -59,7 +59,7 @@ public class SummaryClass extends Derived {
/** MUST be called after all other fields are added */
private void deriveImplicitFields(DocumentSummary summary, Map<String, SummaryClassField> fields) {
if (summary.getName().equals("default")) {
- addField(SummaryClass.DOCUMENT_ID_FIELD, DataType.STRING, fields);
+ addField(SummaryClass.DOCUMENT_ID_FIELD, DataType.STRING, SummaryTransform.DOCUMENT_ID, fields);
}
}
@@ -72,10 +72,6 @@ public class SummaryClass extends Derived {
}
}
- private void addField(String name, DataType type, Map<String, SummaryClassField> fields) {
- addField(name, type, null, fields);
- }
-
private void addField(String name, DataType type,
SummaryTransform transform,
Map<String, SummaryClassField> fields) {
diff --git a/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java b/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java
index 335942de99d..221280dc1e4 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java
@@ -83,6 +83,11 @@ public class ImmutableImportedSDField implements ImmutableSDField {
}
@Override
+ public boolean wasConfiguredToDoIndexing() {
+ return importedField.targetField().wasConfiguredToDoIndexing();
+ }
+
+ @Override
public DataType getDataType() {
return importedField.targetField().getDataType();
}
diff --git a/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java b/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java
index 44e442811ba..37cbb3a8171 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java
@@ -45,6 +45,14 @@ public interface ImmutableSDField {
*/
boolean wasConfiguredToDoAttributing();
+ /**
+ * Whether this field at some time was configured to do indexing.
+ *
+ * This function can typically return a different value than doesIndexing(),
+ * which uses the final state of the underlying indexing script instead.
+ */
+ boolean wasConfiguredToDoIndexing();
+
DataType getDataType();
Index getIndex(String name);
diff --git a/config-model/src/main/java/com/yahoo/schema/document/SDField.java b/config-model/src/main/java/com/yahoo/schema/document/SDField.java
index 943d6c6fc14..2d79d89a2a0 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/SDField.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/SDField.java
@@ -117,6 +117,7 @@ public class SDField extends Field implements TypedKey, ImmutableSDField {
private boolean isExtraField = false;
private boolean wasConfiguredToDoAttributing = false;
+ private boolean wasConfiguredToDoIndexing = false;
/**
* Creates a new field. This method is only used to create reserved fields.
@@ -381,6 +382,11 @@ public class SDField extends Field implements TypedKey, ImmutableSDField {
return wasConfiguredToDoAttributing;
}
+ @Override
+ public boolean wasConfiguredToDoIndexing() {
+ return wasConfiguredToDoIndexing;
+ }
+
/** Parse an indexing expression which will use the simple linguistics implementation suitable for testing */
public void parseIndexingScript(String script) {
parseIndexingScript(script, new SimpleLinguistics(), Embedder.throwsOnUse.asMap());
@@ -408,6 +414,9 @@ public class SDField extends Field implements TypedKey, ImmutableSDField {
if (!wasConfiguredToDoAttributing()) {
wasConfiguredToDoAttributing = doesAttributing();
}
+ if (!wasConfiguredToDoIndexing()) {
+ wasConfiguredToDoIndexing = doesIndexing();
+ }
if (!usesStructOrMap()) {
new ExpressionVisitor() {
diff --git a/config-model/src/main/java/com/yahoo/schema/processing/AddExtraFieldsToDocument.java b/config-model/src/main/java/com/yahoo/schema/processing/AddExtraFieldsToDocument.java
index ca81301da73..471d338a5f6 100644
--- a/config-model/src/main/java/com/yahoo/schema/processing/AddExtraFieldsToDocument.java
+++ b/config-model/src/main/java/com/yahoo/schema/processing/AddExtraFieldsToDocument.java
@@ -39,6 +39,7 @@ public class AddExtraFieldsToDocument extends Processor {
case DYNAMICBOLDED:
case DYNAMICTEASER:
case TEXTEXTRACTOR:
+ case DOCUMENT_ID: // TODO: Adding the 'documentid' field should no longer be needed when the docsum framework in the backend has been simplified and the transform is always used.
addSummaryField(schema, document, summaryField, validate);
break;
default:
diff --git a/config-model/src/main/java/com/yahoo/schema/processing/Processing.java b/config-model/src/main/java/com/yahoo/schema/processing/Processing.java
index 63eca2121c1..8f7e8daeed0 100644
--- a/config-model/src/main/java/com/yahoo/schema/processing/Processing.java
+++ b/config-model/src/main/java/com/yahoo/schema/processing/Processing.java
@@ -52,6 +52,7 @@ public class Processing {
ImplicitSummaries::new,
ImplicitSummaryFields::new,
AdjustPositionSummaryFields::new,
+ SummaryTransformForDocumentId::new,
SummaryConsistency::new,
SummaryNamesFieldCollisions::new,
SummaryFieldsMustHaveValidSource::new,
diff --git a/config-model/src/main/java/com/yahoo/schema/processing/RankingExpressionTypeResolver.java b/config-model/src/main/java/com/yahoo/schema/processing/RankingExpressionTypeResolver.java
index 07f79f16334..d985089b2cb 100644
--- a/config-model/src/main/java/com/yahoo/schema/processing/RankingExpressionTypeResolver.java
+++ b/config-model/src/main/java/com/yahoo/schema/processing/RankingExpressionTypeResolver.java
@@ -93,9 +93,9 @@ public class RankingExpressionTypeResolver extends Processor {
throw new IllegalArgumentException(profile + " is strict but is missing a query profile type " +
"declaration of features " + context.queryFeaturesNotDeclared());
else
- deployLogger.logApplicationPackage(Level.WARNING, "The following query features used in " + profile +
- " are not declared in query profile " +
- "types and will be interpreted as scalars, not tensors: " +
+ deployLogger.logApplicationPackage(Level.WARNING, "The following query features used in " +
+ profile + " are not declared " +
+ "and will be interpreted as scalars, not tensors: " +
context.queryFeaturesNotDeclared());
warnedAbout.addAll(context.queryFeaturesNotDeclared());
}
diff --git a/config-model/src/main/java/com/yahoo/schema/processing/SummaryTransformForDocumentId.java b/config-model/src/main/java/com/yahoo/schema/processing/SummaryTransformForDocumentId.java
new file mode 100644
index 00000000000..99419ecd526
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/schema/processing/SummaryTransformForDocumentId.java
@@ -0,0 +1,32 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.schema.processing;
+
+import com.yahoo.config.application.api.DeployLogger;
+import com.yahoo.schema.RankProfileRegistry;
+import com.yahoo.schema.Schema;
+import com.yahoo.schema.derived.SummaryClass;
+import com.yahoo.vespa.documentmodel.SummaryTransform;
+import com.yahoo.vespa.model.container.search.QueryProfiles;
+
+/**
+ * Adds the corresponding summary transform for all "documentid" summary fields.
+ *
+ * @author geirst
+ */
+public class SummaryTransformForDocumentId extends Processor {
+
+ public SummaryTransformForDocumentId(Schema schema, DeployLogger deployLogger, RankProfileRegistry rankProfileRegistry, QueryProfiles queryProfiles) {
+ super(schema, deployLogger, rankProfileRegistry, queryProfiles);
+ }
+
+ @Override
+ public void process(boolean validate, boolean documentsOnly) {
+ for (var summary : schema.getSummaries().values()) {
+ for (var summaryField : summary.getSummaryFields().values()) {
+ if (summaryField.getName().equals(SummaryClass.DOCUMENT_ID_FIELD)) {
+ summaryField.setTransform(SummaryTransform.DOCUMENT_ID);
+ }
+ }
+ }
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java
index a1ebc9e4bec..5c3aef89edc 100644
--- a/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java
+++ b/config-model/src/main/java/com/yahoo/vespa/documentmodel/SummaryTransform.java
@@ -23,7 +23,8 @@ public enum SummaryTransform {
ATTRIBUTECOMBINER("attributecombiner"),
MATCHED_ELEMENTS_FILTER("matchedelementsfilter"),
MATCHED_ATTRIBUTE_ELEMENTS_FILTER("matchedattributeelementsfilter"),
- COPY("copy");
+ COPY("copy"),
+ DOCUMENT_ID("documentid");
private final String name;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java b/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java
index 1042400442b..fcad1e20c16 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java
@@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.function.BiConsumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -39,30 +40,34 @@ public class HostSystem extends AbstractConfigProducer<Host> {
private final Map<String, HostResource> hostname2host = new LinkedHashMap<>();
private final HostProvisioner provisioner;
private final DeployLogger deployLogger;
+ private final boolean isHosted;
static {
String checkIpProperty = System.getProperty("config_model.ip_check", "true");
doCheckIp = ! checkIpProperty.equalsIgnoreCase("false");
}
- public HostSystem(AbstractConfigProducer<?> parent, String name, HostProvisioner provisioner, DeployLogger deployLogger) {
+ public HostSystem(AbstractConfigProducer<?> parent, String name, HostProvisioner provisioner, DeployLogger deployLogger, boolean isHosted) {
super(parent, name);
this.provisioner = provisioner;
this.deployLogger = deployLogger;
+ this.isHosted = isHosted;
}
void checkName(String hostname) {
if (doCheckIp) {
+ // Bad DNS config in a hosted system isn't actionable by the tenant, so we log any warnings internally
+ BiConsumer<Level, String> logFunction = isHosted ? deployLogger::log : deployLogger::logApplicationPackage;
// Give a warning if the host does not exist
try {
var inetAddr = java.net.InetAddress.getByName(hostname);
String canonical = inetAddr.getCanonicalHostName();
if (!hostname.equals(canonical)) {
- deployLogger.logApplicationPackage(Level.WARNING, "Host named '" + hostname + "' may not receive any config " +
- "since it differs from its canonical hostname '" + canonical + "' (check DNS and /etc/hosts).");
+ logFunction.accept(Level.WARNING, "Host named '" + hostname + "' may not receive any config " +
+ "since it differs from its canonical hostname '" + canonical + "' (check DNS and /etc/hosts).");
}
} catch (UnknownHostException e) {
- deployLogger.logApplicationPackage(Level.WARNING, "Unable to lookup IP address of host: " + hostname);
+ logFunction.accept(Level.WARNING, "Unable to lookup IP address of host: " + hostname);
}
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldAttributesValidator.java
index 01bf846d4cb..8515c34a377 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldAttributesValidator.java
@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
*
* @author geirst
*/
-public class ComplexAttributeFieldsValidator extends Validator {
+public class ComplexFieldsWithStructFieldAttributesValidator extends Validator {
@Override
public void validate(VespaModel model, DeployState deployState) {
@@ -39,7 +39,7 @@ public class ComplexAttributeFieldsValidator extends Validator {
private static void validateComplexFields(String clusterName, Schema schema) {
String unsupportedFields = schema.allFields()
.filter(field -> isUnsupportedComplexField(field))
- .map(ComplexAttributeFieldsValidator::toString)
+ .map(ComplexFieldsWithStructFieldAttributesValidator::toString)
.collect(Collectors.joining(", "));
if (!unsupportedFields.isEmpty()) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java
new file mode 100644
index 00000000000..a18ce7e245d
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java
@@ -0,0 +1,72 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.schema.Schema;
+import com.yahoo.schema.document.ImmutableSDField;
+import com.yahoo.vespa.model.VespaModel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Validates that complex fields (of type struct or map) do not have any struct fields with 'indexing: index'.
+ * This is not supported and will confuse the user if not validated.
+ *
+ * Only applies for indexed search clusters.
+ *
+ * @author geirst
+ */
+public class ComplexFieldsWithStructFieldIndexesValidator extends Validator {
+
+ @Override
+ public void validate(VespaModel model, DeployState deployState) {
+ for (var cluster : model.getSearchClusters()) {
+ if (cluster.isStreaming()) {
+ continue;
+ }
+ for (var spec : cluster.schemas().values()) {
+ validateComplexFields(cluster.getClusterName(), spec.fullSchema());
+ }
+ }
+ }
+
+ private static void validateComplexFields(String clusterName, Schema schema) {
+ String unsupportedFields = schema.allFields()
+ .filter(field -> hasStructFieldsWithIndex(field))
+ .map(ComplexFieldsWithStructFieldIndexesValidator::toString)
+ .collect(Collectors.joining(", "));
+
+ if (!unsupportedFields.isEmpty()) {
+ throw new IllegalArgumentException(
+ String.format("For cluster '%s', schema '%s': The following complex fields have struct fields with 'indexing: index' which is not supported: %s. " +
+ "Change to 'indexing: attribute' instead",
+ clusterName, schema.getName(), unsupportedFields));
+ }
+ }
+
+ private static boolean hasStructFieldsWithIndex(ImmutableSDField field) {
+ return (!field.isImportedField() && field.usesStructOrMap() && hasStructFieldsWithIndex(field.getStructFields()));
+ }
+
+ private static String toString(ImmutableSDField field) {
+ return field.getName() + " (" + String.join(", ", getStructFieldsWithIndex(field.getStructFields())) + ")";
+ }
+
+ private static boolean hasStructFieldsWithIndex(Collection<? extends ImmutableSDField> structFields) {
+ return !getStructFieldsWithIndex(structFields).isEmpty();
+ }
+
+ private static List<String> getStructFieldsWithIndex(Collection<? extends ImmutableSDField> structFields) {
+ var result = new ArrayList<String>();
+ for (var structField : structFields) {
+ if (structField.wasConfiguredToDoIndexing()) {
+ result.add(structField.getName());
+ }
+ result.addAll(getStructFieldsWithIndex(structField.getStructFields()));
+ }
+ return result;
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index ce61d3edc3b..dab1eeccc96 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -71,7 +71,8 @@ public class Validation {
new SchemasDirValidator().validate(model, deployState);
new BundleValidator().validate(model, deployState);
new SearchDataTypeValidator().validate(model, deployState);
- new ComplexAttributeFieldsValidator().validate(model, deployState);
+ new ComplexFieldsWithStructFieldAttributesValidator().validate(model, deployState);
+ new ComplexFieldsWithStructFieldIndexesValidator().validate(model, deployState);
new StreamingValidator().validate(model, deployState);
new RankSetupValidator(validationParameters.ignoreValidationErrors()).validate(model, deployState);
new NoPrefixForIndexes().validate(model, deployState);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java
index e2bfcb66f37..96e2e1d5ebd 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java
@@ -230,7 +230,9 @@ public class VespaDomBuilder extends VespaModelBuilder {
deployState.getDocumentModel(),
deployState.getVespaVersion(),
deployState.getProperties().applicationId());
- root.setHostSystem(new HostSystem(root, "hosts", deployState.getProvisioner(), deployState.getDeployLogger()));
+ root.setHostSystem(new HostSystem(root, "hosts", deployState.getProvisioner(),
+ deployState.getDeployLogger(),
+ deployState.isHosted()));
new Client(root);
return root;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index e69872ca1e7..4d45398de90 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -464,14 +464,12 @@ public abstract class ContainerCluster<CONTAINER extends Container>
@Override
public void getConfig(ApplicationMetadataConfig.Builder builder) {
- if (applicationMetaData != null) {
+ if (applicationMetaData != null)
builder.name(applicationMetaData.getApplicationId().application().value()).
- user(applicationMetaData.getDeployedByUser()).
path(applicationMetaData.getDeployPath()).
timestamp(applicationMetaData.getDeployTimestamp()).
checksum(applicationMetaData.getChecksum()).
generation(applicationMetaData.getGeneration());
- }
}
/**
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/docproc/ContainerDocproc.java b/config-model/src/main/java/com/yahoo/vespa/model/container/docproc/ContainerDocproc.java
index fee10b965aa..242f7cbefdb 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/docproc/ContainerDocproc.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/docproc/ContainerDocproc.java
@@ -15,35 +15,26 @@ import java.util.HashMap;
import java.util.Map;
/**
- * @author einarmr
+ * @author Einar M R Rosenvinge
* @author gjoranv
*/
-public class ContainerDocproc extends ContainerSubsystem<DocprocChains>
- implements
- ContainerMbusConfig.Producer,
- SchemamappingConfig.Producer,
- DocprocConfig.Producer
-{
- public final Options options;
-
- // Whether or not to prefer sending to a local node.
- private final boolean preferLocalNode = false;
-
- // The number of nodes to use per client.
- private final int numNodesPerClient = 0;
+public class ContainerDocproc extends ContainerSubsystem<DocprocChains> implements
+ ContainerMbusConfig.Producer,
+ SchemamappingConfig.Producer,
+ DocprocConfig.Producer {
+ public final Options options;
private final Map<Pair<String, String>, String> fieldNameSchemaMap = new HashMap<>();
public ContainerDocproc(ContainerCluster<?> cluster, DocprocChains chains) {
- this(cluster, chains, new Options( null, null, null, null, null, null));
+ this(cluster, chains, Options.empty());
}
public ContainerDocproc(ContainerCluster<?> cluster, DocprocChains chains, Options options) {
this(cluster, chains, options, true);
}
- private void addSource(
- final ContainerCluster<?> cluster, final String name, final SessionConfig.Type.Enum type) {
+ private void addSource(ContainerCluster<?> cluster, String name, SessionConfig.Type.Enum type) {
final MbusClient mbusClient = new MbusClient(name, type);
mbusClient.addClientBindings(SystemBindingPattern.fromPattern("mbus://*/" + mbusClient.getSessionName()));
cluster.addComponent(mbusClient);
@@ -61,14 +52,6 @@ public class ContainerDocproc extends ContainerSubsystem<DocprocChains>
cluster.addSearchAndDocprocBundles();
}
- public boolean isPreferLocalNode() {
- return preferLocalNode;
- }
-
- public int getNumNodesPerClient() {
- return numNodesPerClient;
- }
-
@Override
public void getConfig(ContainerMbusConfig.Builder builder) {
builder.maxpendingcount(getMaxMessagesInQueue());
@@ -79,13 +62,9 @@ public class ContainerDocproc extends ContainerSubsystem<DocprocChains>
return options.maxMessagesInQueue;
}
- //maxmessagesinqueue has not been set for this node. let's try to give a good value anyway:
+ // maxmessagesinqueue has not been set for this node. let's try to give a good value anyway:
return 2048 * getChains().allChains().allComponents().size();
- //intentionally high, getMaxQueueMbSize() will probably kick in before this one!
- }
-
- private Integer getMaxQueueMbSize() {
- return options.maxQueueMbSize;
+ // intentionally high, getMaxQueueMbSize() will probably kick in before this one!
}
private Integer getMaxQueueTimeMs() {
@@ -134,21 +113,22 @@ public class ContainerDocproc extends ContainerSubsystem<DocprocChains>
public static class Options {
public final Integer maxMessagesInQueue;
- public final Integer maxQueueMbSize;
public final Integer maxQueueTimeMs;
public final Double maxConcurrentFactor;
public final Double documentExpansionFactor;
public final Integer containerCoreMemory;
- public Options(Integer maxMessagesInQueue, Integer maxQueueMbSize, Integer maxQueueTimeMs, Double maxConcurrentFactor, Double documentExpansionFactor, Integer containerCoreMemory) {
+ public Options(Integer maxMessagesInQueue, Integer maxQueueTimeMs, Double maxConcurrentFactor, Double documentExpansionFactor, Integer containerCoreMemory) {
this.maxMessagesInQueue = maxMessagesInQueue;
- this.maxQueueMbSize = maxQueueMbSize;
this.maxQueueTimeMs = maxQueueTimeMs;
this.maxConcurrentFactor = maxConcurrentFactor;
this.documentExpansionFactor = documentExpansionFactor;
this.containerCoreMemory = containerCoreMemory;
}
+
+ static Options empty() { return new Options(null, null, null, null, null); }
+
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index a8ce0219434..8f02476b2cc 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -943,7 +943,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addIncludes(docprocElement);
DocprocChains chains = new DomDocprocChainsBuilder(null, false).build(deployState, cluster, docprocElement);
- ContainerDocproc.Options docprocOptions = DocprocOptionsBuilder.build(docprocElement);
+ ContainerDocproc.Options docprocOptions = DocprocOptionsBuilder.build(docprocElement, deployState.getDeployLogger());
return new ContainerDocproc(cluster, chains, docprocOptions, !standaloneBuilder);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocprocOptionsBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocprocOptionsBuilder.java
index e0dffca2bc5..faf2d01d385 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocprocOptionsBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocprocOptionsBuilder.java
@@ -1,17 +1,18 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.xml;
+import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.vespa.model.container.docproc.ContainerDocproc;
import org.w3c.dom.Element;
+import java.util.Set;
+import java.util.logging.Level;
-/**
- * Extracted from DomDocProcClusterBuilder
- */
public class DocprocOptionsBuilder {
- public static ContainerDocproc.Options build(Element spec) {
+ public static ContainerDocproc.Options build(Element spec, DeployLogger deployLogger) {
+ checkForDeprecatedAttributes(spec, Set.of("maxqueuebytesize", "numnodesperclient", "preferlocalnode"), deployLogger);
+
return new ContainerDocproc.Options(
getMaxMessagesInQueue(spec),
- getSizeInMegabytes(spec.getAttribute("maxqueuebytesize")),
getTime(spec.getAttribute("maxqueuewait")),
getFactor(spec.getAttribute("maxconcurrentfactor")),
getFactor(spec.getAttribute("documentexpansionfactor")),
@@ -19,18 +20,17 @@ public class DocprocOptionsBuilder {
}
private static Integer getInt(String integer) {
- return integer == null || integer.trim().isEmpty() ?
- null:
- Integer.parseInt(integer);
+ return integer == null || integer.trim().isEmpty()
+ ? null
+ : Integer.parseInt(integer);
}
private static Double getFactor(String factor) {
- return factor == null || factor.trim().isEmpty() ?
- null :
- Double.parseDouble(factor);
+ return factor == null || factor.trim().isEmpty()
+ ? null
+ : Double.parseDouble(factor);
}
-
private static Integer getMaxMessagesInQueue(Element spec) {
// get max queue size (number of messages), if set
Integer maxMessagesInQueue = null;
@@ -40,28 +40,6 @@ public class DocprocOptionsBuilder {
return maxMessagesInQueue;
}
- private static Integer getSizeInMegabytes(String size) {
- if (size == null) {
- return null;
- }
- size = size.trim();
- if (size.isEmpty()) {
- return null;
- }
-
- Integer megabyteSize;
- if (size.endsWith("m")) {
- size = size.substring(0, size.length() - 1);
- megabyteSize = Integer.parseInt(size);
- } else if (size.endsWith("g")) {
- size = size.substring(0, size.length() - 1);
- megabyteSize = Integer.parseInt(size) * 1024;
- } else {
- throw new IllegalArgumentException("Heap sizes for docproc must be set to Xm or Xg, where X is an integer specifying megabytes or gigabytes, respectively.");
- }
- return megabyteSize;
- }
-
private static Integer getTime(String intStr) {
if (intStr == null) {
return null;
@@ -73,4 +51,13 @@ public class DocprocOptionsBuilder {
return 1000 * (int)Double.parseDouble(intStr);
}
+
+ private static void checkForDeprecatedAttributes(Element spec, Set<String> names, DeployLogger deployLogger) {
+ names.forEach(n -> {
+ if (!spec.getAttribute(n).isEmpty())
+ deployLogger.logApplicationPackage(Level.WARNING, "'" + n + "' is ignored, deprecated and will be removed in Vespa 9.");
+ });
+ }
+
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/routing/DocumentProtocol.java b/config-model/src/main/java/com/yahoo/vespa/model/routing/DocumentProtocol.java
index 754800a42e1..8a8d38e23e3 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/routing/DocumentProtocol.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/routing/DocumentProtocol.java
@@ -182,44 +182,26 @@ public final class DocumentProtocol implements Protocol,
return table;
}
- private static void addContainerClusterDocprocHops(Collection<ContainerCluster<?>> containerClusters,
- RoutingTableSpec table) {
-
+ private static void addContainerClusterDocprocHops(Collection<ContainerCluster<?>> containerClusters, RoutingTableSpec table) {
for (ContainerCluster<?> cluster: containerClusters) {
ContainerDocproc docproc = cluster.getDocproc();
if (docproc != null) {
- String policy = policy(docproc);
-
for (DocprocChain chain : docproc.getChains().allChains().allComponents()) {
- addChainHop(table, cluster.getConfigId(), policy, chain);
+ addChainHop(table, cluster.getConfigId(), chain);
}
}
}
}
- private static void addChainHop(RoutingTableSpec table, String configId, String policy, DocprocChain chain) {
- final StringBuilder selector = new StringBuilder();
- if (policy != null) {
- selector.append(configId).append("/").append(policy).append("/").append(chain.getSessionName());
- } else {
- selector.append("[LoadBalancer:cluster=").append(configId)
- .append(";session=").append(chain.getSessionName())
- .append("]");
- }
+ private static void addChainHop(RoutingTableSpec table, String configId, DocprocChain chain) {
+ StringBuilder selector = new StringBuilder();
+ selector.append("[LoadBalancer:cluster=").append(configId)
+ .append(";session=").append(chain.getSessionName())
+ .append("]");
table.addHop(new HopSpec(chain.getServiceName(), selector.toString()));
}
- private static String policy(ContainerDocproc docproc) {
- if (docproc.getNumNodesPerClient() > 0) {
- return "[SubsetService:" + docproc.getNumNodesPerClient() + "]";
- } else if (docproc.isPreferLocalNode()) {
- return "[LocalService]";
- } else {
- return null;
- }
- }
-
/**
* Create hops to all configured storage nodes for the Document protocol. The "Distributor" policy resolves its
* recipients using slobrok lookups, so it requires no configured recipients.
@@ -228,23 +210,22 @@ public final class DocumentProtocol implements Protocol,
* @param table the routing table to add to
*/
private static void addContentRouting(List<ContentCluster> content, RoutingTableSpec table) {
-
- for (ContentCluster cluster : content) {
- RouteSpec spec = new RouteSpec(cluster.getConfigId());
-
- if (cluster.getSearch().hasIndexedCluster()) {
- table.addRoute(spec.addHop("[MessageType:" + cluster.getConfigId() + "]"));
- table.addRoute(new RouteSpec(getIndexedRouteName(cluster.getConfigId()))
- .addHop(cluster.getSearch().getIndexed().getIndexingServiceName())
- .addHop("[Content:cluster=" + cluster.getName() + "]"));
- table.addRoute(new RouteSpec(getDirectRouteName(cluster.getConfigId()))
- .addHop("[Content:cluster=" + cluster.getName() + "]"));
- } else {
- table.addRoute(spec.addHop("[Content:cluster=" + cluster.getName() + "]"));
- }
- table.addRoute(new RouteSpec("storage/cluster." + cluster.getName())
- .addHop("route:" + cluster.getConfigId()));
+ for (ContentCluster cluster : content) {
+ RouteSpec spec = new RouteSpec(cluster.getConfigId());
+
+ if (cluster.getSearch().hasIndexedCluster()) {
+ table.addRoute(spec.addHop("[MessageType:" + cluster.getConfigId() + "]"));
+ table.addRoute(new RouteSpec(getIndexedRouteName(cluster.getConfigId()))
+ .addHop(cluster.getSearch().getIndexed().getIndexingServiceName())
+ .addHop("[Content:cluster=" + cluster.getName() + "]"));
+ table.addRoute(new RouteSpec(getDirectRouteName(cluster.getConfigId()))
+ .addHop("[Content:cluster=" + cluster.getName() + "]"));
+ } else {
+ table.addRoute(spec.addHop("[Content:cluster=" + cluster.getName() + "]"));
}
+ table.addRoute(new RouteSpec("storage/cluster." + cluster.getName())
+ .addHop("route:" + cluster.getConfigId()));
+ }
}
/**
@@ -255,9 +236,8 @@ public final class DocumentProtocol implements Protocol,
* @param table the routing table to add to
*/
private static void addIndexingHop(List<ContentCluster> content, RoutingTableSpec table) {
- if (content.isEmpty()) {
- return;
- }
+ if (content.isEmpty()) return;
+
HopSpec hop = new HopSpec("indexing", "[DocumentRouteSelector]");
for (ContentCluster cluster : content) {
hop.addRecipient(cluster.getConfigId());
@@ -281,9 +261,8 @@ public final class DocumentProtocol implements Protocol,
private static void addDefaultRoutes(List<ContentCluster> content,
Collection<ContainerCluster<?>> containerClusters,
RoutingTableSpec table) {
- if (content.isEmpty() || !indexingHopExists(table)) {
- return;
- }
+ if (content.isEmpty() || !indexingHopExists(table)) return;
+
RouteSpec route = new RouteSpec("default");
String hop = getContainerClustersDocprocHop(containerClusters);
if (hop != null) {
@@ -326,9 +305,9 @@ public final class DocumentProtocol implements Protocol,
}
private static DocprocChain getDefaultChain(ContainerDocproc docproc) {
- return docproc == null ?
- null:
- docproc.getChains().allChains().getComponent("default");
+ return docproc == null
+ ? null
+ : docproc.getChains().allChains().getComponent("default");
}
/**
diff --git a/config-model/src/main/resources/schema/docproc.rnc b/config-model/src/main/resources/schema/docproc.rnc
index 42902f7180f..11f8e14fb2d 100644
--- a/config-model/src/main/resources/schema/docproc.rnc
+++ b/config-model/src/main/resources/schema/docproc.rnc
@@ -11,9 +11,6 @@ SchemaMapping = element map {
}+
}
-
-
-
#Version 3 config:
DocProcV3 = attribute version { "3.0" },
@@ -24,10 +21,10 @@ DocProcV3 = attribute version { "3.0" },
# TODO Here we need a thorough cleaning
DocprocClusterAttributes = attribute compressdocuments { xsd:boolean }? &
- attribute numnodesperclient { xsd:positiveInteger }? &
- attribute preferlocalnode { xsd:boolean }? &
+ attribute numnodesperclient { xsd:positiveInteger }? & # TODO: Remove in Vespa 9
+ attribute preferlocalnode { xsd:boolean }? & # TODO: Remove in Vespa 9
attribute maxmessagesinqueue { xsd:nonNegativeInteger }? &
- attribute maxqueuebytesize { xsd:string { minLength = "1" } }? &
+ attribute maxqueuebytesize { xsd:string { minLength = "1" } }? & # TODO: Remove in Vespa 9
attribute maxqueuewait { xsd:positiveInteger }? &
attribute maxconcurrentfactor { xsd:double { minExclusive = "0.0" maxExclusive = "1.0" } }? &
attribute documentexpansionfactor { xsd:double { minExclusive = "0.0" } }? &
diff --git a/config-model/src/test/derived/imported_struct_fields/summarymap.cfg b/config-model/src/test/derived/imported_struct_fields/summarymap.cfg
index cd19a75e85f..653b0a26b75 100644
--- a/config-model/src/test/derived/imported_struct_fields/summarymap.cfg
+++ b/config-model/src/test/derived/imported_struct_fields/summarymap.cfg
@@ -1,4 +1,7 @@
defaultoutputclass -1
+override[].field "documentid"
+override[].command "documentid"
+override[].arguments ""
override[].field "my_elem_array"
override[].command "attributecombiner"
override[].arguments ""
diff --git a/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java b/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java
index 57a61e40d89..ec5850b95b9 100644
--- a/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java
@@ -227,8 +227,7 @@ public class ApplicationDeployTest {
String appPkg = TESTDIR + "app1";
IOUtils.copyDirectory(new File(appPkg), tmp);
ApplicationId applicationId = ApplicationId.from("tenant1", "application1", "instance1");
- DeployData deployData = new DeployData("foo",
- "bar",
+ DeployData deployData = new DeployData("bar",
applicationId,
13L,
false,
@@ -238,7 +237,6 @@ public class ApplicationDeployTest {
app.writeMetaData();
FilesApplicationPackage newApp = FilesApplicationPackage.fromFileWithDeployData(tmp, deployData);
ApplicationMetaData meta = newApp.getMetaData();
- assertEquals("foo", meta.getDeployedByUser());
assertEquals("bar", meta.getDeployPath());
assertEquals(applicationId, meta.getApplicationId());
assertEquals(13L, (long)meta.getDeployTimestamp());
diff --git a/config-model/src/test/java/com/yahoo/schema/derived/SummaryMapTestCase.java b/config-model/src/test/java/com/yahoo/schema/derived/SummaryMapTestCase.java
index f0fc58b97e5..2f1b837554d 100644
--- a/config-model/src/test/java/com/yahoo/schema/derived/SummaryMapTestCase.java
+++ b/config-model/src/test/java/com/yahoo/schema/derived/SummaryMapTestCase.java
@@ -162,23 +162,42 @@ public class SummaryMapTestCase extends AbstractSchemaTestCase {
assertFalse(SummaryMap.isDynamicCommand(SummaryTransform.ATTRIBUTE.getName()));
}
+ @Test
+ public void documentid_summary_field_has_corresponding_summary_transform() throws ParseException {
+ var schema = buildSchema("field foo type string { indexing: summary }",
+ joinLines("document-summary bar {",
+ " summary documentid type string {}",
+ "}"));
+ assertOverride(schema, "documentid", SummaryTransform.DOCUMENT_ID.getName(), "");
+ }
+
+ @Test
+ public void documentid_summary_transform_requires_disk_access() {
+ assertFalse(SummaryTransform.DOCUMENT_ID.isInMemory());
+ }
+
private void assertOverride(String fieldContent, String expFieldName, String expCommand) throws ParseException {
- var summaryMap = new SummaryMap(buildSearch(fieldContent));
+ assertOverride(buildSchema(fieldContent, ""), expFieldName, expCommand, expFieldName);
+ }
+
+ private void assertOverride(Schema schema, String expFieldName, String expCommand, String expArguments) throws ParseException {
+ var summaryMap = new SummaryMap(schema);
var cfgBuilder = new SummarymapConfig.Builder();
summaryMap.getConfig(cfgBuilder);
var cfg = new SummarymapConfig(cfgBuilder);
var override = cfg.override(0);
assertEquals(expFieldName, override.field());
assertEquals(expCommand, override.command());
- assertEquals(expFieldName, override.arguments());
+ assertEquals(expArguments, override.arguments());
}
- private Schema buildSearch(String field) throws ParseException {
+ private Schema buildSchema(String field, String documentSummary) throws ParseException {
var builder = new ApplicationBuilder(new RankProfileRegistry());
builder.addSchema(joinLines("search test {",
" document test {",
field,
" }",
+ documentSummary,
"}"));
builder.build(true);
return builder.getSchema();
diff --git a/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionTypeResolverTestCase.java b/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionTypeResolverTestCase.java
index 4b6a22fc81a..f2f2a82b97c 100644
--- a/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionTypeResolverTestCase.java
+++ b/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionTypeResolverTestCase.java
@@ -456,7 +456,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.build(true);
String message = logger.findMessage("The following query features");
assertNotNull(message);
- assertEquals("WARNING: The following query features used in rank profile 'my_rank_profile' are not declared in query profile types and " +
+ assertEquals("WARNING: The following query features used in rank profile 'my_rank_profile' are not declared and " +
"will be interpreted as scalars, not tensors: [query(bar), query(baz), query(foo)]",
message);
}
diff --git a/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionWithOnnxTestCase.java b/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionWithOnnxTestCase.java
index 94a51d25717..bfd0520c62a 100644
--- a/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionWithOnnxTestCase.java
+++ b/config-model/src/test/java/com/yahoo/schema/processing/RankingExpressionWithOnnxTestCase.java
@@ -391,7 +391,7 @@ public class RankingExpressionWithOnnxTestCase {
@Override
public ApplicationFile getFile(Path file) {
- return new MockApplicationFile(file, Path.fromString(root().toString()));
+ return new MockApplicationFile(file, root());
}
@Override
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java
index d50aedeafa0..b3860459323 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java
@@ -64,7 +64,6 @@ public class MetricsProxyContainerClusterTest {
ApplicationMetadataConfig config = builder.build();
assertEquals(MockApplicationPackage.APPLICATION_GENERATION, config.generation());
assertEquals(MockApplicationPackage.APPLICATION_NAME, config.name());
- assertEquals(MockApplicationPackage.DEPLOYED_BY_USER, config.user());
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexFieldsValidatorTestCase.java
index 85050aa0cf9..11e4ae855a5 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexFieldsValidatorTestCase.java
@@ -22,7 +22,7 @@ import static com.yahoo.config.model.test.TestUtil.joinLines;
/**
* @author geirst
*/
-public class ComplexAttributeFieldsValidatorTestCase {
+public class ComplexFieldsValidatorTestCase {
@SuppressWarnings("deprecation")
@Rule
@@ -78,6 +78,30 @@ public class ComplexAttributeFieldsValidatorTestCase {
}
@Test
+ public void throws_when_complex_fields_have_struct_fields_with_index() throws IOException, SAXException {
+ exceptionRule.expect(IllegalArgumentException.class);
+ exceptionRule.expectMessage("For cluster 'mycluster', schema 'test': " +
+ "The following complex fields have struct fields with 'indexing: index' which is not supported: " +
+ "topics (topics.id, topics.label). Change to 'indexing: attribute' instead");
+ createModelAndValidate(joinLines(
+ "schema test {",
+ "document test {",
+ "struct topic {",
+ " field id type string {}",
+ " field label type string {}",
+ " field desc type string {}",
+ "}",
+ "field topics type array<topic> {",
+ " indexing: summary",
+ " struct-field id { indexing: index }",
+ " struct-field label { indexing: index | attribute }",
+ " struct-field desc { indexing: attribute }",
+ "}",
+ "}",
+ "}"));
+ }
+
+ @Test
public void validation_passes_when_only_supported_struct_field_attributes_are_used() throws IOException, SAXException {
createModelAndValidate(joinLines("search test {",
" document test {",
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/DocprocBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/DocprocBuilderTest.java
index 2044fd2ab39..eee421e8037 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/DocprocBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/DocprocBuilderTest.java
@@ -27,11 +27,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-
/**
- * @author einarmr
+ * @author Einar M R Rosenvinge
* @author gjoranv
- * @since 5.1.9
*/
public class DocprocBuilderTest extends DomBuilderTest {
@@ -64,7 +62,7 @@ public class DocprocBuilderTest extends DomBuilderTest {
" <nodes>",
" <node hostalias='mockhost' baseport='1500' />",
" </nodes>",
- " <document-processing preferlocalnode='true' numnodesperclient='2' maxqueuebytesize='100m' maxmessagesinqueue='300' maxqueuewait='200'>",
+ " <document-processing maxmessagesinqueue='300' maxqueuewait='200'>",
" <documentprocessor id='docproc1' class='com.yahoo.Docproc1' bundle='docproc1bundle'/>",
" <chain id='chein'>",
" <documentprocessor id='docproc2'/>",
@@ -73,12 +71,9 @@ public class DocprocBuilderTest extends DomBuilderTest {
"</container>");
}
- // TODO: re-enable assertions when the appropriate attributes are handled by the builder
@Test
public void testDocprocCluster() {
assertEquals("banan", cluster.getName());
- //assertTrue(cluster.getContainerDocproc().isPreferLocalNode());
- //assertEquals(2, cluster.getContainerDocproc().getNumNodesPerClient());
List<ApplicationContainer> services = cluster.getContainers();
assertEquals(1, services.size());
ApplicationContainer service = services.get(0);