diff options
author | Jon Bratseth <bratseth@gmail.com> | 2021-10-29 14:41:55 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2021-10-29 14:41:55 +0200 |
commit | 91d9fdf134e51322d57d1634253ded11a5ad9f48 (patch) | |
tree | 30deb780c81b0148f56d4d2827c43e5070faf4fd /container-search | |
parent | 2b392be81f7a63d0f2e17c48ac365e4e55bb8a7c (diff) |
Stable query profile ids
Diffstat (limited to 'container-search')
9 files changed, 71 insertions, 23 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java index 08bdca78ee6..8f22c6902c3 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java @@ -2,20 +2,17 @@ package com.yahoo.search.query.profile; import com.yahoo.processing.request.CompoundName; -import com.yahoo.protect.Validator; import java.util.HashMap; import java.util.List; import java.util.Map; /** - * <p>A wrapper of a query profile where overrides to the values in the referenced - * profile can be set.</p> - * - * <p>This is used to allow configured overrides (in a particular referencing profile) of a referenced query profile. - * - * <p>Properties which are defined as not overridable in the type (if any) of the referenced query profile - * cannot be set.</p> + * A wrapper of a query profile where overrides to the values in the referenced + * profile can be set. + * This is used to allow configured overrides (in a particular referencing profile) of a referenced query profile. + * Properties which are defined as not overridable in the type (if any) of the referenced query profile + * cannot be set. * * @author bratseth */ @@ -31,7 +28,7 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple * @param backingProfile the backing profile, which is assumed read only, never null */ public BackedOverridableQueryProfile(QueryProfile backingProfile) { - Validator.ensureNotNull("An overridable query profile must be backed by a real query profile", backingProfile); + super(backingProfile.getOwner()); setType(backingProfile.getType()); this.backingProfile = backingProfile; } @@ -66,7 +63,7 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple if (backing instanceof QueryProfile) return new BackedOverridableQueryProfile((QueryProfile)backing); else - return new OverridableQueryProfile(); // Nothing is set in this branch, so nothing to override, but need override checking + return new OverridableQueryProfile(getOwner()); // Nothing is set in this branch, so nothing to override, but need override checking } /** Returns a clone of this which can be independently overridden, but which refers to the same backing profile */ diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java index b8de533dfbe..ac0712eeb63 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java @@ -16,12 +16,12 @@ public class OverridableQueryProfile extends QueryProfile { private static final String simpleClassName = OverridableQueryProfile.class.getSimpleName(); /** Creates an unbacked overridable query profile */ - protected OverridableQueryProfile() { - this(""); + protected OverridableQueryProfile(QueryProfileRegistry owner) { + this("", owner); } - protected OverridableQueryProfile(String sourceName) { - super(ComponentId.createAnonymousComponentId(simpleClassName), sourceName); + protected OverridableQueryProfile(String sourceName, QueryProfileRegistry owner) { + super(createAnonymousId(owner), sourceName, owner); } @Override @@ -35,7 +35,8 @@ public class OverridableQueryProfile extends QueryProfile { @Override protected QueryProfile createSubProfile(String name, DimensionBinding binding) { - return new OverridableQueryProfile(getSource()); // Nothing is set in this branch, so nothing to override, but need override checking + // Nothing is set in this branch, so nothing to override, but need override checking + return new OverridableQueryProfile(getSource(), getOwner()); } /** Returns a clone of this which can be independently overridden */ @@ -43,7 +44,7 @@ public class OverridableQueryProfile extends QueryProfile { public OverridableQueryProfile clone() { if (isFrozen()) return this; OverridableQueryProfile clone = (OverridableQueryProfile)super.clone(); - clone.initId(ComponentId.createAnonymousComponentId(simpleClassName)); + clone.initId(createAnonymousId(getOwner())); return clone; } @@ -52,4 +53,9 @@ public class OverridableQueryProfile extends QueryProfile { return "an overridable query profile with no backing"; } + private static ComponentId createAnonymousId(QueryProfileRegistry owner) { + return owner != null ? owner.createAnonymousId(simpleClassName) + : ComponentId.createAnonymousComponentId(simpleClassName); + } + } 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 ee7d44f457f..c30a78da57d 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 @@ -45,6 +45,9 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable /** The name of the source of this (a file) */ private final String source; + /** The query profile registry owning this, or null if none (which will only happen in tests) */ + public final QueryProfileRegistry owner; + /** Defines the permissible content of this, or null if any content is permissible */ private QueryProfileType type = null; @@ -84,8 +87,13 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable } public QueryProfile(ComponentId id, String sourceName) { + this(id, sourceName, null); + } + + public QueryProfile(ComponentId id, String sourceName, QueryProfileRegistry owner) { super(id); this.source = sourceName; + this.owner = owner; if ( ! id.isAnonymous()) validateName(id.getName()); } @@ -96,6 +104,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable public String getSource() { return source; } + protected final QueryProfileRegistry getOwner() { return owner; } + /** Returns the type of this or null if it has no type */ public QueryProfileType getType() { return type; } @@ -144,6 +154,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable /** * Returns the content fields declared in this (i.e not including those inherited) as a read-only map. + * * @throws IllegalStateException if this is frozen */ public Map<String, Object> declaredContent() { @@ -390,7 +401,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * Switches this from write-only to read-only mode. * This profile can never be modified again after this method returns. * Calling this on an already frozen profile has no effect. - * <p> + * * Calling this will also freeze any profiles inherited and referenced by this. */ // TODO: Remove/simplify as query profiles are not used at query time @@ -624,7 +635,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable QueryProfile newProfile = (QueryProfile)newValue; if ( ! (existingValue instanceof QueryProfile)) { if ( ! isModifiable(newProfile)) { - newProfile = new BackedOverridableQueryProfile(newProfile); // Make the query profile reference overridable + // Make the query profile reference overridable + newProfile = new BackedOverridableQueryProfile(newProfile); } newProfile.value = existingValue; return newProfile; @@ -652,7 +664,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable } } - private static QueryProfile combineProfiles(QueryProfile newProfile,QueryProfile existingProfile) { + private static QueryProfile combineProfiles(QueryProfile newProfile, QueryProfile existingProfile) { QueryProfile returnValue = null; QueryProfile existingModifiable; @@ -720,7 +732,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * This default implementation returns an empty profile. */ protected QueryProfile createSubProfile(String name, DimensionBinding dimensionBinding) { - return new QueryProfile(ComponentId.createAnonymousComponentId(name), source); + var id = owner != null ? owner.createAnonymousId(name) : ComponentId.createAnonymousComponentId(name); + return new QueryProfile(id, source, owner); } /** Do a variant-aware content lookup in this */ diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java index 83b3cd8c4d0..74d3b4a3525 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java @@ -1,12 +1,15 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.query.profile; +import com.yahoo.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry; import com.yahoo.search.query.profile.types.QueryProfileType; import com.yahoo.search.query.profile.types.QueryProfileTypeRegistry; +import java.util.concurrent.atomic.AtomicInteger; + /** * A set of query profiles. This also holds the query profile types as a dependent registry * @@ -14,7 +17,9 @@ import com.yahoo.search.query.profile.types.QueryProfileTypeRegistry; */ public class QueryProfileRegistry extends ComponentRegistry<QueryProfile> { - private QueryProfileTypeRegistry queryProfileTypeRegistry = new QueryProfileTypeRegistry(); + private int nextAnonymousId = 0; + + private final QueryProfileTypeRegistry queryProfileTypeRegistry = new QueryProfileTypeRegistry(); /** Register this type by its id */ public void register(QueryProfile profile) { @@ -83,4 +88,9 @@ public class QueryProfileRegistry extends ComponentRegistry<QueryProfile> { public CompiledQueryProfileRegistry compile() { return QueryProfileCompiler.compile(this); } + public ComponentId createAnonymousId(String name) { + return ComponentId.newAnonymous(name + "_" + (nextAnonymousId++)); + } + + } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java index f840885f2e4..ceeed9d9167 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java @@ -74,7 +74,7 @@ public class QueryProfileConfigurer implements ConfigSubscriber.SingleSubscriber } private static void createProfile(QueryProfilesConfig.Queryprofile config, QueryProfileRegistry registry) { - QueryProfile profile = new QueryProfile(new ComponentId(config.id()), config.id()); + QueryProfile profile = new QueryProfile(new ComponentId(config.id()), config.id(), registry); try { String typeId = config.type(); if (typeId != null && ! typeId.isEmpty()) diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java index 555d3a8e6b7..c94987ce88e 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java @@ -135,7 +135,7 @@ public class QueryProfileXMLReader { ComponentId id = new ComponentId(idString); validateFileNameToId(reader.getName(), id, "query profile"); - QueryProfile queryProfile = new QueryProfile(id, reader.getName()); + QueryProfile queryProfile = new QueryProfile(id, reader.getName(), registry); String typeId = root.getAttribute("type"); if (typeId != null && ! typeId.equals("")) { QueryProfileType type = registry.getType(typeId); 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 e04835c01b2..a24e9af5928 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 @@ -449,6 +449,18 @@ public class XmlReadingTestCase { query = new Query(HttpRequest.createTestRequest("?query=test&profileRef=ref:MyProfile2", Method.GET), registry.getComponent("default")); assertEquals("MyProfile2", query.properties().get("profileRef.name")); } + + } + + @Test + public void testAnonymousIdsAreStableBetweenImports() { + QueryProfileRegistry registry1 = new QueryProfileXMLReader().read("src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance"); + var childIn1 = registry1.findQueryProfile("child"); + + QueryProfileRegistry registry2 = new QueryProfileXMLReader().read("src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance"); + var childIn2 = registry2.findQueryProfile("child"); + assertEquals(((QueryProfile)childIn1.lookup("a", Map.of())).getId().stringValue(), + ((QueryProfile)childIn2.lookup("a", Map.of())).getId().stringValue()); } @Test diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml new file mode 100644 index 00000000000..10edbacba60 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml @@ -0,0 +1,5 @@ +<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<query-profile id="child" inherits="parent"> + <field name="a.b.c">a.b.c-child</field> +</query-profile> + diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml new file mode 100644 index 00000000000..2e576186628 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml @@ -0,0 +1,5 @@ +<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<query-profile id="parent"> + <field name="a.b">a.b-parent</field> + <field name="a.b.c">a.b.c-parent</field> +</query-profile> |