diff options
author | Jon Bratseth <bratseth@oath.com> | 2018-04-27 08:05:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-27 08:05:29 +0200 |
commit | e34eafa914c22654beeb33f6c536fe0b216f3fb7 (patch) | |
tree | a80535dcba9205195363936a9861402bb6f05bea /container-search | |
parent | 53658ee238caffe4824a04bf498406fad4303e16 (diff) | |
parent | 060f6026eb5e38a282b0e0a2214b64c9f13b9c76 (diff) |
Merge pull request #5724 from vespa-engine/bratseth/correct-listProperties
Bratseth/correct list properties
Diffstat (limited to 'container-search')
18 files changed, 264 insertions, 226 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/Query.java b/container-search/src/main/java/com/yahoo/search/Query.java index 20f87afacc1..0fed379d446 100644 --- a/container-search/src/main/java/com/yahoo/search/Query.java +++ b/container-search/src/main/java/com/yahoo/search/Query.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.search; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.yahoo.collections.Tuple2; import com.yahoo.component.Version; @@ -47,9 +48,11 @@ import com.yahoo.yolean.Exceptions; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; @@ -111,7 +114,7 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { /** Converts a type argument value into a query type */ public static Type getType(String typeString) { for (Type type:Type.values()) - if(type.stringValue.equals(typeString)) + if (type.stringValue.equals(typeString)) return type; return ALL; } @@ -141,10 +144,10 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { /** Whether this query is forbidden to access cached information */ - private boolean noCache=false; + private boolean noCache = false; /** Whether or not grouping should use a session cache */ - private boolean groupingSessionCache=false; + private boolean groupingSessionCache = false; //-------------- Generic property containers -------------------------------- @@ -205,15 +208,14 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { argumentType.addField(new FieldDescription(TIMEOUT.toString(), "string", "timeout")); argumentType.addField(new FieldDescription(FederationSearcher.SOURCENAME.toString(),"string")); argumentType.addField(new FieldDescription(FederationSearcher.PROVIDERNAME.toString(),"string")); - argumentType.addField(new FieldDescription(Presentation.PRESENTATION,new QueryProfileFieldType(Presentation.getArgumentType()))); - argumentType.addField(new FieldDescription(Ranking.RANKING,new QueryProfileFieldType(Ranking.getArgumentType()))); - argumentType.addField(new FieldDescription(Model.MODEL,new QueryProfileFieldType(Model.getArgumentType()))); + argumentType.addField(new FieldDescription(Presentation.PRESENTATION, new QueryProfileFieldType(Presentation.getArgumentType()))); + argumentType.addField(new FieldDescription(Ranking.RANKING, new QueryProfileFieldType(Ranking.getArgumentType()))); + argumentType.addField(new FieldDescription(Model.MODEL, new QueryProfileFieldType(Model.getArgumentType()))); argumentType.freeze(); } public static QueryProfileType getArgumentType() { return argumentType; } - /** The aliases of query properties, these are always the same */ - // Note: Don't make static for now as GSM calls this through reflection + /** The aliases of query properties */ private static Map<String,CompoundName> propertyAliases; static { Map<String,CompoundName> propertyAliasesBuilder = new HashMap<>(); @@ -223,11 +225,11 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { addAliases(Presentation.getArgumentType(), propertyAliasesBuilder); propertyAliases = ImmutableMap.copyOf(propertyAliasesBuilder); } - private static void addAliases(QueryProfileType arguments,Map<String,CompoundName> aliases) { - String prefix=getPrefix(arguments); + private static void addAliases(QueryProfileType arguments, Map<String, CompoundName> aliases) { + String prefix = getPrefix(arguments); for (FieldDescription field : arguments.fields().values()) { for (String alias : field.getAliases()) - aliases.put(alias,new CompoundName(prefix+field.getName())); + aliases.put(alias, new CompoundName(prefix+field.getName())); } } private static String getPrefix(QueryProfileType type) { @@ -244,6 +246,25 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { registry.register(DefaultProperties.argumentType.unfrozen()); } + /** Returns an unmodifiable list of all the native properties under a Query */ + public static final List<CompoundName> nativeProperties = + ImmutableList.copyOf(namesUnder(CompoundName.empty, Query.getArgumentType())); + + private static List<CompoundName> namesUnder(CompoundName prefix, QueryProfileType type) { + if ( type == null) return Collections.emptyList(); // Names not known statically + List<CompoundName> names = new ArrayList<>(); + for (Map.Entry<String, FieldDescription> field : type.fields().entrySet()) { + if (field.getValue().getType() instanceof QueryProfileFieldType) { + names.addAll(namesUnder(prefix.append(field.getKey()), + ((QueryProfileFieldType) field.getValue().getType()).getQueryProfileType())); + } + else { + names.add(prefix.append(field.getKey())); + } + } + return names; + } + //---------------- Construction ------------------------------------ /** @@ -294,7 +315,7 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { startTime = System.currentTimeMillis(); if (queryProfile != null) { // Move all request parameters to the query profile just to validate that the parameter settings are legal - Properties queryProfileProperties=new QueryProfileProperties(queryProfile); + Properties queryProfileProperties = new QueryProfileProperties(queryProfile); properties().chain(queryProfileProperties); // TODO: Just checking legality rather than actually setting would be faster setPropertiesFromRequestMap(requestMap, properties()); // Adds errors to the query for illegal set attempts @@ -360,9 +381,9 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { * (if any) set it to properties(). */ private void setFrom(Properties originalProperties,QueryProfileType arguments,Map<String,String> context) { - String prefix=getPrefix(arguments); + String prefix = getPrefix(arguments); for (FieldDescription field : arguments.fields().values()) { - String fullName=prefix + field.getName(); + String fullName = prefix + field.getName(); if (field.getType() == FieldType.genericQueryProfileType) { for (Map.Entry<String, Object> entry : originalProperties.listProperties(fullName,context).entrySet()) { try { diff --git a/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java b/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java index 9034484b022..686c019688e 100644 --- a/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.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.search.federation; +import com.google.common.collect.ImmutableList; import com.google.inject.Inject; import com.yahoo.collections.Pair; import com.yahoo.component.ComponentId; @@ -93,6 +94,8 @@ public class FederationSearcher extends ForkingSearcher { private final Clock clock = Clock.systemUTC(); + private static final List<CompoundName> queryAndHits = ImmutableList.of(Query.OFFSET, Query.HITS); + @Inject public FederationSearcher(FederationConfig config, StrictContractsConfig strict, ComponentRegistry<TargetSelector> targetSelectors) { @@ -277,11 +280,11 @@ public class FederationSearcher extends ForkingSearcher { switch (propagateSourceProperties) { case ALL: propagatePerSourceQueryProperties(query, outgoing, window, sourceName, providerName, - QueryProperties.PER_SOURCE_QUERY_PROPERTIES); + Query.nativeProperties); break; case OFFSET_HITS: propagatePerSourceQueryProperties(query, outgoing, window, sourceName, providerName, - new CompoundName[]{Query.OFFSET, Query.HITS}); + queryAndHits); break; } @@ -293,7 +296,7 @@ public class FederationSearcher extends ForkingSearcher { private void propagatePerSourceQueryProperties(Query original, Query outgoing, Window window, String sourceName, String providerName, - CompoundName[] queryProperties) { + List<CompoundName> queryProperties) { for (CompoundName key : queryProperties) { Object value = getSourceOrProviderProperty(original, key, sourceName, providerName, window.get(key)); if (value != null) diff --git a/container-search/src/main/java/com/yahoo/search/query/Ranking.java b/container-search/src/main/java/com/yahoo/search/query/Ranking.java index 44c26f55040..903eedfe870 100644 --- a/container-search/src/main/java/com/yahoo/search/query/Ranking.java +++ b/container-search/src/main/java/com/yahoo/search/query/Ranking.java @@ -6,7 +6,9 @@ import com.yahoo.prelude.Freshness; import com.yahoo.prelude.Location; import com.yahoo.search.Query; import com.yahoo.search.query.profile.types.FieldDescription; +import com.yahoo.search.query.profile.types.QueryProfileFieldType; import com.yahoo.search.query.profile.types.QueryProfileType; +import com.yahoo.search.query.ranking.Diversity; import com.yahoo.search.query.ranking.MatchPhase; import com.yahoo.search.query.ranking.Matching; import com.yahoo.search.query.ranking.RankFeatures; @@ -54,7 +56,10 @@ public class Ranking implements Cloneable { argumentType.addField(new FieldDescription(LIST_FEATURES, "string", RANKFEATURES.toString())); argumentType.addField(new FieldDescription(FRESHNESS, "string", "datetime")); argumentType.addField(new FieldDescription(QUERYCACHE, "string")); - argumentType.addField(new FieldDescription(MATCH_PHASE, "query-profile", "matchPhase")); + argumentType.addField(new FieldDescription(MATCH_PHASE, new QueryProfileFieldType(MatchPhase.getArgumentType()), "matchPhase")); + argumentType.addField(new FieldDescription(DIVERSITY, new QueryProfileFieldType(Diversity.getArgumentType()))); + argumentType.addField(new FieldDescription(SOFTTIMEOUT, new QueryProfileFieldType(SoftTimeout.getArgumentType()))); + argumentType.addField(new FieldDescription(MATCHING, new QueryProfileFieldType(Matching.getArgumentType()))); argumentType.addField(new FieldDescription(FEATURES, "query-profile", "rankfeature")); argumentType.addField(new FieldDescription(PROPERTIES, "query-profile", "rankproperty")); argumentType.freeze(); diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/DumpTool.java b/container-search/src/main/java/com/yahoo/search/query/profile/DumpTool.java index bfdf49bf50a..572a78addd2 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/DumpTool.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/DumpTool.java @@ -17,8 +17,8 @@ public class DumpTool { /** Creates and returns a dump from some parameters */ public String resolveAndDump(String... args) { - if (args.length==0 || args[0].startsWith("-")) { - StringBuilder result=new StringBuilder(); + if (args.length == 0 || args[0].startsWith("-")) { + StringBuilder result = new StringBuilder(); result.append("Dumps all resolved query profile properties for a set of dimension values\n"); result.append("USAGE: dump [query-profile] [dir]? [parameters]?\n"); result.append(" and [query-profile] is the name of the query profile to dump the values of\n"); @@ -37,37 +37,37 @@ public class DumpTool { } // Find what the arguments means - if (args.length>=3) { - return dump(args[0],args[1],args[2]); + if (args.length >= 3) { + return dump(args[0], args[1], args[2]); } - else if (args.length==2) { - if (args[1].indexOf("=")>=0) - return dump(args[0],"",args[1]); + else if (args.length == 2) { + if (args[1].contains("=")) + return dump(args[0], "", args[1]); else - return dump(args[0],args[1],""); + return dump(args[0], args[1],""); } else { // args.length=1 - return dump(args[0],"",""); + return dump(args[0], "", ""); } } private String dump(String profileName,String dir,String parameters) { // Import profiles if (dir.isEmpty()) - dir="."; - File dirInAppPackage=new File(dir,"search/query-profiles"); + dir = "."; + File dirInAppPackage = new File(dir, "search/query-profiles"); if (dirInAppPackage.exists()) - dir=dirInAppPackage.getPath(); + dir = dirInAppPackage.getPath(); QueryProfileXMLReader reader = new QueryProfileXMLReader(); QueryProfileRegistry registry = reader.read(dir); registry.freeze(); // Dump (through query to get wiring & parameter parsing done easily) Query query = new Query("?" + parameters, registry.compile().findQueryProfile(profileName)); - Map<String,Object> properties=query.properties().listProperties(); + Map<String,Object> properties = query.properties().listProperties(); // Create result - StringBuilder b=new StringBuilder(); + StringBuilder b = new StringBuilder(); for (Map.Entry<String,Object> property : properties.entrySet()) { b.append(property.getKey()); b.append("="); diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java index a347fbfb3ab..0e6af6113b5 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java @@ -234,17 +234,18 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * will return {"d" => "a.d-value","e" => "a.e-value"} */ public Map<String, Object> listValues(CompoundName prefix, Map<String, String> context, Properties substitution) { - DimensionBinding dimensionBinding=DimensionBinding.createFrom(getDimensions(),context); + DimensionBinding dimensionBinding = DimensionBinding.createFrom(getDimensions(),context); - AllValuesQueryProfileVisitor visitor=new AllValuesQueryProfileVisitor(prefix); + AllValuesQueryProfileVisitor visitor = new AllValuesQueryProfileVisitor(prefix); accept(visitor,dimensionBinding, null); - Map<String,Object> values=visitor.getResult(); + Map<String,Object> values = visitor.getResult(); - if (substitution==null) return values; + if (substitution == null) return values; for (Map.Entry<String, Object> entry : values.entrySet()) { if (entry.getValue().getClass() == String.class) continue; // Shortcut - if (entry.getValue() instanceof SubstituteString) - entry.setValue(((SubstituteString)entry.getValue()).substitute(context,substitution)); + if (entry.getValue() instanceof SubstituteString) { + entry.setValue(((SubstituteString) entry.getValue()).substitute(context, substitution)); + } } return values; } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java index 324c1bf796e..3e1f664cf87 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java @@ -100,7 +100,8 @@ public class QueryProfileProperties extends Properties { if (i == name.size()-1 && fieldDescription != null) { // at the end of the path, check the assignment type value = fieldDescription.getType().convertFrom(value, profile.getRegistry()); if (value == null) - throw new IllegalArgumentException("'" + value + "' is not a " + fieldDescription.getType().toInstanceDescription()); + throw new IllegalArgumentException("'" + value + "' is not a " + + fieldDescription.getType().toInstanceDescription()); } } } @@ -138,7 +139,6 @@ public class QueryProfileProperties extends Properties { if (context == null) context = Collections.emptyMap(); Map<String, Object> properties = profile.listValues(path, context, substitution); - properties.putAll(super.listProperties(path, context, substitution)); if (references != null) { diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/SubstituteString.java b/container-search/src/main/java/com/yahoo/search/query/profile/SubstituteString.java index ca492de101f..36b38ad8d03 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/SubstituteString.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/SubstituteString.java @@ -56,8 +56,8 @@ public class SubstituteString { * Perform the substitution in this, by looking up in the given query profile, * and returns the resulting string */ - public String substitute(Map<String,String> context,Properties substitution) { - StringBuilder b=new StringBuilder(); + public String substitute(Map<String, String> context, Properties substitution) { + StringBuilder b = new StringBuilder(); for (Component component : components) b.append(component.getValue(context,substitution)); return b.toString(); diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java index fca1124665b..7ac73947905 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java @@ -12,6 +12,7 @@ import com.yahoo.search.query.profile.types.QueryProfileType; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -109,7 +110,7 @@ public class CompiledQueryProfile extends AbstractComponent implements Cloneable * For example, if {a.d => "a.d-value" ,a.e => "a.e-value", b.d => "b.d-value", then calling listValues("a") * will return {"d" => "a.d-value","e" => "a.e-value"} */ - public final Map<String, Object> listValues(final String prefix,Map<String,String> context) { + public final Map<String, Object> listValues(final String prefix,Map<String, String> context) { return listValues(new CompoundName(prefix), context); } /** @@ -118,7 +119,7 @@ public class CompiledQueryProfile extends AbstractComponent implements Cloneable * For example, if {a.d => "a.d-value" ,a.e => "a.e-value", b.d => "b.d-value", then calling listValues("a") * will return {"d" => "a.d-value","e" => "a.e-value"} */ - public final Map<String, Object> listValues(final CompoundName prefix,Map<String,String> context) { + public final Map<String, Object> listValues(final CompoundName prefix,Map<String, String> context) { return listValues(prefix, context, null); } /** @@ -127,7 +128,7 @@ public class CompiledQueryProfile extends AbstractComponent implements Cloneable * For example, if {a.d => "a.d-value" ,a.e => "a.e-value", b.d => "b.d-value", then calling listValues("a") * will return {"d" => "a.d-value","e" => "a.e-value"} */ - public Map<String, Object> listValues(CompoundName prefix, Map<String,String> context, Properties substitution) { + public Map<String, Object> listValues(CompoundName prefix, Map<String, String> context, Properties substitution) { Map<String, Object> values = new HashMap<>(); for (Map.Entry<CompoundName, DimensionalValue<Object>> entry : entries.entrySet()) { if ( entry.getKey().size() <= prefix.size()) continue; @@ -144,19 +145,19 @@ public class CompiledQueryProfile extends AbstractComponent implements Cloneable } public final Object get(String name) { - return get(name, Collections.<String,String>emptyMap()); + return get(name, Collections.emptyMap()); } - public final Object get(String name, Map<String,String> context) { + public final Object get(String name, Map<String, String> context) { return get(name, context, new QueryProfileProperties(this)); } - public final Object get(String name, Map<String,String> context, Properties substitution) { + public final Object get(String name, Map<String, String> context, Properties substitution) { return get(new CompoundName(name), context, substitution); } public final Object get(CompoundName name, Map<String, String> context, Properties substitution) { return substitute(entries.get(name, context), context, substitution); } - private Object substitute(Object value, Map<String,String> context, Properties substitution) { + private Object substitute(Object value, Map<String, String> context, Properties substitution) { if (value == null) return value; if (substitution == null) return value; if (value.getClass() != SubstituteString.class) return value; @@ -165,7 +166,7 @@ public class CompiledQueryProfile extends AbstractComponent implements Cloneable /** Throws IllegalArgumentException if the given string is not a valid query profile name */ private static void validateName(String name) { - Matcher nameMatcher=namePattern.matcher(name); + Matcher nameMatcher = namePattern.matcher(name); if ( ! nameMatcher.matches()) throw new IllegalArgumentException("Illegal name '" + name + "'"); } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java b/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java index c826d834d47..2ec3df4a976 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java @@ -299,20 +299,20 @@ public class QueryProfileType extends FreezableSimpleComponent { } } - private void addAlias(String alias,String field) { + private void addAlias(String alias, String field) { ensureNotFrozen(); - if (aliases==null) - aliases=new HashMap<>(); - aliases.put(toLowerCase(alias),field); + if (aliases == null) + aliases = new HashMap<>(); + aliases.put(toLowerCase(alias), field); } /** Returns all the fields of this profile type and all types it inherits as a read-only map */ - public Map<String,FieldDescription> fields() { + public Map<String, FieldDescription> fields() { if (isFrozen()) return fields; - if (inherited().size()==0) return Collections.unmodifiableMap(fields); + if (inherited().size() == 0) return Collections.unmodifiableMap(fields); // Collapse inherited - Map<String,FieldDescription> allFields=new HashMap<>(fields); + Map<String, FieldDescription> allFields = new HashMap<>(fields); for (QueryProfileType inheritedType : inherited) allFields.putAll(inheritedType.fields()); return Collections.unmodifiableMap(allFields); @@ -322,7 +322,7 @@ public class QueryProfileType extends FreezableSimpleComponent { * Returns the alias to field mapping of this type as a read-only map. This is never null. * Note that all keys are lower-cased because aliases are case-insensitive */ - public Map<String,String> aliases() { + public Map<String, String> aliases() { if (isFrozen()) return aliases; if (aliases == null) return Collections.emptyMap(); return Collections.unmodifiableMap(aliases); @@ -330,9 +330,9 @@ public class QueryProfileType extends FreezableSimpleComponent { /** Returns the field name of an alias or field name */ public String unalias(String aliasOrField) { - if (aliases==null || aliases.isEmpty()) return aliasOrField; - String field=aliases.get(toLowerCase(aliasOrField)); - if (field!=null) return field; + if (aliases == null || aliases.isEmpty()) return aliasOrField; + String field = aliases.get(toLowerCase(aliasOrField)); + if (field != null) return field; return aliasOrField; } diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java index f6d30ee57e2..0aea5e96161 100644 --- a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java +++ b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java @@ -6,6 +6,7 @@ import com.yahoo.search.Query; import com.yahoo.search.query.*; import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry; import com.yahoo.search.query.profile.types.FieldDescription; +import com.yahoo.search.query.profile.types.QueryProfileFieldType; import com.yahoo.search.query.profile.types.QueryProfileType; import com.yahoo.search.query.ranking.Diversity; import com.yahoo.search.query.ranking.MatchPhase; @@ -13,6 +14,9 @@ import com.yahoo.search.query.ranking.Matching; import com.yahoo.search.query.ranking.SoftTimeout; import com.yahoo.tensor.Tensor; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; /** @@ -24,37 +28,13 @@ import java.util.Map; */ public class QueryProperties extends Properties { - private static final String MODEL_PREFIX = Model.MODEL + "."; - private static final String RANKING_PREFIX = Ranking.RANKING + "."; - private static final String PRESENTATION_PREFIX = Presentation.PRESENTATION + "."; - - public static final CompoundName[] PER_SOURCE_QUERY_PROPERTIES = new CompoundName[] { - new CompoundName(MODEL_PREFIX + Model.QUERY_STRING), - new CompoundName(MODEL_PREFIX + Model.TYPE), - new CompoundName(MODEL_PREFIX + Model.FILTER), - new CompoundName(MODEL_PREFIX + Model.DEFAULT_INDEX), - new CompoundName(MODEL_PREFIX + Model.LANGUAGE), - new CompoundName(MODEL_PREFIX + Model.ENCODING), - new CompoundName(MODEL_PREFIX + Model.SOURCES), - new CompoundName(MODEL_PREFIX + Model.SEARCH_PATH), - new CompoundName(MODEL_PREFIX + Model.RESTRICT), - new CompoundName(RANKING_PREFIX + Ranking.LOCATION), - new CompoundName(RANKING_PREFIX + Ranking.PROFILE), - new CompoundName(RANKING_PREFIX + Ranking.SORTING), - new CompoundName(RANKING_PREFIX + Ranking.FRESHNESS), - new CompoundName(RANKING_PREFIX + Ranking.QUERYCACHE), - new CompoundName(RANKING_PREFIX + Ranking.LIST_FEATURES), - new CompoundName(PRESENTATION_PREFIX + Presentation.BOLDING), - new CompoundName(PRESENTATION_PREFIX + Presentation.SUMMARY), - new CompoundName(PRESENTATION_PREFIX + Presentation.REPORT_COVERAGE), - new CompoundName(PRESENTATION_PREFIX + Presentation.FORMAT), - new CompoundName(PRESENTATION_PREFIX + Presentation.SUMMARY_FIELDS), - Query.HITS, - Query.OFFSET, - Query.TRACE_LEVEL, - Query.TIMEOUT, - Query.NO_CACHE, - Query.GROUPING_SESSION_CACHE }; + /** + * TODO: Remove on Vespa 7 + * @deprecated use Query.nativeProperties + */ + @Deprecated + public static final CompoundName[] PER_SOURCE_QUERY_PROPERTIES = + Query.nativeProperties.toArray(new CompoundName[] {}); private Query query; private final CompiledQueryProfileRegistry profileRegistry; @@ -73,7 +53,7 @@ public class QueryProperties extends Properties { @Override public Object get(CompoundName key, Map<String,String> context, com.yahoo.processing.request.Properties substitution) { - if (key.size()==2 && key.first().equals(Model.MODEL)) { + if (key.size() == 2 && key.first().equals(Model.MODEL)) { Model model = query.getModel(); if (key.last().equals(Model.QUERY_STRING)) return model.getQueryString(); if (key.last().equals(Model.TYPE)) return model.getType(); @@ -87,7 +67,7 @@ public class QueryProperties extends Properties { } else if (key.first().equals(Ranking.RANKING)) { Ranking ranking = query.getRanking(); - if (key.size()==2) { + if (key.size() == 2) { if (key.last().equals(Ranking.LOCATION)) return ranking.getLocation(); if (key.last().equals(Ranking.PROFILE)) return ranking.getProfile(); if (key.last().equals(Ranking.SORTING)) return ranking.getSorting(); @@ -156,7 +136,7 @@ public class QueryProperties extends Properties { if (key.toString().equals(Ranking.RANKING)) return query.getRanking(); if (key.toString().equals(Presentation.PRESENTATION)) return query.getPresentation(); } - return super.get(key,context,substitution); + return super.get(key, context, substitution); } @SuppressWarnings("deprecation") @@ -298,6 +278,21 @@ public class QueryProperties extends Properties { } } + @Override + public Map<String, Object> listProperties(CompoundName prefix, + Map<String,String> context, + com.yahoo.processing.request.Properties substitution) { + Map<String, Object> properties = super.listProperties(prefix, context, substitution); + for (CompoundName queryProperty : Query.nativeProperties) { + if (queryProperty.hasPrefix(prefix)) { + Object value = this.get(queryProperty, context, substitution); + if (value != null) + properties.put(queryProperty.toString(), value); + } + } + return properties; + } + private void setRankingFeature(Query query, String key, Object value) { if (value instanceof Tensor) query.getRanking().getFeatures().put(key, (Tensor)value); @@ -322,4 +317,5 @@ public class QueryProperties extends Properties { public final Query getParentQuery() { return query; } + } diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/RequestContextProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/RequestContextProperties.java index 3627b0d6951..ee09521fa74 100644 --- a/container-search/src/main/java/com/yahoo/search/query/properties/RequestContextProperties.java +++ b/container-search/src/main/java/com/yahoo/search/query/properties/RequestContextProperties.java @@ -15,27 +15,27 @@ import java.util.Map; */ public class RequestContextProperties extends Properties { - private final Map<String,String> requestMap; + private final Map<String, String> requestMap; public RequestContextProperties(Map<String, String> properties) { - this.requestMap=properties; + this.requestMap = properties; } @Override public Object get(CompoundName name,Map<String,String> context, com.yahoo.processing.request.Properties substitution) { - return super.get(name,context==null ? requestMap : context,substitution); + return super.get(name, context == null ? requestMap : context, substitution); } @Override public void set(CompoundName name,Object value,Map<String,String> context) { - super.set(name,value,context==null ? requestMap : context); + super.set(name, value, context == null ? requestMap : context); } @Override public Map<String, Object> listProperties(CompoundName path,Map<String,String> context, com.yahoo.processing.request.Properties substitution) { - return super.listProperties(path,context==null ? requestMap : context,substitution); + return super.listProperties(path, context == null ? requestMap : context, substitution); } } diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/Diversity.java b/container-search/src/main/java/com/yahoo/search/query/ranking/Diversity.java index ebd1a4cfc98..83b35c60f15 100644 --- a/container-search/src/main/java/com/yahoo/search/query/ranking/Diversity.java +++ b/container-search/src/main/java/com/yahoo/search/query/ranking/Diversity.java @@ -30,7 +30,7 @@ public class Diversity implements Cloneable { static { - argumentType =new QueryProfileType(Ranking.DIVERSITY); + argumentType = new QueryProfileType(Ranking.DIVERSITY); argumentType.setStrict(true); argumentType.setBuiltin(true); argumentType.addField(new FieldDescription(ATTRIBUTE, "string")); diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java index bc07ad7bdbd..fb3f2acfadd 100644 --- a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java +++ b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java @@ -13,6 +13,7 @@ import java.util.Objects; * @author baldersheim */ public class Matching implements Cloneable { + /** The type representing the property arguments consumed by this */ private static final QueryProfileType argumentType; @@ -32,6 +33,7 @@ public class Matching implements Cloneable { argumentType.addField(new FieldDescription(MINHITSPERTHREAD, "integer")); argumentType.freeze(); } + public static QueryProfileType getArgumentType() { return argumentType; } public Double termwiseLimit = null; diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java b/container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java index 75fa9f957d7..1fad45a99e3 100644 --- a/container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java +++ b/container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java @@ -13,6 +13,7 @@ import java.util.Objects; * @author baldersheim */ public class SoftTimeout implements Cloneable { + /** The type representing the property arguments consumed by this */ private static final QueryProfileType argumentType; @@ -20,9 +21,8 @@ public class SoftTimeout implements Cloneable { public static final String FACTOR = "factor"; public static final String TAILCOST = "tailcost"; - static { - argumentType =new QueryProfileType(Ranking.SOFTTIMEOUT); + argumentType = new QueryProfileType(Ranking.SOFTTIMEOUT); argumentType.setStrict(true); argumentType.setBuiltin(true); argumentType.addField(new FieldDescription(TAILCOST, "double")); diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java index b510f6c59bd..bc4c8cbc298 100644 --- a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java @@ -121,7 +121,7 @@ public class XmlReadingTestCase { assertEquals("test", q.properties().get("query")); assertEquals("test", q.properties().get("QueRY")); assertEquals("test", q.properties().get("model.queryString")); - assertEquals("test",q.getModel().getQueryString()); + assertEquals("test", q.getModel().getQueryString()); } /** Tests a subset of the configuration in the system test of this */ @@ -137,23 +137,22 @@ public class XmlReadingTestCase { Properties p = query.properties(); assertEquals("test", query.getModel().getQueryString()); - assertEquals("test",p.get("query")); - assertEquals("test",p.get("QueRY")); - assertEquals("test",p.get("model.queryString")); - assertEquals("bar",p.get("foo")); - assertEquals(5,p.get("hits")); - assertEquals("tit",p.get("subst")); - assertEquals("le",p.get("subst.end")); - assertEquals("title",p.get("model.defaultIndex")); + assertEquals("test", p.get("query")); + assertEquals("test", p.get("QueRY")); + assertEquals("test", p.get("model.queryString")); + assertEquals("bar", p.get("foo")); + assertEquals(5, p.get("hits")); + assertEquals("tit", p.get("subst")); + assertEquals("le", p.get("subst.end")); + assertEquals("title", p.get("model.defaultIndex")); Map<String,Object> ps = p.listProperties(); - assertEquals(6,ps.size()); - assertEquals("bar",ps.get("foo")); - assertEquals("5",ps.get("hits")); - assertEquals("tit",ps.get("subst")); - assertEquals("le",ps.get("subst.end")); - assertEquals("title",ps.get("model.defaultIndex")); - assertEquals("test",ps.get("model.queryString")); + assertEquals("bar", ps.get("foo")); + assertEquals(5, ps.get("hits")); + assertEquals("tit", ps.get("subst")); + assertEquals("le", ps.get("subst.end")); + assertEquals("title", ps.get("model.defaultIndex")); + assertEquals("test", ps.get("model.queryString")); } @Test diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/test/DumpToolTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/test/DumpToolTestCase.java index 46d574f1713..68cda12dab7 100644 --- a/container-search/src/test/java/com/yahoo/search/query/profile/test/DumpToolTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/profile/test/DumpToolTestCase.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertTrue; */ public class DumpToolTestCase { - String profileDir="src/test/java/com/yahoo/search/query/profile/config/test/multiprofile"; + private String profileDir = "src/test/java/com/yahoo/search/query/profile/config/test/multiprofile"; @Test public void testNoParameters() { @@ -25,18 +25,20 @@ public class DumpToolTestCase { @Test public void testNoDimensionValues() { - assertTrue(new DumpTool().resolveAndDump("multiprofile1",profileDir).startsWith("a=general-a\n")); + assertTrue(new DumpTool().resolveAndDump("multiprofile1", profileDir).startsWith("a=general-a\n")); } @Test public void testAllParametersSet() { - assertTrue(new DumpTool().resolveAndDump("multiprofile1",profileDir,"").startsWith("a=general-a\n")); + assertTrue(new DumpTool().resolveAndDump("multiprofile1", profileDir, "").startsWith("a=general-a\n")); } - // This test is order dependent. Fix this!! @Test public void testVariant() { - assertTrue(new DumpTool().resolveAndDump("multiprofile1",profileDir,"region=us").startsWith("a=us-a\nb=us-b\nregion=us")); + String result = new DumpTool().resolveAndDump("multiprofile1", profileDir, "region=us"); + assertTrue(result.contains("a=us-a")); + assertTrue(result.contains("b=us-b")); + assertTrue(result.contains("region=us")); } } diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileTestCase.java index f3133855729..bf7e66122d6 100644 --- a/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileTestCase.java @@ -506,10 +506,10 @@ public class QueryProfileTestCase { @Test public void testRankTypeNames() { - QueryProfile p=new QueryProfile("test"); + QueryProfile p = new QueryProfile("test"); p.set("a.$b","foo", null); - p.set("a.query(b)","bar", null); - p.set("a.b.default-index","fuu", null); + p.set("a.query(b)", "bar", null); + p.set("a.b.default-index", "fuu", null); CompiledQueryProfile cp = p.compile(null); assertEquals("foo", cp.get("a.$b")); @@ -529,58 +529,58 @@ public class QueryProfileTestCase { @Test public void testQueryProfileInlineValueReassignment() { - QueryProfile p=new QueryProfile("test"); - p.set("source.rel.params.query","%{model.queryString}", null); + QueryProfile p = new QueryProfile("test"); + p.set("source.rel.params.query", "%{model.queryString}", null); p.freeze(); Query q = new Query(HttpRequest.createTestRequest("?query=foo", Method.GET), p.compile(null)); - assertEquals("foo",q.properties().get("source.rel.params.query")); - assertEquals("foo",q.properties().listProperties().get("source.rel.params.query")); + assertEquals("foo", q.properties().get("source.rel.params.query")); + assertEquals("foo", q.properties().listProperties().get("source.rel.params.query")); q.getModel().setQueryString("bar"); - assertEquals("bar",q.properties().get("source.rel.params.query")); - assertEquals("foo",q.properties().listProperties().get("source.rel.params.query")); // Is still foo because model variables are not supported with the list function + assertEquals("bar", q.properties().get("source.rel.params.query")); + assertEquals("bar", q.properties().listProperties().get("source.rel.params.query")); } @Test public void testQueryProfileInlineValueReassignmentSimpleName() { - QueryProfile p=new QueryProfile("test"); + QueryProfile p = new QueryProfile("test"); p.set("key","%{model.queryString}", null); p.freeze(); Query q = new Query(HttpRequest.createTestRequest("?query=foo", Method.GET), p.compile(null)); - assertEquals("foo",q.properties().get("key")); - assertEquals("foo",q.properties().listProperties().get("key")); + assertEquals("foo", q.properties().get("key")); + assertEquals("foo", q.properties().listProperties().get("key")); q.getModel().setQueryString("bar"); - assertEquals("bar",q.properties().get("key")); - assertEquals("foo",q.properties().listProperties().get("key")); // Is still bar because model variables are not supported with the list function + assertEquals("bar", q.properties().get("key")); + assertEquals("bar", q.properties().listProperties().get("key")); } @Test public void testQueryProfileInlineValueReassignmentSimpleNameGenericProperty() { - QueryProfile p=new QueryProfile("test"); - p.set("key","%{value}", null); + QueryProfile p = new QueryProfile("test"); + p.set("key", "%{value}", null); p.freeze(); Query q = new Query(HttpRequest.createTestRequest("?query=test&value=foo", Method.GET), p.compile(null)); - assertEquals("foo",q.properties().get("key")); - assertEquals("foo",q.properties().listProperties().get("key")); - q.properties().set("value","bar"); - assertEquals("bar",q.properties().get("key")); - assertEquals("bar",q.properties().listProperties().get("key")); + assertEquals("foo", q.properties().get("key")); + assertEquals("foo", q.properties().listProperties().get("key")); + q.properties().set("value", "bar"); + assertEquals("bar", q.properties().get("key")); + assertEquals("bar", q.properties().listProperties().get("key")); } @Test public void testQueryProfileModelValueListing() { - QueryProfile p=new QueryProfile("test"); + QueryProfile p = new QueryProfile("test"); p.freeze(); Query q = new Query(HttpRequest.createTestRequest("?query=bar", Method.GET), p.compile(null)); - assertEquals("bar",q.properties().get("model.queryString")); - assertEquals("bar",q.properties().listProperties().get("model.queryString")); + assertEquals("bar", q.properties().get("model.queryString")); + assertEquals("bar", q.properties().listProperties().get("model.queryString")); q.getModel().setQueryString("baz"); - assertEquals("baz",q.properties().get("model.queryString")); - assertEquals("bar",q.properties().listProperties().get("model.queryString")); // Is still bar because model variables are not supported with the list function + assertEquals("baz", q.properties().get("model.queryString")); + assertEquals("baz", q.properties().listProperties().get("model.queryString")); } @Test public void testEmptyBoolean() { - QueryProfile p=new QueryProfile("test"); + QueryProfile p = new QueryProfile("test"); p.setDimensions(new String[] {"x","y"}); p.set("clustering.something","bar", null); p.set("clustering.something","bar", new String[] {"x1","y1"}, null); @@ -588,8 +588,8 @@ public class QueryProfileTestCase { Query q = new Query(HttpRequest.createTestRequest("?x=x1&y=y1&query=bar&clustering.timeline.kano=tur&" + "clustering.enable=true&clustering.timeline.bucketspec=-" + "7d/3h&clustering.timeline.tophit=false&clustering.timeli" + - "ne=true", Method.GET),p.compile(null)); - assertEquals(true,q.properties().getBoolean("clustering.timeline",false)); + "ne=true", Method.GET), p.compile(null)); + assertEquals(true, q.properties().getBoolean("clustering.timeline", false)); } } diff --git a/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java b/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java index 2a36e30b95a..70896bbad5f 100644 --- a/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java @@ -21,6 +21,7 @@ import com.yahoo.prelude.query.OrItem; import com.yahoo.prelude.query.QueryException; import com.yahoo.prelude.query.RankItem; import com.yahoo.prelude.query.WordItem; +import com.yahoo.processing.request.CompoundName; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; @@ -444,28 +445,28 @@ public class QueryTestCase { @Test public void testQueryPropertyResolveTracing() { - QueryProfile testProfile=new QueryProfile("test"); + QueryProfile testProfile = new QueryProfile("test"); testProfile.setOverridable("u", false, null); testProfile.set("d","e", null); testProfile.set("u","11", null); testProfile.set("foo.bar", "wiz", null); Query q = new Query(QueryTestCase.httpEncode("?query=a:>5&a=b&traceLevel=5&sources=a,b&u=12&foo.bar2=wiz2&c.d=foo&queryProfile=test"),testProfile.compile(null)); - String trace=q.getContext(false).getTrace().toString(); - String[] traceLines=trace.split("\n"); + String trace = q.getContext(false).getTrace().toString(); + String[] traceLines = trace.split("\n"); for (String line : traceLines) System.out.println(line); - assertTrue(contains("query=a:>5 (value from request)",traceLines)); - assertTrue(contains("traceLevel=5 (value from request)",traceLines)); - assertTrue(contains("a=b (value from request)",traceLines)); - assertTrue(contains("sources=[a, b] (value from request)",traceLines)); - assertTrue(contains("d=e (value from query profile)",traceLines)); - assertTrue(contains("u=11 (value from query profile - unoverridable, ignoring request value)",traceLines)); + assertTrue(contains("query=a:>5 (value from request)", traceLines)); + assertTrue(contains("traceLevel=5 (value from request)", traceLines)); + assertTrue(contains("a=b (value from request)", traceLines)); + assertTrue(contains("sources=[a, b] (value from request)", traceLines)); + assertTrue(contains("d=e (value from query profile)", traceLines)); + assertTrue(contains("u=11 (value from query profile - unoverridable, ignoring request value)", traceLines)); } @Test public void testNonleafInRequestDoesNotOverrideProfile() { - QueryProfile testProfile=new QueryProfile("test"); - testProfile.set("a.b", "foo", (QueryProfileRegistry)null); + QueryProfile testProfile = new QueryProfile("test"); + testProfile.set("a.b", "foo", null); testProfile.freeze(); { Query q = new Query("?", testProfile.compile(null)); @@ -481,54 +482,61 @@ public class QueryTestCase { @Test public void testQueryPropertyResolveTracing2() { - QueryProfile defaultProfile=new QueryProfile("default"); + QueryProfile defaultProfile = new QueryProfile("default"); defaultProfile.freeze(); Query q = new Query(QueryTestCase.httpEncode("?query=dvd&a.b=foo&tracelevel=9"), defaultProfile.compile(null)); - String trace=q.getContext(false).getTrace().toString(); - String[] traceLines=trace.split("\n"); - assertTrue(contains("query=dvd (value from request)",traceLines)); - assertTrue(contains("a.b=foo (value from request)",traceLines)); + String trace = q.getContext(false).getTrace().toString(); + String[] traceLines = trace.split("\n"); + assertTrue(contains("query=dvd (value from request)", traceLines)); + assertTrue(contains("a.b=foo (value from request)", traceLines)); + } + + @Test + public void testNativeProperties() { + Set<String> nativeProperties = Query.nativeProperties.stream().map(CompoundName::toString).collect(Collectors.toSet()); + // Sample the content + assertTrue(nativeProperties.contains("hits")); + assertTrue(nativeProperties.contains("model.sources")); + assertTrue(nativeProperties.contains("ranking.matchPhase.attribute")); } @Test public void testQueryPropertyListingAndTrace() { - QueryProfile defaultProfile=new QueryProfile("default"); + QueryProfile defaultProfile = new QueryProfile("default"); defaultProfile.setDimensions(new String[]{"x"}); - defaultProfile.set("a.b","a.b-x1-value",new String[] {"x1"}, null); + defaultProfile.set("a.b","a.b-x1-value", new String[] {"x1"}, null); defaultProfile.set("a.b", "a.b-x2-value", new String[]{"x2"}, null); defaultProfile.freeze(); { Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x1"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties(); - assertEquals(3,propertyList.size()); - assertEquals("a.b-x1-value",propertyList.get("a.b")); - String trace=q.getContext(false).getTrace().toString(); - String[] traceLines=trace.split("\n"); - assertTrue(contains("a.b=a.b-x1-value (value from query profile)",traceLines)); + Map<String,Object> propertyList = q.properties().listProperties(); + assertEquals("a.b-x1-value", propertyList.get("a.b")); + String trace = q.getContext(false).getTrace().toString(); + String[] traceLines = trace.split("\n"); + assertTrue(contains("a.b=a.b-x1-value (value from query profile)", traceLines)); } { - Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x1"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties("a"); - assertEquals(1,propertyList.size()); - assertEquals("a.b-x1-value",propertyList.get("b")); + Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x1"), defaultProfile.compile(null)); + Map<String,Object> propertyList = q.properties().listProperties("a"); + assertEquals(1, propertyList.size()); + assertEquals("a.b-x1-value", propertyList.get("b")); } { Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x2"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties(); - assertEquals(3,propertyList.size()); - assertEquals("a.b-x2-value",propertyList.get("a.b")); - String trace=q.getContext(false).getTrace().toString(); - String[] traceLines=trace.split("\n"); - assertTrue(contains("a.b=a.b-x2-value (value from query profile)",traceLines)); + Map<String,Object> propertyList = q.properties().listProperties(); + assertEquals("a.b-x2-value", propertyList.get("a.b")); + String trace = q.getContext(false).getTrace().toString(); + String[] traceLines = trace.split("\n"); + assertTrue(contains("a.b=a.b-x2-value (value from query profile)", traceLines)); } } @Test public void testQueryPropertyListingThreeLevel() { - QueryProfile defaultProfile=new QueryProfile("default"); + QueryProfile defaultProfile = new QueryProfile("default"); defaultProfile.setDimensions(new String[] {"x"}); defaultProfile.set("a.b.c", "a.b.c-x1-value", new String[]{"x1"}, null); defaultProfile.set("a.b.c", "a.b.c-x2-value", new String[]{"x2"}, null); @@ -536,47 +544,45 @@ public class QueryTestCase { { Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x1"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties(); - assertEquals(3,propertyList.size()); - assertEquals("a.b.c-x1-value",propertyList.get("a.b.c")); + Map<String,Object> propertyList = q.properties().listProperties(); + assertEquals("a.b.c-x1-value", propertyList.get("a.b.c")); } { Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x1"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties("a"); - assertEquals(1,propertyList.size()); - assertEquals("a.b.c-x1-value",propertyList.get("b.c")); + Map<String,Object> propertyList = q.properties().listProperties("a"); + assertEquals(1, propertyList.size()); + assertEquals("a.b.c-x1-value", propertyList.get("b.c")); } { Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x1"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties("a.b"); - assertEquals(1,propertyList.size()); - assertEquals("a.b.c-x1-value",propertyList.get("c")); + Map<String,Object> propertyList = q.properties().listProperties("a.b"); + assertEquals(1, propertyList.size()); + assertEquals("a.b.c-x1-value", propertyList.get("c")); } { Query q = new Query(QueryTestCase.httpEncode("?tracelevel=9&x=x2"),defaultProfile.compile(null)); - Map<String,Object> propertyList=q.properties().listProperties(); - assertEquals(3,propertyList.size()); - assertEquals("a.b.c-x2-value",propertyList.get("a.b.c")); + Map<String,Object> propertyList = q.properties().listProperties(); + assertEquals("a.b.c-x2-value", propertyList.get("a.b.c")); } } @Test public void testQueryPropertyReplacement() { - QueryProfile defaultProfile=new QueryProfile("default"); - defaultProfile.set("model.queryString","myquery", (QueryProfileRegistry)null); - defaultProfile.set("queryUrl","http://provider:80?query=%{model.queryString}", (QueryProfileRegistry)null); + QueryProfile defaultProfile = new QueryProfile("default"); + defaultProfile.set("model.queryString","myquery", null); + defaultProfile.set("queryUrl","http://provider:80?query=%{model.queryString}", null); defaultProfile.freeze(); - Query q1 = new Query(QueryTestCase.httpEncode(""),defaultProfile.compile(null)); - assertEquals("myquery",q1.getModel().getQueryString()); - assertEquals("http://provider:80?query=myquery",q1.properties().get("queryUrl")); + Query q1 = new Query(QueryTestCase.httpEncode(""), defaultProfile.compile(null)); + assertEquals("myquery", q1.getModel().getQueryString()); + assertEquals("http://provider:80?query=myquery", q1.properties().get("queryUrl")); - Query q2 = new Query(QueryTestCase.httpEncode("?model.queryString=foo"),defaultProfile.compile(null)); - assertEquals("foo",q2.getModel().getQueryString()); - assertEquals("http://provider:80?query=foo",q2.properties().get("queryUrl")); + Query q2 = new Query(QueryTestCase.httpEncode("?model.queryString=foo"), defaultProfile.compile(null)); + assertEquals("foo", q2.getModel().getQueryString()); + assertEquals("http://provider:80?query=foo", q2.properties().get("queryUrl")); Query q3 = new Query(QueryTestCase.httpEncode("?query=foo"),defaultProfile.compile(null)); assertEquals("foo",q3.getModel().getQueryString()); @@ -588,7 +594,7 @@ public class QueryTestCase { } @Test - public void testNoQueryString() throws IOException { + public void testNoQueryString() { Query q = new Query(httpEncode("?tracelevel=1")); Chain<Searcher> chain = new Chain<>(new RandomSearcher()); new Execution(chain, Execution.Context.createContextStub()).search(q); @@ -598,7 +604,7 @@ public class QueryTestCase { @Test public void testSetCollapseField() { Query q = new Query(httpEncode("?collapsefield=foo&presentation.format=tiled")); - assertEquals("foo",q.properties().get("collapsefield")); + assertEquals("foo", q.properties().get("collapsefield")); assertEquals("tiled", q.properties().get("presentation.format")); assertEquals("tiled", q.getPresentation().getFormat()); } @@ -606,23 +612,23 @@ public class QueryTestCase { @Test public void testSetNullProperty() { QueryProfile profile = new QueryProfile("test"); - profile.set("property","initialValue", (QueryProfileRegistry)null); + profile.set("property","initialValue", null); Query query = new Query(httpEncode("?query=test"), profile.compile(null)); assertEquals("initialValue",query.properties().get("property")); - query.properties().set("property",null); + query.properties().set("property", null); assertNull(query.properties().get("property")); } @Test public void testSetNullPropertyNoQueryProfile() { - Query query=new Query(); - query.properties().set("a",null); + Query query = new Query(); + query.properties().set("a", null); assertNull(query.properties().get("a")); } @Test public void testMissingParameter() { - Query q=new Query("?query=foo&hits="); + Query q = new Query("?query=foo&hits="); assertEquals(0, q.errors().size()); } @@ -631,23 +637,25 @@ public class QueryTestCase { { Query query = new Query(); query.properties().set("model.searchPath", "foo"); - assertEquals("Set dynamic get dynamic works","foo",query.properties().get("model.searchPath")); - assertEquals("Set dynamic get static works","foo",query.getModel().getSearchPath()); + assertEquals("Set dynamic get dynamic works","foo", query.properties().get("model.searchPath")); + assertEquals("Set dynamic get static works","foo", query.getModel().getSearchPath()); + Map<String, Object> properties = query.properties().listProperties(); + assertEquals("Listing built-in properties works", "foo", properties.get("model.searchPath")); } { - Query query=new Query(); + Query query = new Query(); query.getModel().setSearchPath("foo"); - assertEquals("Set static get dynamic works","foo",query.properties().get("model.searchPath")); - assertEquals("Set static get static works","foo",query.getModel().getSearchPath()); + assertEquals("Set static get dynamic works","foo", query.properties().get("model.searchPath")); + assertEquals("Set static get static works","foo", query.getModel().getSearchPath()); } { - Query query=new Query(); - query.properties().set("a","bar"); - assertEquals("bar",query.properties().get("a")); - query.properties().set("a.b","baz"); - assertEquals("baz",query.properties().get("a.b")); + Query query = new Query(); + query.properties().set("a", "bar"); + assertEquals("bar", query.properties().get("a")); + query.properties().set("a.b", "baz"); + assertEquals("baz", query.properties().get("a.b")); } } |