diff options
author | Geir Storli <geirst@oath.com> | 2018-06-14 17:00:57 +0200 |
---|---|---|
committer | Geir Storli <geirst@oath.com> | 2018-06-14 17:00:57 +0200 |
commit | d99c687658dfc89522d6af953fb74abfbc820078 (patch) | |
tree | a7e6d6c2011e930dabe2fed6df1bc4076522997c /config-model/src/main/java/com | |
parent | 27b64a81a6a133976bd17385eb150e34added12d (diff) |
Validate that complex fields that have struct field attributes are supported.
This only applies for indexed search clusters.
Diffstat (limited to 'config-model/src/main/java/com')
3 files changed, 92 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java index 857959d0678..72eb1c96e0f 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java @@ -31,6 +31,12 @@ public class ComplexAttributeFieldUtils { isMapOfPrimitiveType(field)); } + public static boolean isSupportedComplexField(DataType fieldType) { + return (isArrayOfSimpleStruct(fieldType) || + isMapOfSimpleStruct(fieldType) || + isMapOfPrimitiveType(fieldType)); + } + public static boolean isArrayOfSimpleStruct(ImmutableSDField field, SDDocumentType docType) { return isArrayOfSimpleStruct(field.getDataType(), Optional.of(docType)); } 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/ComplexAttributeFieldsValidator.java new file mode 100644 index 00000000000..005c1dd8b2e --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java @@ -0,0 +1,85 @@ +// Copyright 2018 Yahoo Holdings. 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.document.DataType; +import com.yahoo.document.PositionDataType; +import com.yahoo.searchdefinition.Search; +import com.yahoo.searchdefinition.document.ComplexAttributeFieldUtils; +import com.yahoo.searchdefinition.document.ImmutableSDField; +import com.yahoo.vespa.model.VespaModel; +import com.yahoo.vespa.model.search.AbstractSearchCluster; +import com.yahoo.vespa.model.search.SearchCluster; +import org.apache.commons.lang.StringUtils; + +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) that have struct field attributes are supported. + * + * Only applies for indexed search clusters. + * + * @author geirst + */ +public class ComplexAttributeFieldsValidator extends Validator { + + @Override + public void validate(VespaModel model, DeployState deployState) { + List<AbstractSearchCluster> searchClusters = model.getSearchClusters(); + for (AbstractSearchCluster cluster : searchClusters) { + if (cluster.isStreaming()) { + continue; + } + SearchCluster searchCluster = (SearchCluster) cluster; + for (AbstractSearchCluster.SearchDefinitionSpec spec : searchCluster.getLocalSDS()) { + validateComplexFields(searchCluster.getClusterName(), spec.getSearchDefinition().getSearch()); + } + } + } + + private static void validateComplexFields(String clusterName, Search search) { + String unsupportedFields = search.allFields() + .filter(field -> isUnsupportedComplexField(field)) + .map(ComplexAttributeFieldsValidator::toString) + .collect(Collectors.joining(", ")); + + if (!unsupportedFields.isEmpty()) { + throw new IllegalArgumentException( + String.format("For cluster '%s', search '%s': The following complex fields do not support using struct field attributes: %s. " + + "Only supported for the following complex field types: array or map of struct with primitive types, map of primitive types", + clusterName, search.getName(), unsupportedFields)); + } + } + + private static boolean isUnsupportedComplexField(ImmutableSDField field) { + return (field.usesStructOrMap() && + !isSupportedComplexField(field) && + hasStructFieldAttributes(field.getStructFields())); + } + + private static boolean isSupportedComplexField(ImmutableSDField field) { + return (ComplexAttributeFieldUtils.isSupportedComplexField(field.getDataType()) || + field.getDataType().equals(PositionDataType.INSTANCE) || + field.getDataType().equals(DataType.getArray(PositionDataType.INSTANCE))); + } + + private static String toString(ImmutableSDField field) { + return field.getName() + " (" + StringUtils.join(getStructFieldAttributes(field.getStructFields()), ", ") + ")"; + } + + private static boolean hasStructFieldAttributes(Collection<? extends ImmutableSDField> structFields) { + return !getStructFieldAttributes(structFields).isEmpty(); + } + + private static List<String> getStructFieldAttributes(Collection<? extends ImmutableSDField> structFields) { + List<String> result = new ArrayList<>(); + for (ImmutableSDField structField : structFields) { + structField.getAttributes().values().forEach(attr -> result.add(attr.getName())); + result.addAll(getStructFieldAttributes(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 523ced52306..c08e81b250f 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 @@ -52,6 +52,7 @@ public class Validation { } new ComponentValidator().validate(model, deployState); new SearchDataTypeValidator().validate(model, deployState); + new ComplexAttributeFieldsValidator().validate(model, deployState); new StreamingValidator().validate(model, deployState); new RankSetupValidator(force).validate(model, deployState); new NoPrefixForIndexes().validate(model, deployState); |