diff --git a/src/main/java/com/yelp/nrtsearch/server/field/AtomFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/AtomFieldDef.java index 8a74766d9..6c77f3875 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/AtomFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/AtomFieldDef.java @@ -32,8 +32,9 @@ public class AtomFieldDef extends TextBaseFieldDef implements Sortable { private static final Analyzer keywordAnalyzer = new KeywordAnalyzer(); - public AtomFieldDef(String name, Field requestField) { - super(name, requestField); + public AtomFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/BooleanFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/BooleanFieldDef.java index 441514d82..481739835 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/BooleanFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/BooleanFieldDef.java @@ -37,8 +37,9 @@ /** Field class for 'BOOLEAN' field type. */ public class BooleanFieldDef extends IndexableFieldDef implements TermQueryable { - protected BooleanFieldDef(String name, Field requestField) { - super(name, requestField, Boolean.class); + protected BooleanFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, Boolean.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDef.java index e51e0f414..9a3bf7116 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDef.java @@ -36,9 +36,11 @@ public class ContextSuggestFieldDef extends IndexableFieldDef { /** * @param name name of field * @param requestField field definition from grpc request + * @param context creation context */ - protected ContextSuggestFieldDef(String name, Field requestField) { - super(name, requestField, Void.class); + protected ContextSuggestFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, Void.class); this.indexAnalyzer = this.parseIndexAnalyzer(requestField); this.searchAnalyzer = this.parseSearchAnalyzer(requestField); } diff --git a/src/main/java/com/yelp/nrtsearch/server/field/DateTimeFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/DateTimeFieldDef.java index 246d96563..4971e8f64 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/DateTimeFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/DateTimeFieldDef.java @@ -77,8 +77,9 @@ private static DateTimeFormatter createDateTimeFormatter(String dateTimeFormat) } } - public DateTimeFieldDef(String name, Field requestField) { - super(name, requestField, Instant.class); + public DateTimeFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, Instant.class); dateTimeFormat = requestField.getDateTimeFormat(); dateTimeFormatter = createDateTimeFormatter(dateTimeFormat); } diff --git a/src/main/java/com/yelp/nrtsearch/server/field/DoubleFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/DoubleFieldDef.java index 11af60de2..418a7dcdd 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/DoubleFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/DoubleFieldDef.java @@ -37,8 +37,9 @@ /** Field class for 'DOUBLE' field type. */ public class DoubleFieldDef extends NumberFieldDef { - public DoubleFieldDef(String name, Field requestField) { - super(name, requestField, DOUBLE_PARSER, Double.class); + public DoubleFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, DOUBLE_PARSER, context, Double.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/FieldDefCreator.java b/src/main/java/com/yelp/nrtsearch/server/field/FieldDefCreator.java index 44dbe8e72..5e5828a41 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/FieldDefCreator.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/FieldDefCreator.java @@ -20,6 +20,7 @@ import com.yelp.nrtsearch.server.grpc.FieldType; import com.yelp.nrtsearch.server.plugins.FieldTypePlugin; import com.yelp.nrtsearch.server.plugins.Plugin; +import com.yelp.nrtsearch.server.state.GlobalState; import com.yelp.nrtsearch.server.utils.StructValueTransformer; import java.util.HashMap; import java.util.Map; @@ -34,6 +35,13 @@ public class FieldDefCreator { private final Map> fieldDefMap = new HashMap<>(); + /** + * Addition context for field definition creation. + * + * @param config service configuration + */ + public record FieldDefCreatorContext(NrtsearchConfig config) {} + public FieldDefCreator(NrtsearchConfig configuration) { register("ATOM", AtomFieldDef::new); register("TEXT", TextFieldDef::new); @@ -52,12 +60,12 @@ public FieldDefCreator(NrtsearchConfig configuration) { // completely registered. register( "VIRTUAL", - (name, field) -> { + (name, field, context) -> { throw new UnsupportedOperationException("Virtual fields should be created directly"); }); register( "RUNTIME", - (name, field) -> { + (name, field, context) -> { throw new UnsupportedOperationException("Runtime fields should be created directly"); }); register("VECTOR", VectorFieldDef::createField); @@ -72,7 +80,7 @@ public FieldDefCreator(NrtsearchConfig configuration) { * @param field grpc request field definition * @return field definition */ - public FieldDef createFieldDef(String name, Field field) { + public FieldDef createFieldDef(String name, Field field, FieldDefCreatorContext context) { String type; if (field.getType().equals(FieldType.CUSTOM)) { type = @@ -86,7 +94,17 @@ public FieldDef createFieldDef(String name, Field field) { if (provider == null) { throw new IllegalArgumentException("Invalid field type: " + type); } - return provider.get(name, field); + return provider.get(name, field, context); + } + + /** + * Create a new {@link FieldDefCreatorContext} instance. + * + * @param globalState global state + * @return new context instance + */ + public static FieldDefCreatorContext createContext(GlobalState globalState) { + return new FieldDefCreatorContext(globalState.getConfiguration()); } private void register(Map> fieldDefs) { diff --git a/src/main/java/com/yelp/nrtsearch/server/field/FieldDefProvider.java b/src/main/java/com/yelp/nrtsearch/server/field/FieldDefProvider.java index 6818a1efc..8ece13fb0 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/FieldDefProvider.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/FieldDefProvider.java @@ -30,7 +30,8 @@ public interface FieldDefProvider { * * @param name field name * @param requestField field request definition + * @param context creation context * @return concrete {@link FieldDef} instance for field */ - T get(String name, Field requestField); + T get(String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context); } diff --git a/src/main/java/com/yelp/nrtsearch/server/field/FloatFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/FloatFieldDef.java index f581799b2..935cb577e 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/FloatFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/FloatFieldDef.java @@ -37,8 +37,9 @@ /** Field class for 'FLOAT' field type. */ public class FloatFieldDef extends NumberFieldDef { - public FloatFieldDef(String name, Field requestField) { - super(name, requestField, FLOAT_PARSER, Float.class); + public FloatFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, FLOAT_PARSER, context, Float.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/IdFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/IdFieldDef.java index 1affb74ab..473648282 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/IdFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/IdFieldDef.java @@ -38,8 +38,9 @@ /** Field class for defining '_ID' fields which are used to update documents */ public class IdFieldDef extends IndexableFieldDef implements TermQueryable { - protected IdFieldDef(String name, Field requestField) { - super(name, requestField, String.class); + protected IdFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, String.class); } /** diff --git a/src/main/java/com/yelp/nrtsearch/server/field/IndexableFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/IndexableFieldDef.java index 2acb097f7..44b727975 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/IndexableFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/IndexableFieldDef.java @@ -73,10 +73,14 @@ public enum FacetValueType { * * @param name name of field * @param requestField field definition from grpc request + * @param context creation context * @param docValuesObjectClass class of doc values object */ protected IndexableFieldDef( - String name, Field requestField, Class docValuesObjectClass) { + String name, + Field requestField, + FieldDefCreator.FieldDefCreatorContext context, + Class docValuesObjectClass) { super(name); validateRequest(requestField); @@ -116,7 +120,7 @@ protected IndexableFieldDef( for (Field field : requestField.getChildFieldsList()) { checkChildName(field.getName()); String childName = getName() + IndexState.CHILD_FIELD_SEPARATOR + field.getName(); - FieldDef fieldDef = FieldDefCreator.getInstance().createFieldDef(childName, field); + FieldDef fieldDef = FieldDefCreator.getInstance().createFieldDef(childName, field, context); if (!(fieldDef instanceof IndexableFieldDef)) { throw new IllegalArgumentException("Child field is not indexable: " + childName); } diff --git a/src/main/java/com/yelp/nrtsearch/server/field/IntFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/IntFieldDef.java index 0405fd28f..d6acf1d15 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/IntFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/IntFieldDef.java @@ -36,8 +36,9 @@ /** Field class for 'INT' field type. */ public class IntFieldDef extends NumberFieldDef { - public IntFieldDef(String name, Field requestField) { - super(name, requestField, INT_PARSER, Integer.class); + public IntFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, INT_PARSER, context, Integer.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/LatLonFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/LatLonFieldDef.java index d1db27954..868170753 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/LatLonFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/LatLonFieldDef.java @@ -47,8 +47,9 @@ /** Field class for 'LAT_LON' field type. */ public class LatLonFieldDef extends IndexableFieldDef implements Sortable, GeoQueryable { - public LatLonFieldDef(String name, Field requestField) { - super(name, requestField, GeoPoint.class); + public LatLonFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, GeoPoint.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/LongFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/LongFieldDef.java index 775a98457..cd22c302a 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/LongFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/LongFieldDef.java @@ -36,8 +36,9 @@ /** Field class for 'LONG' field type. */ public class LongFieldDef extends NumberFieldDef { - public LongFieldDef(String name, Field requestField) { - super(name, requestField, LONG_PARSER, Long.class); + public LongFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, LONG_PARSER, context, Long.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/NumberFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/NumberFieldDef.java index 16c7a1c92..41a56dbb2 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/NumberFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/NumberFieldDef.java @@ -69,8 +69,9 @@ protected NumberFieldDef( String name, Field requestField, Function fieldParser, + FieldDefCreator.FieldDefCreatorContext context, Class docValuesClass) { - super(name, requestField, docValuesClass); + super(name, requestField, context, docValuesClass); this.fieldParser = fieldParser; } diff --git a/src/main/java/com/yelp/nrtsearch/server/field/ObjectFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/ObjectFieldDef.java index c572cf118..6834549a1 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/ObjectFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/ObjectFieldDef.java @@ -47,8 +47,9 @@ public class ObjectFieldDef extends IndexableFieldDef { private final Gson gson; private final boolean isNestedDoc; - protected ObjectFieldDef(String name, Field requestField) { - super(name, requestField, Struct.class); + protected ObjectFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, Struct.class); this.isNestedDoc = requestField.getNestedDoc(); gson = new GsonBuilder().serializeNulls().create(); } diff --git a/src/main/java/com/yelp/nrtsearch/server/field/PolygonfieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/PolygonfieldDef.java index 8a432294c..f7f3a8a44 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/PolygonfieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/PolygonfieldDef.java @@ -38,8 +38,9 @@ public class PolygonfieldDef extends IndexableFieldDef implements PolygonQueryable { - protected PolygonfieldDef(String name, Field requestField) { - super(name, requestField, Struct.class); + protected PolygonfieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, Struct.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/TextBaseFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/TextBaseFieldDef.java index a49ffe4e2..f34b6d17e 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/TextBaseFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/TextBaseFieldDef.java @@ -65,15 +65,18 @@ public abstract class TextBaseFieldDef extends IndexableFieldDef private final int ignoreAbove; /** - * Field constructor. Uses {@link IndexableFieldDef#IndexableFieldDef(String, Field, Class)} to do - * common initialization, then sets up analyzers. Analyzers are parsed through calls to the - * protected methods {@link #parseIndexAnalyzer(Field)} and {@link #parseSearchAnalyzer(Field)}. + * Field constructor. Uses {@link IndexableFieldDef#IndexableFieldDef(String, Field, + * FieldDefCreator.FieldDefCreatorContext, Class)} to do common initialization, then sets up + * analyzers. Analyzers are parsed through calls to the protected methods {@link + * #parseIndexAnalyzer(Field)} and {@link #parseSearchAnalyzer(Field)}. * * @param name field name * @param requestField field definition from grpc request + * @param context creation context */ - protected TextBaseFieldDef(String name, Field requestField) { - super(name, requestField, String.class); + protected TextBaseFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, String.class); indexAnalyzer = parseIndexAnalyzer(requestField); searchAnalyzer = parseSearchAnalyzer(requestField); eagerFieldGlobalOrdinals = requestField.getEagerFieldGlobalOrdinals(); diff --git a/src/main/java/com/yelp/nrtsearch/server/field/TextFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/TextFieldDef.java index 535c4609c..19083cd0d 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/TextFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/TextFieldDef.java @@ -21,8 +21,9 @@ /** Field class for 'TEXT' field type. */ public class TextFieldDef extends TextBaseFieldDef { - public TextFieldDef(String name, Field requestField) { - super(name, requestField); + public TextFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/field/VectorFieldDef.java b/src/main/java/com/yelp/nrtsearch/server/field/VectorFieldDef.java index 54152e5a6..a969baad9 100644 --- a/src/main/java/com/yelp/nrtsearch/server/field/VectorFieldDef.java +++ b/src/main/java/com/yelp/nrtsearch/server/field/VectorFieldDef.java @@ -208,12 +208,14 @@ private static KnnVectorsFormat getHnswScalarQuantizedVectorsFormat( * * @param name name of field * @param field field definition from grpc request + * @param context creation context * @return new VectorFieldDef */ - static VectorFieldDef createField(String name, Field field) { + static VectorFieldDef createField( + String name, Field field, FieldDefCreator.FieldDefCreatorContext context) { return switch (field.getVectorElementType()) { - case VECTOR_ELEMENT_FLOAT -> new FloatVectorFieldDef(name, field); - case VECTOR_ELEMENT_BYTE -> new ByteVectorFieldDef(name, field); + case VECTOR_ELEMENT_FLOAT -> new FloatVectorFieldDef(name, field, context); + case VECTOR_ELEMENT_BYTE -> new ByteVectorFieldDef(name, field, context); default -> throw new IllegalArgumentException("Invalid field type: " + field.getVectorElementType()); }; @@ -222,10 +224,15 @@ static VectorFieldDef createField(String name, Field field) { /** * @param name name of field * @param requestField field definition from grpc request + * @param context creation context * @param docValuesClass class of doc values object */ - protected VectorFieldDef(String name, Field requestField, Class docValuesClass) { - super(name, requestField, docValuesClass); + protected VectorFieldDef( + String name, + Field requestField, + FieldDefCreator.FieldDefCreatorContext context, + Class docValuesClass) { + super(name, requestField, context, docValuesClass); this.vectorDimensions = requestField.getVectorDimensions(); if (isSearchable()) { VectorSearchType vectorSearchType = getSearchType(requestField.getVectorIndexingOptions()); @@ -322,8 +329,9 @@ public Query getKnnQuery(KnnQuery knnQuery, Query filterQuery) { /** Field class for 'FLOAT' vector field type. */ public static class FloatVectorFieldDef extends VectorFieldDef { - public FloatVectorFieldDef(String name, Field requestField) { - super(name, requestField, FloatVectorType.class); + public FloatVectorFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, FloatVectorType.class); } @Override @@ -462,8 +470,9 @@ public void validateVectorForSearch(float[] vector) { /** Field class for 'BYTE' vector field type. */ public static class ByteVectorFieldDef extends VectorFieldDef { - public ByteVectorFieldDef(String name, Field requestField) { - super(name, requestField, ByteVectorType.class); + public ByteVectorFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, ByteVectorType.class); } @Override diff --git a/src/main/java/com/yelp/nrtsearch/server/index/BackendStateManager.java b/src/main/java/com/yelp/nrtsearch/server/index/BackendStateManager.java index 5ad759c34..3ea3eea68 100644 --- a/src/main/java/com/yelp/nrtsearch/server/index/BackendStateManager.java +++ b/src/main/java/com/yelp/nrtsearch/server/index/BackendStateManager.java @@ -16,6 +16,7 @@ package com.yelp.nrtsearch.server.index; import com.google.common.annotations.VisibleForTesting; +import com.yelp.nrtsearch.server.field.FieldDefCreator; import com.yelp.nrtsearch.server.grpc.Field; import com.yelp.nrtsearch.server.grpc.IndexLiveSettings; import com.yelp.nrtsearch.server.grpc.IndexSettings; @@ -87,7 +88,10 @@ public synchronized void load() throws IOException { stateInfo = fixIndexName(stateInfo, indexName); UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - new FieldAndFacetState(), Collections.emptyMap(), stateInfo.getFieldsMap().values()); + new FieldAndFacetState(), + Collections.emptyMap(), + stateInfo.getFieldsMap().values(), + FieldDefCreator.createContext(globalState)); currentState = createIndexState(stateInfo, updatedFieldInfo.fieldAndFacetState, liveSettingsOverrides); } @@ -203,7 +207,8 @@ public synchronized String updateFields(List fields) throws IOException { FieldUpdateUtils.updateFields( currentState.getFieldAndFacetState(), currentState.getIndexStateInfo().getFieldsMap(), - fields); + fields, + FieldDefCreator.createContext(globalState)); IndexStateInfo updatedStateInfo = replaceFields(currentState.getIndexStateInfo(), updatedFieldInfo.fields); ImmutableIndexState updatedIndexState = diff --git a/src/main/java/com/yelp/nrtsearch/server/index/FieldUpdateUtils.java b/src/main/java/com/yelp/nrtsearch/server/index/FieldUpdateUtils.java index 961a016bc..1d26fa1a7 100644 --- a/src/main/java/com/yelp/nrtsearch/server/index/FieldUpdateUtils.java +++ b/src/main/java/com/yelp/nrtsearch/server/index/FieldUpdateUtils.java @@ -60,12 +60,14 @@ public UpdatedFieldInfo(Map fields, FieldAndFacetState fieldAndFa * @param currentState built state from the current fields * @param currentFields current fields * @param updateFields field updates + * @param context creation context * @return state after applying field updates */ public static UpdatedFieldInfo updateFields( FieldAndFacetState currentState, Map currentFields, - Iterable updateFields) { + Iterable updateFields, + FieldDefCreator.FieldDefCreatorContext context) { Map newFields = new HashMap<>(currentFields); FieldAndFacetState.Builder fieldStateBuilder = currentState.toBuilder(); @@ -85,7 +87,7 @@ public static UpdatedFieldInfo updateFields( if (newFields.containsKey(field.getName())) { throw new IllegalArgumentException("Duplicate field registration: " + field.getName()); } - parseField(field, fieldStateBuilder); + parseField(field, fieldStateBuilder, context); newFields.put(field.getName(), field); } @@ -126,9 +128,14 @@ public static void checkFieldName(String fieldName) { * * @param field field to process * @param fieldStateBuilder builder for new field state + * @param context creation context */ - public static void parseField(Field field, FieldAndFacetState.Builder fieldStateBuilder) { - FieldDef fieldDef = FieldDefCreator.getInstance().createFieldDef(field.getName(), field); + public static void parseField( + Field field, + FieldAndFacetState.Builder fieldStateBuilder, + FieldDefCreator.FieldDefCreatorContext context) { + FieldDef fieldDef = + FieldDefCreator.getInstance().createFieldDef(field.getName(), field, context); fieldStateBuilder.addField(fieldDef, field); if (fieldDef instanceof IndexableFieldDef) { addChildFields((IndexableFieldDef) fieldDef, fieldStateBuilder); diff --git a/src/main/java/com/yelp/nrtsearch/server/index/IndexState.java b/src/main/java/com/yelp/nrtsearch/server/index/IndexState.java index a92e5acf0..8c07128c2 100644 --- a/src/main/java/com/yelp/nrtsearch/server/index/IndexState.java +++ b/src/main/java/com/yelp/nrtsearch/server/index/IndexState.java @@ -221,7 +221,7 @@ public IndexState(GlobalState globalState, String name, Path rootDir) throws IOE this.rootDir = rootDir; // add meta data fields - metaFields = getPredefinedMetaFields(); + metaFields = getPredefinedMetaFields(globalState); if (!Files.exists(rootDir)) { Files.createDirectories(rootDir); @@ -500,7 +500,7 @@ public abstract IndexWriterConfig getIndexWriterConfig( public void close() throws IOException {} // Get all predifined meta fields - private static Map getPredefinedMetaFields() { + private static Map getPredefinedMetaFields(GlobalState globalState) { return ImmutableMap.of( NESTED_PATH, FieldDefCreator.getInstance() @@ -510,7 +510,8 @@ private static Map getPredefinedMetaFields() { .setName(IndexState.NESTED_PATH) .setType(FieldType.ATOM) .setSearch(true) - .build()), + .build(), + FieldDefCreator.createContext(globalState)), FIELD_NAMES, FieldDefCreator.getInstance() .createFieldDef( @@ -520,6 +521,7 @@ private static Map getPredefinedMetaFields() { .setType(FieldType.ATOM) .setSearch(true) .setMultiValued(true) - .build())); + .build(), + FieldDefCreator.createContext(globalState))); } } diff --git a/src/test/java/com/yelp/nrtsearch/server/field/AtomFieldDefTest.java b/src/test/java/com/yelp/nrtsearch/server/field/AtomFieldDefTest.java index eb5e7fcc4..de5d542b3 100644 --- a/src/test/java/com/yelp/nrtsearch/server/field/AtomFieldDefTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/field/AtomFieldDefTest.java @@ -16,6 +16,7 @@ package com.yelp.nrtsearch.server.field; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import com.yelp.nrtsearch.server.config.NrtsearchConfig; import com.yelp.nrtsearch.server.grpc.Field; @@ -39,7 +40,8 @@ public static void init() { } private AtomFieldDef createFieldDef(Field field) { - return new AtomFieldDef("test_field", field); + return new AtomFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); } @Test diff --git a/src/test/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDefTest.java b/src/test/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDefTest.java index 17f12b96b..eea7a25f5 100644 --- a/src/test/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDefTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/field/ContextSuggestFieldDefTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; import com.yelp.nrtsearch.server.ServerTestCase; import com.yelp.nrtsearch.server.grpc.Analyzer; @@ -69,7 +70,9 @@ public void validSearchAndIndexAnalyzerWhenFieldAnalyzerIsProvided() { .setIndexAnalyzer(standardAnalyzer) // should be ignored as analyzer takes precedence .setAnalyzer(analyzer) .build(); - ContextSuggestFieldDef contextSuggestFieldDef = new ContextSuggestFieldDef("test_field", field); + ContextSuggestFieldDef contextSuggestFieldDef = + new ContextSuggestFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); assertEquals( ClassicAnalyzer.class, contextSuggestFieldDef.getSearchAnalyzer().get().getClass()); assertEquals(ClassicAnalyzer.class, contextSuggestFieldDef.getIndexAnalyzer().get().getClass()); @@ -84,7 +87,9 @@ public void validSearchAndIndexAnalyzerWhenSearchAndIndexAnalyzersAreProvided() .setSearchAnalyzer(searchAnalyzer) .setIndexAnalyzer(indexAnalyzer) .build(); - ContextSuggestFieldDef contextSuggestFieldDef = new ContextSuggestFieldDef("test_field", field); + ContextSuggestFieldDef contextSuggestFieldDef = + new ContextSuggestFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); assertSame( BulgarianAnalyzer.class, contextSuggestFieldDef.getSearchAnalyzer().get().getClass()); assertSame(EnglishAnalyzer.class, contextSuggestFieldDef.getIndexAnalyzer().get().getClass()); @@ -93,7 +98,9 @@ public void validSearchAndIndexAnalyzerWhenSearchAndIndexAnalyzersAreProvided() @Test public void validDefaultSearchAndIndexAnalyzerNoAnalyzersAreProvided() { Field field = Field.newBuilder().build(); - ContextSuggestFieldDef contextSuggestFieldDef = new ContextSuggestFieldDef("test_field", field); + ContextSuggestFieldDef contextSuggestFieldDef = + new ContextSuggestFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); assertSame(StandardAnalyzer.class, contextSuggestFieldDef.getSearchAnalyzer().get().getClass()); assertSame(StandardAnalyzer.class, contextSuggestFieldDef.getIndexAnalyzer().get().getClass()); } diff --git a/src/test/java/com/yelp/nrtsearch/server/field/FieldDefCreatorTest.java b/src/test/java/com/yelp/nrtsearch/server/field/FieldDefCreatorTest.java index 5d8c75498..4d4a3048d 100644 --- a/src/test/java/com/yelp/nrtsearch/server/field/FieldDefCreatorTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/field/FieldDefCreatorTest.java @@ -15,7 +15,10 @@ */ package com.yelp.nrtsearch.server.field; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import com.google.protobuf.Struct; import com.google.protobuf.Value; @@ -24,6 +27,7 @@ import com.yelp.nrtsearch.server.grpc.FieldType; import com.yelp.nrtsearch.server.plugins.FieldTypePlugin; import com.yelp.nrtsearch.server.plugins.Plugin; +import com.yelp.nrtsearch.server.state.GlobalState; import java.io.ByteArrayInputStream; import java.util.Collections; import java.util.HashMap; @@ -49,9 +53,12 @@ private NrtsearchConfig getEmptyConfig() { } static class TestFieldDef extends FieldDef { + final FieldDefCreator.FieldDefCreatorContext context; - public TestFieldDef(String name, Field requestField) { + public TestFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { super(name); + this.context = context; } @Override @@ -90,7 +97,8 @@ public void testCustomFieldNotDefined() { "type", Value.newBuilder().setStringValue("custom_field_type").build()) .build()) .build(); - FieldDefCreator.getInstance().createFieldDef("test_field", field); + FieldDefCreator.getInstance() + .createFieldDef("test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); } @Test @@ -105,7 +113,40 @@ public void testPluginProvidesFieldType() { "type", Value.newBuilder().setStringValue("custom_field_type").build()) .build()) .build(); - FieldDef testFieldDef = FieldDefCreator.getInstance().createFieldDef("test_field", field); + FieldDef testFieldDef = + FieldDefCreator.getInstance() + .createFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); assertTrue(testFieldDef instanceof TestFieldDef); } + + @Test + public void testProvidesContext() { + init(Collections.singletonList(new TestFieldTypePlugin())); + Field field = + Field.newBuilder() + .setType(FieldType.CUSTOM) + .setAdditionalProperties( + Struct.newBuilder() + .putFields( + "type", Value.newBuilder().setStringValue("custom_field_type").build()) + .build()) + .build(); + FieldDefCreator.FieldDefCreatorContext mockContext = + mock(FieldDefCreator.FieldDefCreatorContext.class); + FieldDef testFieldDef = + FieldDefCreator.getInstance().createFieldDef("test_field", field, mockContext); + assertTrue(testFieldDef instanceof TestFieldDef); + assertSame(mockContext, ((TestFieldDef) testFieldDef).context); + } + + @Test + public void testCreateContext() { + NrtsearchConfig config = getEmptyConfig(); + GlobalState mockGlobalState = mock(GlobalState.class); + when(mockGlobalState.getConfiguration()).thenReturn(config); + FieldDefCreator.FieldDefCreatorContext context = FieldDefCreator.createContext(mockGlobalState); + + assertSame(config, context.config()); + } } diff --git a/src/test/java/com/yelp/nrtsearch/server/field/TestFieldDefTest.java b/src/test/java/com/yelp/nrtsearch/server/field/TestFieldDefTest.java index 419d28bb7..9432606f0 100644 --- a/src/test/java/com/yelp/nrtsearch/server/field/TestFieldDefTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/field/TestFieldDefTest.java @@ -16,6 +16,7 @@ package com.yelp.nrtsearch.server.field; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import com.yelp.nrtsearch.server.config.NrtsearchConfig; import com.yelp.nrtsearch.server.grpc.Field; @@ -36,7 +37,8 @@ public static void init() { } private TextFieldDef createFieldDef(Field field) { - return new TextFieldDef("test_field", field); + return new TextFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); } @Test diff --git a/src/test/java/com/yelp/nrtsearch/server/field/TextFieldDefTest.java b/src/test/java/com/yelp/nrtsearch/server/field/TextFieldDefTest.java index 2a1c64e2a..463a05a9f 100644 --- a/src/test/java/com/yelp/nrtsearch/server/field/TextFieldDefTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/field/TextFieldDefTest.java @@ -16,6 +16,7 @@ package com.yelp.nrtsearch.server.field; import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; import com.yelp.nrtsearch.server.config.NrtsearchConfig; import com.yelp.nrtsearch.server.grpc.Field; @@ -39,7 +40,8 @@ public static void init() { } private TextFieldDef createFieldDef(Field field) { - return new TextFieldDef("test_field", field); + return new TextFieldDef( + "test_field", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); } @Test diff --git a/src/test/java/com/yelp/nrtsearch/server/field/VectorFieldDefTest.java b/src/test/java/com/yelp/nrtsearch/server/field/VectorFieldDefTest.java index 12d18b1d4..f9821f50b 100644 --- a/src/test/java/com/yelp/nrtsearch/server/field/VectorFieldDefTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/field/VectorFieldDefTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; import com.google.common.primitives.Floats; import com.google.protobuf.ByteString; @@ -858,7 +859,9 @@ public void testVectorFormat_none() { .setVectorDimensions(3) .setVectorSimilarity("l2_norm") .build(); - VectorFieldDef vectorFieldDef = VectorFieldDef.createField("vector", field); + VectorFieldDef vectorFieldDef = + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); KnnVectorsFormat format = vectorFieldDef.getVectorsFormat(); assertNotNull(format); assertEquals( @@ -878,7 +881,9 @@ public void testVectorFormat_set_m() { .setVectorIndexingOptions( VectorIndexingOptions.newBuilder().setType("hnsw").setHnswM(5).build()) .build(); - VectorFieldDef vectorFieldDef = VectorFieldDef.createField("vector", field); + VectorFieldDef vectorFieldDef = + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); KnnVectorsFormat format = vectorFieldDef.getVectorsFormat(); assertNotNull(format); assertEquals( @@ -901,7 +906,9 @@ public void testVectorFormat_set_ef_construction() { .setHnswEfConstruction(50) .build()) .build(); - VectorFieldDef vectorFieldDef = VectorFieldDef.createField("vector", field); + VectorFieldDef vectorFieldDef = + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); KnnVectorsFormat format = vectorFieldDef.getVectorsFormat(); assertNotNull(format); assertEquals( @@ -921,7 +928,8 @@ public void testVectorFormat_invalid_type() { .setVectorIndexingOptions(VectorIndexingOptions.newBuilder().setType("invalid").build()) .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertTrue( @@ -941,7 +949,8 @@ public void testVectorFormat_invalid_similarity() { .setVectorSimilarity("invalid") .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertTrue( @@ -960,7 +969,8 @@ public void testMaxDocValueDimensions() { .setStoreDocValues(true) .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals("Vector dimension must be <= 4096", e.getMessage()); @@ -978,7 +988,8 @@ public void testMaxSearchDimensions() { .setVectorSimilarity("cosine") .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals("Vector dimension must be <= 4096", e.getMessage()); @@ -1334,7 +1345,8 @@ public void testInvalidConfidenceInterval() { .build()) .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals( @@ -1359,7 +1371,8 @@ public void testInvalidBits() { .build()) .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals("bits must be one of: 4, 7; bits=9", e.getMessage()); @@ -1380,7 +1393,8 @@ public void testInvalidQuantizedByteVector() { VectorIndexingOptions.newBuilder().setType("hnsw_scalar_quantized").build()) .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals( @@ -1404,7 +1418,8 @@ public void testInvalid4BitsOddDimensions() { .build()) .build(); try { - VectorFieldDef.createField("vector", field); + VectorFieldDef.createField( + "vector", field, mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals( diff --git a/src/test/java/com/yelp/nrtsearch/server/grpc/CustomFieldTypeTest.java b/src/test/java/com/yelp/nrtsearch/server/grpc/CustomFieldTypeTest.java index b315a13ff..a9ec65f92 100644 --- a/src/test/java/com/yelp/nrtsearch/server/grpc/CustomFieldTypeTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/grpc/CustomFieldTypeTest.java @@ -21,6 +21,7 @@ import com.yelp.nrtsearch.server.config.NrtsearchConfig; import com.yelp.nrtsearch.server.doc.LoadedDocValues; import com.yelp.nrtsearch.server.field.FieldDef; +import com.yelp.nrtsearch.server.field.FieldDefCreator; import com.yelp.nrtsearch.server.field.FieldDefProvider; import com.yelp.nrtsearch.server.field.IndexableFieldDef; import com.yelp.nrtsearch.server.plugins.FieldTypePlugin; @@ -98,8 +99,9 @@ private GrpcServer setUpGrpcServer(PrometheusRegistry prometheusRegistry) throws static class TestFieldDef extends IndexableFieldDef { - public TestFieldDef(String name, Field requestField) { - super(name, requestField, Integer.class); + public TestFieldDef( + String name, Field requestField, FieldDefCreator.FieldDefCreatorContext context) { + super(name, requestField, context, Integer.class); } @Override diff --git a/src/test/java/com/yelp/nrtsearch/server/index/BackendStateManagerTest.java b/src/test/java/com/yelp/nrtsearch/server/index/BackendStateManagerTest.java index 9ce75f43b..53cb242b5 100644 --- a/src/test/java/com/yelp/nrtsearch/server/index/BackendStateManagerTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/index/BackendStateManagerTest.java @@ -145,6 +145,7 @@ public void testLoadsExistingState() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verifyNoMoreInteractions(mockBackend, mockGlobalState, mockState); } @@ -172,6 +173,7 @@ public void testLoadsExistingState_liveSettingsOverride() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verifyNoMoreInteractions(mockBackend, mockGlobalState, mockState); } @@ -199,6 +201,7 @@ public void testLoadFixesIndexName() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verifyNoMoreInteractions(mockBackend, mockGlobalState, mockState); } @@ -331,6 +334,7 @@ public void testGetSettings() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getMergedSettings(); verifyNoMoreInteractions(mockBackend, mockGlobalState, mockState); @@ -396,6 +400,7 @@ public void testUpdateSettingsNoop() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); @@ -458,6 +463,7 @@ public void testUpdateEmptySettings() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); @@ -538,6 +544,7 @@ public void testUpdateExistingSettings() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); @@ -621,6 +628,7 @@ public void testUpdateExistingSettings_liveSettingsOverride() throws IOException verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); @@ -712,6 +720,7 @@ public void testGetLiveSettings() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getMergedLiveSettings(false); verifyNoMoreInteractions(mockBackend, mockGlobalState, mockState); @@ -759,6 +768,7 @@ public void testGetLiveSettings_liveSettingsOverride() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getMergedLiveSettings(false); verify(mockState, times(1)).getMergedLiveSettings(true); @@ -829,6 +839,7 @@ public void testUpdateLiveSettingsNoop() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getMergedLiveSettings(false); @@ -895,6 +906,7 @@ public void testUpdateEmptyLiveSettings() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getMergedLiveSettings(false); @@ -976,6 +988,7 @@ public void testUpdateExistingLiveSettings() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getMergedLiveSettings(false); @@ -1060,6 +1073,7 @@ public void testUpdateExistingLiveSettings_liveSettingsOverride() throws IOExcep verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedStateInfo); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getMergedLiveSettings(false); @@ -1148,6 +1162,7 @@ public void testUpdateLocalLiveSettings_noInitialOverride() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getMergedLiveSettings(true); @@ -1224,6 +1239,7 @@ public void testUpdateLocalLiveSettings_withInitialOverride() throws IOException verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getMergedLiveSettings(true); @@ -1297,6 +1313,7 @@ public void testUpdateFields() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedState); + verify(mockGlobalState, times(2)).getConfiguration(); verify(mockState, times(2)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getAllFieldsJSON(); @@ -1371,6 +1388,7 @@ public void testUpdateFields_liveSettingsOverride() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedState); + verify(mockGlobalState, times(2)).getConfiguration(); verify(mockState, times(2)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getAllFieldsJSON(); @@ -1470,6 +1488,7 @@ public void testUpdateFieldsAddToExisting() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), expectedState); + verify(mockGlobalState, times(2)).getConfiguration(); verify(mockState, times(2)).getIndexStateInfo(); verify(mockState, times(1)).getFieldAndFacetState(); verify(mockState2, times(1)).getAllFieldsJSON(); @@ -1528,6 +1547,7 @@ public void testLoadFields() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verifyNoMoreInteractions(mockBackend, mockGlobalState, mockState); } @@ -1578,6 +1598,7 @@ public void testStartIndex() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).start(Mode.PRIMARY, mockDataManager, 1, mockReplicationClient); @@ -1614,6 +1635,7 @@ public void testStartIndex_liveSettingsOverride() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).getIndexStateInfo(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).start(Mode.PRIMARY, mockDataManager, 1, mockReplicationClient); @@ -1647,6 +1669,7 @@ public void testStartIndexReplicaSkipCommit() throws IOException { verify(mockBackend, times(1)) .loadIndexState(BackendGlobalState.getUniqueIndexName("test_index", "test_id")); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).start(Mode.REPLICA, mockDataManager, 1, mockReplicationClient); @@ -1690,6 +1713,7 @@ public void testStartIndexInitialCommit() throws IOException { verify(mockBackend, times(1)) .commitIndexState( BackendGlobalState.getUniqueIndexName("test_index", "test_id"), updatedState); + verify(mockGlobalState, times(1)).getConfiguration(); verify(mockState, times(3)).getIndexStateInfo(); verify(mockState, times(1)).isStarted(); verify(mockState, times(1)).start(Mode.PRIMARY, mockDataManager, 1, mockReplicationClient); diff --git a/src/test/java/com/yelp/nrtsearch/server/index/FieldUpdateUtilsTest.java b/src/test/java/com/yelp/nrtsearch/server/index/FieldUpdateUtilsTest.java index a31a75424..703cd2ac2 100644 --- a/src/test/java/com/yelp/nrtsearch/server/index/FieldUpdateUtilsTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/index/FieldUpdateUtilsTest.java @@ -99,7 +99,11 @@ private UpdatedFieldInfo initializeAndCheckSimple() { Map initialFields = Collections.emptyMap(); UpdatedFieldInfo updatedFieldInfo = - FieldUpdateUtils.updateFields(initialState, initialFields, simpleUpdates); + FieldUpdateUtils.updateFields( + initialState, + initialFields, + simpleUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(2, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -146,7 +150,10 @@ public void testRegisterAdditionalFields() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(4, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -190,7 +197,10 @@ public void testRegisterIdField() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(4, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -236,7 +246,10 @@ public void testRegisterSecondIdField() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); try { FieldUpdateUtils.updateFields( @@ -247,7 +260,8 @@ public void testRegisterSecondIdField() { .setName("second_id") .setType(FieldType._ID) .setStoreDocValues(true) - .build())); + .build()), + mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals( @@ -278,7 +292,10 @@ public void testRegisterAnalyzedFields() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(4, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -316,7 +333,10 @@ public void testRegisterVirtualField() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(3, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -359,7 +379,10 @@ public void testRegisterVirtualFieldRefRequest() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(4, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -423,7 +446,10 @@ public void testRegisterFieldWithChildren() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(3, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -493,7 +519,10 @@ public void testRegisterFieldWithNestedChildren() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(3, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -548,7 +577,10 @@ public void testRegisterFieldsWithFacets() { UpdatedFieldInfo updatedFieldInfo = FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); Map fields = updatedFieldInfo.fields; assertEquals(4, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -586,7 +618,10 @@ public void testRegisterFieldsWithFacets() { updatedFieldInfo = FieldUpdateUtils.updateFields( - updatedFieldInfo.fieldAndFacetState, updatedFieldInfo.fields, fieldUpdates2); + updatedFieldInfo.fieldAndFacetState, + updatedFieldInfo.fields, + fieldUpdates2, + mock(FieldDefCreator.FieldDefCreatorContext.class)); fields = updatedFieldInfo.fields; assertEquals(5, fields.size()); assertEquals(simpleUpdates.get(0), fields.get("field1")); @@ -634,7 +669,10 @@ public void testRegisterFieldNameConflict() { try { FieldUpdateUtils.updateFields( - initialInfo.fieldAndFacetState, initialInfo.fields, fieldUpdates); + initialInfo.fieldAndFacetState, + initialInfo.fields, + fieldUpdates, + mock(FieldDefCreator.FieldDefCreatorContext.class)); fail(); } catch (IllegalArgumentException e) { assertEquals("Duplicate field registration: field2", e.getMessage()); diff --git a/src/test/java/com/yelp/nrtsearch/server/index/ImmutableIndexStateTest.java b/src/test/java/com/yelp/nrtsearch/server/index/ImmutableIndexStateTest.java index 152f8c96c..02c7aec50 100644 --- a/src/test/java/com/yelp/nrtsearch/server/index/ImmutableIndexStateTest.java +++ b/src/test/java/com/yelp/nrtsearch/server/index/ImmutableIndexStateTest.java @@ -382,7 +382,10 @@ public void testIndexSort_set() throws IOException { .build(); UpdatedFieldInfo fieldInfo = FieldUpdateUtils.updateFields( - new FieldAndFacetState(), Collections.emptyMap(), Collections.singleton(sortField)); + new FieldAndFacetState(), + Collections.emptyMap(), + Collections.singleton(sortField), + mock(FieldDefCreator.FieldDefCreatorContext.class)); ImmutableIndexState indexState = getIndexState( getStateWithSettings( @@ -1021,7 +1024,10 @@ public void testGetField() throws IOException { .build(); UpdatedFieldInfo fieldInfo = FieldUpdateUtils.updateFields( - new FieldAndFacetState(), Collections.emptyMap(), Collections.singleton(field)); + new FieldAndFacetState(), + Collections.emptyMap(), + Collections.singleton(field), + mock(FieldDefCreator.FieldDefCreatorContext.class)); IndexStateInfo indexStateInfo = getEmptyState().toBuilder().putAllFields(fieldInfo.fields).build(); ImmutableIndexState indexState = getIndexState(indexStateInfo, fieldInfo.fieldAndFacetState); @@ -1053,7 +1059,10 @@ public void testGetFieldOrThrow() throws IOException { .build(); UpdatedFieldInfo fieldInfo = FieldUpdateUtils.updateFields( - new FieldAndFacetState(), Collections.emptyMap(), Collections.singleton(field)); + new FieldAndFacetState(), + Collections.emptyMap(), + Collections.singleton(field), + mock(FieldDefCreator.FieldDefCreatorContext.class)); IndexStateInfo indexStateInfo = getEmptyState().toBuilder().putAllFields(fieldInfo.fields).build(); ImmutableIndexState indexState = getIndexState(indexStateInfo, fieldInfo.fieldAndFacetState); @@ -1090,7 +1099,10 @@ public void testGetAllFields() throws IOException { .build(); UpdatedFieldInfo fieldInfo = FieldUpdateUtils.updateFields( - new FieldAndFacetState(), Collections.emptyMap(), Collections.singleton(field)); + new FieldAndFacetState(), + Collections.emptyMap(), + Collections.singleton(field), + mock(FieldDefCreator.FieldDefCreatorContext.class)); IndexStateInfo indexStateInfo = getEmptyState().toBuilder().putAllFields(fieldInfo.fields).build(); ImmutableIndexState indexState = getIndexState(indexStateInfo, fieldInfo.fieldAndFacetState); @@ -1108,7 +1120,10 @@ public void testGetAllFieldsJSON() throws IOException { .build(); UpdatedFieldInfo fieldInfo = FieldUpdateUtils.updateFields( - new FieldAndFacetState(), Collections.emptyMap(), Collections.singleton(field)); + new FieldAndFacetState(), + Collections.emptyMap(), + Collections.singleton(field), + mock(FieldDefCreator.FieldDefCreatorContext.class)); IndexStateInfo indexStateInfo = getEmptyState().toBuilder().putAllFields(fieldInfo.fields).build(); ImmutableIndexState indexState = getIndexState(indexStateInfo, fieldInfo.fieldAndFacetState);