diff options
Diffstat (limited to 'config-model/src/main/java/com')
16 files changed, 87 insertions, 165 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java index 937d511bb09..c19865fafc9 100644 --- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java +++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java @@ -341,7 +341,7 @@ public class DeployState implements ConfigDefinitionStore { public DeployState build(ValidationParameters validationParameters) { RankProfileRegistry rankProfileRegistry = new RankProfileRegistry(); - QueryProfiles queryProfiles = new QueryProfilesBuilder().build(applicationPackage); + QueryProfiles queryProfiles = new QueryProfilesBuilder().build(applicationPackage, logger); SemanticRules semanticRules = new SemanticRuleBuilder().build(applicationPackage); SearchDocumentModel searchDocumentModel = createSearchDocumentModel(rankProfileRegistry, logger, queryProfiles, validationParameters); return new DeployState(applicationPackage, diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/FeatureNames.java b/config-model/src/main/java/com/yahoo/searchdefinition/FeatureNames.java index 2f41b172ab6..1e133d0b8f4 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/FeatureNames.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/FeatureNames.java @@ -34,6 +34,12 @@ public class FeatureNames { return name.equals("attribute") || name.equals("constant") || name.equals("query"); } + /** Returns true if this is a constant */ + public static boolean isConstantFeature(Reference reference) { + if ( ! isSimpleFeature(reference)) return false; + return reference.name().equals("constant"); + } + /** * Returns the single argument of the given feature name, without any quotes, * or empty if it is not a valid query, attribute or constant feature name diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java index b3853b36aa5..d738929f721 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java @@ -756,7 +756,7 @@ public class RankProfile implements Serializable, Cloneable { for (FieldDescription field : queryProfileType.declaredFields().values()) { TensorType type = field.getType().asTensorType(); Optional<Reference> feature = Reference.simple(field.getName()); - if ( ! feature.isPresent() || ! feature.get().name().equals("query")) continue; + if ( feature.isEmpty() || ! feature.get().name().equals("query")) continue; TensorType existingType = context.getType(feature.get()); if ( ! Objects.equals(existingType, context.defaultTypeOf(feature.get()))) diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java b/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java index bd4daa58253..6481d42446f 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java @@ -8,7 +8,9 @@ import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.document.DocumentTypeManager; import com.yahoo.io.IOUtils; import com.yahoo.io.reader.NamedReader; +import com.yahoo.search.query.profile.QueryProfile; import com.yahoo.search.query.profile.QueryProfileRegistry; +import com.yahoo.search.query.profile.config.QueryProfileXMLReader; import com.yahoo.searchdefinition.derived.SearchOrderer; import com.yahoo.searchdefinition.document.SDDocumentType; import com.yahoo.searchdefinition.parser.ParseException; @@ -246,7 +248,7 @@ public class SearchBuilder { DocumentModelBuilder builder = new DocumentModelBuilder(model); for (Search search : new SearchOrderer().order(searchList)) { new FieldOperationApplierForSearch().process(search); // TODO: Why is this not in the regular list? - process(search, deployLogger, new QueryProfiles(queryProfileRegistry), validate); + process(search, deployLogger, new QueryProfiles(queryProfileRegistry, deployLogger), validate); built.add(search); } builder.addToModel(searchList); @@ -394,7 +396,11 @@ public class SearchBuilder { } public static SearchBuilder createFromDirectory(String dir) throws IOException, ParseException { - return createFromDirectory(dir, new RankProfileRegistry(), new QueryProfileRegistry()); + return createFromDirectory(dir, new RankProfileRegistry()); + } + public static SearchBuilder createFromDirectory(String dir, + RankProfileRegistry rankProfileRegistry) throws IOException, ParseException { + return createFromDirectory(dir, rankProfileRegistry, createQueryProfileRegistryFromDirectory(dir)); } public static SearchBuilder createFromDirectory(String dir, RankProfileRegistry rankProfileRegistry, @@ -409,6 +415,12 @@ public class SearchBuilder { return builder; } + private static QueryProfileRegistry createQueryProfileRegistryFromDirectory(String dir) { + File queryProfilesDir = new File(dir, "query-profiles"); + if ( ! queryProfilesDir.exists()) return new QueryProfileRegistry(); + return new QueryProfileXMLReader().read(queryProfilesDir.toString()); + } + // TODO: The build methods below just call the create methods above - remove /** diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ConstantTensorTransformer.java b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ConstantTensorTransformer.java index caf5f0442eb..6991e2b978b 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ConstantTensorTransformer.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ConstantTensorTransformer.java @@ -49,13 +49,13 @@ public class ConstantTensorTransformer extends ExpressionTransformer<RankProfile } private ExpressionNode transformConstantReference(ReferenceNode node, RankProfileTransformContext context) { - Reference constantReference = FeatureNames.asConstantFeature(node.getName()); + Reference constantReference = node.reference(); + if ( ! FeatureNames.isConstantFeature(constantReference) && constantReference.isIdentifier()) + constantReference = FeatureNames.asConstantFeature(node.getName()); + Value value = context.constants().get(node.getName()); - if (value == null || value.type().rank() == 0) { - if (context.rankProfile().rankingConstants().get(node.getName()) != null) // Large constants: Transform reference but don't add value - return new ReferenceNode(constantReference); - return node; - } + if (value == null || value.type().rank() == 0) return node; + TensorValue tensorValue = (TensorValue)value; String tensorType = tensorValue.asTensor().type().toString(); context.rankProperties().put(constantReference.toString() + ".value", tensorValue.toString()); diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ExpressionTransforms.java b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ExpressionTransforms.java index cbabfffb7a1..6fdf448a39b 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ExpressionTransforms.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/ExpressionTransforms.java @@ -6,6 +6,7 @@ import com.yahoo.searchlib.rankingexpression.RankingExpression; import com.yahoo.searchlib.rankingexpression.transform.ConstantDereferencer; import com.yahoo.searchlib.rankingexpression.transform.ExpressionTransformer; import com.yahoo.searchlib.rankingexpression.transform.Simplifier; +import com.yahoo.searchlib.rankingexpression.transform.TensorMaxMinTransformer; import java.util.List; @@ -30,7 +31,7 @@ public class ExpressionTransforms { new ConstantTensorTransformer(), new FunctionInliner(), new FunctionShadower(), - new TensorTransformer(), + new TensorMaxMinTransformer(), new Simplifier()); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/RankProfileTransformContext.java b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/RankProfileTransformContext.java index 2c0e1eaa56a..630c8644eb1 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/RankProfileTransformContext.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/RankProfileTransformContext.java @@ -24,19 +24,17 @@ public class RankProfileTransformContext extends TransformContext { private final ImportedMlModels importedModels; private final Map<String, RankProfile.RankingExpressionFunction> inlineFunctions; private final Map<String, String> rankProperties = new HashMap<>(); - private final MapEvaluationTypeContext types; public RankProfileTransformContext(RankProfile rankProfile, QueryProfileRegistry queryProfiles, ImportedMlModels importedModels, Map<String, Value> constants, Map<String, RankProfile.RankingExpressionFunction> inlineFunctions) { - super(constants); + super(constants, rankProfile.typeContext(queryProfiles)); this.rankProfile = rankProfile; this.queryProfiles = queryProfiles; this.importedModels = importedModels; this.inlineFunctions = inlineFunctions; - this.types = rankProfile.typeContext(queryProfiles); } public RankProfile rankProfile() { return rankProfile; } @@ -45,10 +43,4 @@ public class RankProfileTransformContext extends TransformContext { public Map<String, RankProfile.RankingExpressionFunction> inlineFunctions() { return inlineFunctions; } public Map<String, String> rankProperties() { return rankProperties; } - /** - * Returns the types known in this context. We may have type information for references - * for which no value is available - */ - public MapEvaluationTypeContext types() { return types; } - } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorTransformer.java b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorTransformer.java deleted file mode 100644 index 5d03c323803..00000000000 --- a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorTransformer.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.searchdefinition.expressiontransforms; - -import com.yahoo.searchdefinition.RankProfile; -import com.yahoo.searchdefinition.RankingConstant; -import com.yahoo.searchdefinition.document.Attribute; -import com.yahoo.searchlib.rankingexpression.Reference; -import com.yahoo.searchlib.rankingexpression.evaluation.Context; -import com.yahoo.searchlib.rankingexpression.evaluation.DoubleValue; -import com.yahoo.searchlib.rankingexpression.evaluation.MapContext; -import com.yahoo.searchlib.rankingexpression.evaluation.StringValue; -import com.yahoo.searchlib.rankingexpression.evaluation.TensorValue; -import com.yahoo.searchlib.rankingexpression.evaluation.Value; -import com.yahoo.searchlib.rankingexpression.rule.CompositeNode; -import com.yahoo.searchlib.rankingexpression.rule.ExpressionNode; -import com.yahoo.searchlib.rankingexpression.rule.FunctionNode; -import com.yahoo.searchlib.rankingexpression.rule.NameNode; -import com.yahoo.searchlib.rankingexpression.rule.ReferenceNode; -import com.yahoo.searchlib.rankingexpression.rule.TensorFunctionNode; -import com.yahoo.searchlib.rankingexpression.transform.ExpressionTransformer; -import com.yahoo.tensor.Tensor; -import com.yahoo.tensor.TensorType; -import com.yahoo.tensor.evaluation.TypeContext; -import com.yahoo.tensor.functions.Reduce; - -import java.util.List; -import java.util.Optional; - -/** - * Transforms and simplifies tensor expressions. - * - * Currently transforms min(tensor,dim) and max(tensor,dim) to - * reduce(tensor,min/max,dim). This is necessary as the backend does - * not recognize these forms of min and max. - * - * @author lesters - */ -public class TensorTransformer extends ExpressionTransformer<RankProfileTransformContext> { - - @Override - public ExpressionNode transform(ExpressionNode node, RankProfileTransformContext context) { - if (node instanceof CompositeNode) { - node = transformChildren((CompositeNode) node, context); - } - if (node instanceof FunctionNode) { - node = transformFunctionNode((FunctionNode) node, context); - } - return node; - } - - private ExpressionNode transformFunctionNode(FunctionNode node, RankProfileTransformContext context) { - switch (node.getFunction()) { - case min: - case max: - return transformMaxAndMinFunctionNode(node, context); - } - return node; - } - - /** - * Transforms max and min functions if the first - * argument returns a tensor type and the second argument is a valid - * dimension in the tensor. - */ - private ExpressionNode transformMaxAndMinFunctionNode(FunctionNode node, RankProfileTransformContext context) { - if (node.children().size() != 2) { - return node; - } - ExpressionNode arg1 = node.children().get(0); - Optional<String> dimension = dimensionName(node.children().get(1)); - if (dimension.isPresent()) { - TensorType type = arg1.type(context.types()); - if (type.dimension(dimension.get()).isPresent()) { - return replaceMaxAndMinFunction(node); - } - } - return node; - } - - private Optional<String> dimensionName(ExpressionNode node) { - if (node instanceof ReferenceNode) { - Reference reference = ((ReferenceNode)node).reference(); - if (reference.isIdentifier()) - return Optional.of(reference.name()); - else - return Optional.empty(); - } - else if (node instanceof NameNode) { - return Optional.of(((NameNode)node).getValue()); - } - else { - return Optional.empty(); - } - } - - private ExpressionNode replaceMaxAndMinFunction(FunctionNode node) { - ExpressionNode arg1 = node.children().get(0); - ExpressionNode arg2 = node.children().get(1); - - TensorFunctionNode.TensorFunctionExpressionNode expression = TensorFunctionNode.wrapArgument(arg1); - Reduce.Aggregator aggregator = Reduce.Aggregator.valueOf(node.getFunction().name()); - String dimension = ((ReferenceNode) arg2).getName(); - - return new TensorFunctionNode(new Reduce(expression, aggregator, dimension)); - } - -} diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java index 233075155b5..e75547a5bb2 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/AddExtraFieldsToDocument.java @@ -21,10 +21,15 @@ import com.yahoo.vespa.model.container.search.QueryProfiles; */ public class AddExtraFieldsToDocument extends Processor { - public AddExtraFieldsToDocument(Search search, DeployLogger deployLogger, RankProfileRegistry rankProfileRegistry, QueryProfiles queryProfiles) { + AddExtraFieldsToDocument(Search search, DeployLogger deployLogger, RankProfileRegistry rankProfileRegistry, QueryProfiles queryProfiles) { super(search, deployLogger, rankProfileRegistry, queryProfiles); } + //TODO This is a tempoarry hack to avoid producing illegal code for fields not wanted anyway. + private boolean dirtyLegalFieldNameCheck(String fieldName) { + return ! fieldName.contains(".") && !"rankfeatures".equals(fieldName) && !"summaryfeatures".equals(fieldName); + } + @Override public void process(boolean validate, boolean documentsOnly) { SDDocumentType document = search.getDocument(); @@ -32,8 +37,11 @@ public class AddExtraFieldsToDocument extends Processor { for (Field field : search.extraFieldList()) { addSdField(search, document, (SDField)field, validate); } + //TODO Vespa 8 or sooner we should avoid the dirty addition of fields from dirty 'default' summary to document at all for (SummaryField field : search.getSummary("default").getSummaryFields()) { - addSummaryField(search, document, field, validate); + if (dirtyLegalFieldNameCheck(field.getName())) { + addSummaryField(search, document, field, validate); + } } } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java index 44c10b0738b..03c8055dd12 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java @@ -221,7 +221,9 @@ public class Admin extends AbstractConfigProducer implements Serializable { metricsProxyCluster = new MetricsProxyContainerCluster(this, "metrics", deployState); int index = 0; for (var host : hosts) { - var container = new MetricsProxyContainer(metricsProxyCluster, index++, deployState.isHosted()); + // Send hostname to be used in configId (instead of index), as the sorting of hosts seems to be unstable + // between config changes, even when the set of hosts is unchanged. + var container = new MetricsProxyContainer(metricsProxyCluster, host.getHostname(), index, deployState.isHosted()); addAndInitializeService(deployState.getDeployLogger(), host, container); metricsProxyCluster.addContainer(container); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java index e683b70bbde..3bc38cad1d1 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java @@ -45,8 +45,8 @@ public class MetricsProxyContainer extends Container implements private final boolean isHostedVespa; - public MetricsProxyContainer(AbstractConfigProducer parent, int index, boolean isHostedVespa) { - super(parent, "metricsproxy." + index, index); + public MetricsProxyContainer(AbstractConfigProducer parent, String hostname, int index, boolean isHostedVespa) { + super(parent, hostname, index); this.isHostedVespa = isHostedVespa; setProp("clustertype", "admin"); setProp("index", String.valueOf(index)); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java index fcc8cc8fa41..aa793b3c6a2 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java @@ -5,7 +5,6 @@ import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ConfigModelContext; import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.deploy.DeployState; -import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.log.LogLevel; import com.yahoo.vespa.model.HostResource; @@ -22,7 +21,6 @@ import org.w3c.dom.Element; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -33,8 +31,6 @@ import java.util.stream.Collectors; */ public class DomAdminV4Builder extends DomAdminBuilderBase { - private ApplicationId ZONE_APPLICATION_ID = ApplicationId.from("hosted-vespa", "routing", "default"); - private final Collection<ContainerModel> containerModels; private final ConfigModelContext context; @@ -134,34 +130,17 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { * @param minHostsPerContainerCluster the desired number of hosts per cluster */ private List<HostResource> pickContainerHostsForSlobrok(int count, int minHostsPerContainerCluster) { - Collection<ContainerModel> containerModelsWithSlobrok = containerModels.stream() - .filter(this::shouldHaveSlobrok) - .collect(Collectors.toList()); int hostsPerCluster = (int) Math.max(minHostsPerContainerCluster, - Math.ceil((double) count / containerModelsWithSlobrok.size())); + Math.ceil((double) count / containerModels.size())); // Pick from all container clusters to make sure we don't lose all nodes at once if some clusters are removed. // This will overshoot the desired size (due to ceil and picking at least one node per cluster). List<HostResource> picked = new ArrayList<>(); - for (ContainerModel containerModel : containerModelsWithSlobrok) + for (ContainerModel containerModel : containerModels) picked.addAll(pickContainerHostsFrom(containerModel, hostsPerCluster)); return picked; } - private boolean shouldHaveSlobrok(ContainerModel containerModel) { - // Avoid Slobroks on node-admin container cluster, as node-admin is migrating - // TODO: Remove after removing tenant hosts from zone-app - - ApplicationId applicationId = context.getDeployState().getProperties().applicationId(); - if (!applicationId.equals(ZONE_APPLICATION_ID)) { - return true; - } - - // aka clustername, aka application-model's ClusterId - String clustername = containerModel.getCluster().getName(); - return !Objects.equals(clustername, "node-admin"); - } - private List<HostResource> pickContainerHostsFrom(ContainerModel model, int count) { boolean retired = true; List<HostResource> picked = sortedContainerHostsFrom(model, count, !retired); 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 47adac637ee..a8f0f5941b0 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 @@ -37,6 +37,7 @@ import com.yahoo.search.config.QrStartConfig; import com.yahoo.search.pagetemplates.PageTemplatesConfig; import com.yahoo.search.query.profile.config.QueryProfilesConfig; import com.yahoo.vespa.configdefinition.IlscriptsConfig; +import com.yahoo.vespa.defaults.Defaults; import com.yahoo.vespa.model.PortsMeta; import com.yahoo.vespa.model.Service; import com.yahoo.vespa.model.admin.monitoring.Monitoring; @@ -63,6 +64,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -190,6 +192,7 @@ public abstract class ContainerCluster<CONTAINER extends Container> addSimpleComponent("com.yahoo.container.handler.VipStatus"); addSimpleComponent(com.yahoo.container.handler.ClustersStatus.class.getName()); addJaxProviders(); + addTestrunnerComponentsIfTester(deployState); } public void setZone(Zone zone) { @@ -204,6 +207,11 @@ public abstract class ContainerCluster<CONTAINER extends Container> addVipHandler(); } + private void addTestrunnerComponentsIfTester(DeployState deployState) { + if (deployState.isHosted() && deployState.getProperties().applicationId().instance().isTester()) + addPlatformBundle(Paths.get(Defaults.getDefaults().underVespaHome("vespa-testrunner-components-jar-with-dependencies.jar"))); + } + public final void addDefaultHandlersExceptStatus() { addDefaultRootHandler(); addMetricStateHandler(); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java index 526b2abe1e1..c7114178ad6 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.container.search; +import com.yahoo.config.application.api.DeployLogger; import com.yahoo.search.query.profile.BackedOverridableQueryProfile; import com.yahoo.search.query.profile.QueryProfile; import com.yahoo.search.query.profile.QueryProfileRegistry; @@ -12,6 +13,8 @@ import com.yahoo.search.query.profile.config.QueryProfilesConfig; import java.io.Serializable; import java.util.*; import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.stream.Collectors; /** * Owns the query profiles and query profile types to be handed to the qrs nodes. @@ -29,8 +32,9 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer * @param registry the registry containing the query profiles and types of this. * The given registry cannot be frozen on calling this. */ - public QueryProfiles(QueryProfileRegistry registry) { + public QueryProfiles(QueryProfileRegistry registry, DeployLogger logger) { this.registry = registry; + validate(registry, logger); } public QueryProfiles() { @@ -41,6 +45,28 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer return registry; } + /** Emits warnings/hints on some common configuration errors */ + private void validate(QueryProfileRegistry registry, DeployLogger logger) { + Set<String> tensorFields = new HashSet<>(); + for (QueryProfileType type : registry.getTypeRegistry().allComponents()) { + for (var fieldEntry : type.fields().entrySet()) { + if (fieldEntry.getValue().getType().asTensorType().rank() > 0) + tensorFields.add(fieldEntry.getKey()); + } + } + + if ( registry.getTypeRegistry().hasApplicationTypes() && registry.allComponents().isEmpty()) { + logger.log(Level.WARNING, "This application define query profile types, but has " + + "no query profiles referencing them so they have no effect. " + + (tensorFields.isEmpty() + ? "" + : "In particular, the tensors (" + String.join(", ", tensorFields) + + ") will be interpreted as strings, not tensors if sent in requests. ") + + "See https://docs.vespa.ai/documentation/query-profiles.html"); + } + + } + @Override public void getConfig(QueryProfilesConfig.Builder builder) { for (QueryProfile profile : registry.allComponents()) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfilesBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfilesBuilder.java index b85cb88bf2e..b832c1bbdcd 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfilesBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfilesBuilder.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.container.search; +import com.yahoo.config.application.api.DeployLogger; import com.yahoo.io.reader.NamedReader; import com.yahoo.search.query.profile.config.QueryProfileXMLReader; import com.yahoo.config.application.api.ApplicationPackage; @@ -17,13 +18,14 @@ import java.util.List; public class QueryProfilesBuilder { /** Build the set of query profiles for an application package */ - public QueryProfiles build(ApplicationPackage applicationPackage) { + public QueryProfiles build(ApplicationPackage applicationPackage, DeployLogger logger) { List<NamedReader> queryProfileTypeFiles = null; List<NamedReader> queryProfileFiles = null; try { queryProfileTypeFiles = applicationPackage.getQueryProfileTypeFiles(); queryProfileFiles = applicationPackage.getQueryProfileFiles(); - return new QueryProfiles(new QueryProfileXMLReader().read(queryProfileTypeFiles, queryProfileFiles)); + return new QueryProfiles(new QueryProfileXMLReader().read(queryProfileTypeFiles, queryProfileFiles), + logger); } finally { NamedReader.closeAll(queryProfileTypeFiles); 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 b7c96d63755..642f882f3ed 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 @@ -223,13 +223,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { }); } - private boolean zoneHasActiveRotation(Zone zone) { - return app.getDeployment() - .map(DeploymentSpec::fromXml) - .map(spec -> zoneHasActiveRotation(zone, spec)) - .orElse(true); - } - private boolean zoneHasActiveRotation(Zone zone, DeploymentSpec spec) { return spec.zones().stream() .anyMatch(declaredZone -> declaredZone.deploysTo(zone.environment(), Optional.of(zone.region())) && |