Skip to content

Commit c352c76

Browse files
committed
Add config option to require indices have an _ID field
1 parent 9577334 commit c352c76

File tree

6 files changed

+77
-2
lines changed

6 files changed

+77
-2
lines changed

docs/server_configuration.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ Example server configuration
117117
- If enabled, the server will use a separate executor for commit operations instead of using the indexing executor.
118118
- false
119119

120+
* - requireIdField
121+
- bool
122+
- If enabled, all indices must contain an _ID field to be started.
123+
- false
124+
120125
.. list-table:: `Threadpool Configuration <https://github.com/Yelp/nrtsearch/blob/master/src/main/java/com/yelp/nrtsearch/server/config/ThreadPoolConfiguration.java>`_ (``threadPoolConfiguration.*``)
121126
:widths: 25 10 50 25
122127
:header-rows: 1

src/main/java/com/yelp/nrtsearch/server/config/NrtsearchConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public class NrtsearchConfig {
113113
private final boolean verifyReplicationIndexId;
114114
private final boolean useKeepAliveForReplication;
115115
private final DirectoryFactory.MMapGrouping mmapGrouping;
116+
private final boolean requireIdField;
116117

117118
@Inject
118119
public NrtsearchConfig(InputStream yamlStream) {
@@ -192,6 +193,7 @@ public NrtsearchConfig(InputStream yamlStream) {
192193
o -> DirectoryFactory.parseMMapGrouping(o.toString()),
193194
DirectoryFactory.MMapGrouping.SEGMENT);
194195
useSeparateCommitExecutor = configReader.getBoolean("useSeparateCommitExecutor", false);
196+
requireIdField = configReader.getBoolean("requireIdField", false);
195197

196198
List<String> indicesWithOverrides = configReader.getKeysOrEmpty("indexLiveSettingsOverrides");
197199
Map<String, IndexLiveSettings> liveSettingsMap = new HashMap<>();
@@ -389,6 +391,10 @@ public boolean getUseSeparateCommitExecutor() {
389391
return useSeparateCommitExecutor;
390392
}
391393

394+
public boolean getRequireIdField() {
395+
return requireIdField;
396+
}
397+
392398
/**
393399
* Substitute all sub strings of the form ${FOO} with the environment variable value env[FOO].
394400
* Variable names may only contain letters, numbers, and underscores. If a variable is not present

src/main/java/com/yelp/nrtsearch/server/index/StartIndexProcessor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class StartIndexProcessor {
4242
private final IndexStateManager indexStateManager;
4343
private final boolean remoteCommit;
4444
private final int discoveryFileUpdateIntervalMs;
45+
private final boolean requireIdField;
4546
private static final Logger logger = LoggerFactory.getLogger(StartIndexProcessor.class);
4647

4748
/**
@@ -53,20 +54,23 @@ public class StartIndexProcessor {
5354
* @param indexStateManager index state manager
5455
* @param remoteCommit whether to commit to remote state
5556
* @param discoveryFileUpdateIntervalMs interval to update backends from discovery file
57+
* @param requireIdField whether the index must have an _ID field defined
5658
*/
5759
public StartIndexProcessor(
5860
String serviceName,
5961
String ephemeralId,
6062
RemoteBackend remoteBackend,
6163
IndexStateManager indexStateManager,
6264
boolean remoteCommit,
63-
int discoveryFileUpdateIntervalMs) {
65+
int discoveryFileUpdateIntervalMs,
66+
boolean requireIdField) {
6467
this.serviceName = serviceName;
6568
this.ephemeralId = ephemeralId;
6669
this.remoteBackend = remoteBackend;
6770
this.indexStateManager = indexStateManager;
6871
this.remoteCommit = remoteCommit;
6972
this.discoveryFileUpdateIntervalMs = discoveryFileUpdateIntervalMs;
73+
this.requireIdField = requireIdField;
7074
}
7175

7276
public StartIndexResponse process(IndexState indexState, StartIndexRequest startIndexRequest)
@@ -96,6 +100,13 @@ public StartIndexResponse process(IndexState indexState, StartIndexRequest start
96100
private StartIndexResponse processInternal(
97101
IndexState indexState, StartIndexRequest startIndexRequest)
98102
throws StartIndexProcessorException {
103+
104+
if (requireIdField && indexState.getIdFieldDef().isEmpty()) {
105+
throw new IllegalArgumentException(
106+
String.format(
107+
"Index %s must have an _ID field defined to be started", indexState.getName()));
108+
}
109+
99110
final ShardState shardState = indexState.getShard(0);
100111
final Mode mode = startIndexRequest.getMode();
101112
final long primaryGen;

src/main/java/com/yelp/nrtsearch/server/state/BackendGlobalState.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,8 @@ private StartIndexResponse startIndex(
450450
.getIndexStartConfig()
451451
.getDataLocationType()
452452
.equals(IndexDataLocationType.REMOTE),
453-
getConfiguration().getDiscoveryFileUpdateIntervalMs());
453+
getConfiguration().getDiscoveryFileUpdateIntervalMs(),
454+
getConfiguration().getRequireIdField());
454455
try {
455456
return startIndexHandler.process(indexStateManager.getCurrent(), startIndexRequest);
456457
} catch (StartIndexProcessorException e) {

src/test/java/com/yelp/nrtsearch/server/config/NrtsearchConfigTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,18 @@ public void testCustomMaxClauseCount() {
232232
NrtsearchConfig luceneConfig = getForConfig(config);
233233
assertEquals(2048, luceneConfig.getMaxClauseCount());
234234
}
235+
236+
@Test
237+
public void testRequireIdField_default() {
238+
String config = "nodeName: \"server_foo\"";
239+
NrtsearchConfig luceneConfig = getForConfig(config);
240+
assertFalse(luceneConfig.getRequireIdField());
241+
}
242+
243+
@Test
244+
public void testRequireIdField_set() {
245+
String config = "requireIdField: true";
246+
NrtsearchConfig luceneConfig = getForConfig(config);
247+
assertTrue(luceneConfig.getRequireIdField());
248+
}
235249
}

src/test/java/com/yelp/nrtsearch/server/grpc/IndexStartTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.io.IOException;
3030
import java.util.Collections;
3131
import java.util.HashSet;
32+
import java.util.List;
3233
import org.apache.lucene.replicator.nrt.ReplicaDeleterManager;
3334
import org.junit.After;
3435
import org.junit.Rule;
@@ -888,4 +889,41 @@ public void testCommitIndexNotStarted() throws IOException {
888889
assertTrue(e.getMessage().contains("index \"test_index:0\" was not started"));
889890
}
890891
}
892+
893+
@Test
894+
public void testNoIdWhenNotRequired() throws IOException {
895+
TestServer server =
896+
TestServer.builder(folder)
897+
.withAutoStartConfig(true, Mode.PRIMARY, 0, IndexDataLocationType.LOCAL)
898+
.withAdditionalConfig("requireIdField: false")
899+
.build();
900+
server.createIndex("test_index");
901+
server.registerFields(
902+
"test_index",
903+
List.of(Field.newBuilder().setName("field1").setType(FieldType.ATOM).build()));
904+
assertFalse(server.isStarted("test_index"));
905+
server.startIndexV2(StartIndexV2Request.newBuilder().setIndexName("test_index").build());
906+
assertTrue(server.isStarted("test_index"));
907+
}
908+
909+
@Test
910+
public void testNoIdWhenRequired() throws IOException {
911+
TestServer server =
912+
TestServer.builder(folder)
913+
.withAutoStartConfig(true, Mode.PRIMARY, 0, IndexDataLocationType.LOCAL)
914+
.withAdditionalConfig("requireIdField: true")
915+
.build();
916+
server.createIndex("test_index");
917+
server.registerFields(
918+
"test_index",
919+
List.of(Field.newBuilder().setName("field1").setType(FieldType.ATOM).build()));
920+
assertFalse(server.isStarted("test_index"));
921+
try {
922+
server.startIndexV2(StartIndexV2Request.newBuilder().setIndexName("test_index").build());
923+
fail();
924+
} catch (StatusRuntimeException e) {
925+
assertTrue(
926+
e.getMessage().contains("Index test_index must have an _ID field defined to be started"));
927+
}
928+
}
891929
}

0 commit comments

Comments
 (0)