Skip to content

Commit d136b40

Browse files
committed
Add strict hash check on top queries indices
Signed-off-by: Jason Chenyang Ji <chenyang.yale@gmail.com>
1 parent efb871c commit d136b40

File tree

4 files changed

+95
-31
lines changed

4 files changed

+95
-31
lines changed

src/main/java/org/opensearch/plugin/insights/core/service/TopQueriesService.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.opensearch.plugin.insights.core.reader.QueryInsightsReaderFactory;
4646
import org.opensearch.plugin.insights.core.service.grouper.MinMaxHeapQueryGrouper;
4747
import org.opensearch.plugin.insights.core.service.grouper.QueryGrouper;
48+
import org.opensearch.plugin.insights.core.utils.ExporterReaderUtils;
4849
import org.opensearch.plugin.insights.rules.model.AggregationType;
4950
import org.opensearch.plugin.insights.rules.model.Attribute;
5051
import org.opensearch.plugin.insights.rules.model.GroupingType;
@@ -545,14 +546,16 @@ public static boolean isTopQueriesIndex(String indexName, IndexMetadata indexMet
545546

546547
// Validate the second part is a valid date in "YYYY.MM.dd" format
547548
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT);
549+
LocalDate date;
548550
try {
549-
LocalDate.parse(parts[1], formatter);
551+
date = LocalDate.parse(parts[1], formatter);
550552
} catch (DateTimeParseException e) {
551553
return false;
552554
}
553555

554-
// Validate the third part is exactly 5 digits
555-
return parts[2].matches("\\d{5}");
556+
// Generate the expected hash for the date and compare with the third part
557+
String expectedHash = ExporterReaderUtils.generateLocalIndexDateHash(date);
558+
return parts[2].equals(expectedHash);
556559
} catch (Exception e) {
557560
return false;
558561
}

src/test/java/org/opensearch/plugin/insights/core/exporter/LocalIndexExporterTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import static org.mockito.Mockito.when;
1919
import static org.opensearch.plugin.insights.core.service.QueryInsightsService.QUERY_INSIGHTS_INDEX_TAG_NAME;
2020
import static org.opensearch.plugin.insights.core.service.TopQueriesService.TOP_QUERIES_INDEX_TAG_VALUE;
21-
import static org.opensearch.plugin.insights.core.utils.ExporterReaderUtils.generateLocalIndexDateHash;
2221

2322
import java.time.ZoneOffset;
2423
import java.time.ZonedDateTime;
@@ -43,6 +42,7 @@
4342
import org.opensearch.common.settings.Settings;
4443
import org.opensearch.common.util.io.IOUtils;
4544
import org.opensearch.plugin.insights.QueryInsightsTestUtils;
45+
import org.opensearch.plugin.insights.core.utils.ExporterReaderUtils;
4646
import org.opensearch.plugin.insights.rules.model.SearchQueryRecord;
4747
import org.opensearch.test.ClusterServiceUtils;
4848
import org.opensearch.test.OpenSearchTestCase;
@@ -69,7 +69,7 @@ public class LocalIndexExporterTests extends OpenSearchTestCase {
6969
public void setup() {
7070
indexName = format.format(ZonedDateTime.now(ZoneOffset.UTC))
7171
+ "-"
72-
+ generateLocalIndexDateHash(ZonedDateTime.now(ZoneOffset.UTC).toLocalDate());
72+
+ ExporterReaderUtils.generateLocalIndexDateHash(ZonedDateTime.now(ZoneOffset.UTC).toLocalDate());
7373
Settings.Builder settingsBuilder = Settings.builder();
7474
Settings settings = settingsBuilder.build();
7575
ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);

src/test/java/org/opensearch/plugin/insights/core/service/QueryInsightsServiceTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
* Unit Tests for {@link QueryInsightsService}.
9595
*/
9696
public class QueryInsightsServiceTests extends OpenSearchTestCase {
97-
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("YYYY.MM.dd", Locale.ROOT);
97+
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT);
9898
private ThreadPool threadPool;
9999
private final Client client = mock(Client.class);
100100
private final NamedXContentRegistry namedXContentRegistry = mock(NamedXContentRegistry.class);

src/test/java/org/opensearch/plugin/insights/core/service/TopQueriesServiceTests.java

+86-25
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
import static org.opensearch.plugin.insights.core.service.TopQueriesService.isTopQueriesIndex;
1818

1919
import java.time.Instant;
20+
import java.time.LocalDate;
21+
import java.time.format.DateTimeFormatter;
2022
import java.util.List;
23+
import java.util.Locale;
2124
import java.util.Map;
2225
import java.util.concurrent.TimeUnit;
2326
import java.util.stream.Collectors;
@@ -32,6 +35,7 @@
3235
import org.opensearch.plugin.insights.core.exporter.QueryInsightsExporterFactory;
3336
import org.opensearch.plugin.insights.core.metrics.OperationalMetricsCounter;
3437
import org.opensearch.plugin.insights.core.reader.QueryInsightsReaderFactory;
38+
import org.opensearch.plugin.insights.core.utils.ExporterReaderUtils;
3539
import org.opensearch.plugin.insights.rules.model.GroupingType;
3640
import org.opensearch.plugin.insights.rules.model.MetricType;
3741
import org.opensearch.plugin.insights.rules.model.SearchQueryRecord;
@@ -222,18 +226,33 @@ private IndexMetadata createValidIndexMetadata(String indexName) {
222226
}
223227

224228
public void testIsTopQueriesIndexWithValidMetaData() {
225-
assertTrue(isTopQueriesIndex("top_queries-2024.01.01-01234", createValidIndexMetadata("top_queries-2024.01.01-01234")));
226-
assertTrue(isTopQueriesIndex("top_queries-2025.12.12-99999", createValidIndexMetadata("top_queries-2025.12.12-99999")));
229+
// Generate correct hash values for test dates
230+
LocalDate date1 = LocalDate.parse("2024.01.01", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
231+
LocalDate date2 = LocalDate.parse("2025.12.12", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
232+
String hash1 = ExporterReaderUtils.generateLocalIndexDateHash(date1);
233+
String hash2 = ExporterReaderUtils.generateLocalIndexDateHash(date2);
234+
235+
// Test with valid index names and correct hash values
236+
assertTrue(isTopQueriesIndex("top_queries-2024.01.01-" + hash1, createValidIndexMetadata("top_queries-2024.01.01-" + hash1)));
237+
assertTrue(isTopQueriesIndex("top_queries-2025.12.12-" + hash2, createValidIndexMetadata("top_queries-2025.12.12-" + hash2)));
238+
239+
// Test with invalid index names (wrong hash, format issues, etc.)
227240
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-012345", createValidIndexMetadata("top_queries-2024.01.01-012345")));
228241
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-0123w", createValidIndexMetadata("top_queries-2024.01.01-0123w")));
229242
assertFalse(isTopQueriesIndex("top_queries-2024.01.01", createValidIndexMetadata("top_queries-2024.01.01")));
230-
assertFalse(isTopQueriesIndex("top_queries-2024.01.32-01234", createValidIndexMetadata("top_queries-2024.01.32-01234")));
243+
assertFalse(isTopQueriesIndex("top_queries-2024.01.32-" + hash1, createValidIndexMetadata("top_queries-2024.01.32-" + hash1)));
231244
assertFalse(isTopQueriesIndex("top_queries-01234", createValidIndexMetadata("top_queries-01234")));
232-
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-01234", createValidIndexMetadata("top_querie-2024.01.01-01234")));
233-
assertFalse(isTopQueriesIndex("2024.01.01-01234", createValidIndexMetadata("2024.01.01-01234")));
245+
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-" + hash1, createValidIndexMetadata("top_querie-2024.01.01-" + hash1)));
246+
assertFalse(isTopQueriesIndex("2024.01.01-" + hash1, createValidIndexMetadata("2024.01.01-" + hash1)));
234247
assertFalse(isTopQueriesIndex("any_index", createValidIndexMetadata("any_index")));
235248
assertFalse(isTopQueriesIndex("", createValidIndexMetadata("")));
236249
assertFalse(isTopQueriesIndex("_customer_index", createValidIndexMetadata("_customer_index")));
250+
251+
// Test with a valid date but incorrect hash
252+
String wrongHash = hash1.equals("00000") ? "11111" : "00000";
253+
assertFalse(
254+
isTopQueriesIndex("top_queries-2024.01.01-" + wrongHash, createValidIndexMetadata("top_queries-2024.01.01-" + wrongHash))
255+
);
237256
}
238257

239258
private IndexMetadata createIndexMetadataWithEmptyMapping(String indexName) {
@@ -250,17 +269,31 @@ private IndexMetadata createIndexMetadataWithEmptyMapping(String indexName) {
250269
}
251270

252271
public void testIsTopQueriesIndexWithEmptyMetaData() {
253-
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-01234", createIndexMetadataWithEmptyMapping("top_queries-2024.01.01-01234")));
254-
assertFalse(isTopQueriesIndex("top_queries-2025.12.12-99999", createIndexMetadataWithEmptyMapping("top_queries-2025.12.12-99999")));
272+
// Generate correct hash values for test dates
273+
LocalDate date1 = LocalDate.parse("2024.01.01", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
274+
LocalDate date2 = LocalDate.parse("2025.12.12", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
275+
String hash1 = ExporterReaderUtils.generateLocalIndexDateHash(date1);
276+
String hash2 = ExporterReaderUtils.generateLocalIndexDateHash(date2);
277+
278+
assertFalse(
279+
isTopQueriesIndex("top_queries-2024.01.01-" + hash1, createIndexMetadataWithEmptyMapping("top_queries-2024.01.01-" + hash1))
280+
);
281+
assertFalse(
282+
isTopQueriesIndex("top_queries-2025.12.12-" + hash2, createIndexMetadataWithEmptyMapping("top_queries-2025.12.12-" + hash2))
283+
);
255284
assertFalse(
256285
isTopQueriesIndex("top_queries-2024.01.01-012345", createIndexMetadataWithEmptyMapping("top_queries-2024.01.01-012345"))
257286
);
258287
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-0123w", createIndexMetadataWithEmptyMapping("top_queries-2024.01.01-0123w")));
259288
assertFalse(isTopQueriesIndex("top_queries-2024.01.01", createIndexMetadataWithEmptyMapping("top_queries-2024.01.01")));
260-
assertFalse(isTopQueriesIndex("top_queries-2024.01.32-01234", createIndexMetadataWithEmptyMapping("top_queries-2024.01.32-01234")));
289+
assertFalse(
290+
isTopQueriesIndex("top_queries-2024.01.32-" + hash1, createIndexMetadataWithEmptyMapping("top_queries-2024.01.32-" + hash1))
291+
);
261292
assertFalse(isTopQueriesIndex("top_queries-01234", createIndexMetadataWithEmptyMapping("top_queries-01234")));
262-
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-01234", createIndexMetadataWithEmptyMapping("top_querie-2024.01.01-01234")));
263-
assertFalse(isTopQueriesIndex("2024.01.01-01234", createIndexMetadataWithEmptyMapping("2024.01.01-01234")));
293+
assertFalse(
294+
isTopQueriesIndex("top_querie-2024.01.01-" + hash1, createIndexMetadataWithEmptyMapping("top_querie-2024.01.01-" + hash1))
295+
);
296+
assertFalse(isTopQueriesIndex("2024.01.01-" + hash1, createIndexMetadataWithEmptyMapping("2024.01.01-" + hash1)));
264297
assertFalse(isTopQueriesIndex("any_index", createIndexMetadataWithEmptyMapping("any_index")));
265298
assertFalse(isTopQueriesIndex("", createIndexMetadataWithEmptyMapping("")));
266299
assertFalse(isTopQueriesIndex("_customer_index", createIndexMetadataWithEmptyMapping("_customer_index")));
@@ -281,11 +314,17 @@ private IndexMetadata createIndexMetadataWithDifferentValue(String indexName) {
281314
}
282315

283316
public void testIsTopQueriesIndexWithDifferentMetaData() {
317+
// Generate correct hash values for test dates
318+
LocalDate date1 = LocalDate.parse("2024.01.01", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
319+
LocalDate date2 = LocalDate.parse("2025.12.12", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
320+
String hash1 = ExporterReaderUtils.generateLocalIndexDateHash(date1);
321+
String hash2 = ExporterReaderUtils.generateLocalIndexDateHash(date2);
322+
284323
assertFalse(
285-
isTopQueriesIndex("top_queries-2024.01.01-01234", createIndexMetadataWithDifferentValue("top_queries-2024.01.01-01234"))
324+
isTopQueriesIndex("top_queries-2024.01.01-" + hash1, createIndexMetadataWithDifferentValue("top_queries-2024.01.01-" + hash1))
286325
);
287326
assertFalse(
288-
isTopQueriesIndex("top_queries-2025.12.12-99999", createIndexMetadataWithDifferentValue("top_queries-2025.12.12-99999"))
327+
isTopQueriesIndex("top_queries-2025.12.12-" + hash2, createIndexMetadataWithDifferentValue("top_queries-2025.12.12-" + hash2))
289328
);
290329
assertFalse(
291330
isTopQueriesIndex("top_queries-2024.01.01-012345", createIndexMetadataWithDifferentValue("top_queries-2024.01.01-012345"))
@@ -295,11 +334,13 @@ public void testIsTopQueriesIndexWithDifferentMetaData() {
295334
);
296335
assertFalse(isTopQueriesIndex("top_queries-2024.01.01", createIndexMetadataWithDifferentValue("top_queries-2024.01.01")));
297336
assertFalse(
298-
isTopQueriesIndex("top_queries-2024.01.32-01234", createIndexMetadataWithDifferentValue("top_queries-2024.01.32-01234"))
337+
isTopQueriesIndex("top_queries-2024.01.32-" + hash1, createIndexMetadataWithDifferentValue("top_queries-2024.01.32-" + hash1))
299338
);
300339
assertFalse(isTopQueriesIndex("top_queries-01234", createIndexMetadataWithDifferentValue("top_queries-01234")));
301-
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-01234", createIndexMetadataWithDifferentValue("top_querie-2024.01.01-01234")));
302-
assertFalse(isTopQueriesIndex("2024.01.01-01234", createIndexMetadataWithDifferentValue("2024.01.01-01234")));
340+
assertFalse(
341+
isTopQueriesIndex("top_querie-2024.01.01-" + hash1, createIndexMetadataWithDifferentValue("top_querie-2024.01.01-" + hash1))
342+
);
343+
assertFalse(isTopQueriesIndex("2024.01.01-" + hash1, createIndexMetadataWithDifferentValue("2024.01.01-" + hash1)));
303344
assertFalse(isTopQueriesIndex("any_index", createIndexMetadataWithDifferentValue("any_index")));
304345
assertFalse(isTopQueriesIndex("", createIndexMetadataWithDifferentValue("")));
305346
assertFalse(isTopQueriesIndex("_customer_index", createIndexMetadataWithDifferentValue("_customer_index")));
@@ -320,30 +361,50 @@ private IndexMetadata createIndexMetadataWithExtraValue(String indexName) {
320361
}
321362

322363
public void testIsTopQueriesIndexWithExtraMetaData() {
323-
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-01234", createIndexMetadataWithExtraValue("top_queries-2024.01.01-01234")));
324-
assertFalse(isTopQueriesIndex("top_queries-2025.12.12-99999", createIndexMetadataWithExtraValue("top_queries-2025.12.12-99999")));
364+
// Generate correct hash values for test dates
365+
LocalDate date1 = LocalDate.parse("2024.01.01", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
366+
LocalDate date2 = LocalDate.parse("2025.12.12", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
367+
String hash1 = ExporterReaderUtils.generateLocalIndexDateHash(date1);
368+
String hash2 = ExporterReaderUtils.generateLocalIndexDateHash(date2);
369+
370+
assertFalse(
371+
isTopQueriesIndex("top_queries-2024.01.01-" + hash1, createIndexMetadataWithExtraValue("top_queries-2024.01.01-" + hash1))
372+
);
373+
assertFalse(
374+
isTopQueriesIndex("top_queries-2025.12.12-" + hash2, createIndexMetadataWithExtraValue("top_queries-2025.12.12-" + hash2))
375+
);
325376
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-012345", createIndexMetadataWithExtraValue("top_queries-2024.01.01-012345")));
326377
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-0123w", createIndexMetadataWithExtraValue("top_queries-2024.01.01-0123w")));
327378
assertFalse(isTopQueriesIndex("top_queries-2024.01.01", createIndexMetadataWithExtraValue("top_queries-2024.01.01")));
328-
assertFalse(isTopQueriesIndex("top_queries-2024.01.32-01234", createIndexMetadataWithExtraValue("top_queries-2024.01.32-01234")));
379+
assertFalse(
380+
isTopQueriesIndex("top_queries-2024.01.32-" + hash1, createIndexMetadataWithExtraValue("top_queries-2024.01.32-" + hash1))
381+
);
329382
assertFalse(isTopQueriesIndex("top_queries-01234", createIndexMetadataWithExtraValue("top_queries-01234")));
330-
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-01234", createIndexMetadataWithExtraValue("top_querie-2024.01.01-01234")));
331-
assertFalse(isTopQueriesIndex("2024.01.01-01234", createIndexMetadataWithExtraValue("2024.01.01-01234")));
383+
assertFalse(
384+
isTopQueriesIndex("top_querie-2024.01.01-" + hash1, createIndexMetadataWithExtraValue("top_querie-2024.01.01-" + hash1))
385+
);
386+
assertFalse(isTopQueriesIndex("2024.01.01-" + hash1, createIndexMetadataWithExtraValue("2024.01.01-" + hash1)));
332387
assertFalse(isTopQueriesIndex("any_index", createIndexMetadataWithExtraValue("any_index")));
333388
assertFalse(isTopQueriesIndex("", createIndexMetadataWithExtraValue("")));
334389
assertFalse(isTopQueriesIndex("_customer_index", createIndexMetadataWithExtraValue("_customer_index")));
335390
}
336391

337392
public void testIsTopQueriesIndexWithNullMetaData() {
338-
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-01234", null));
339-
assertFalse(isTopQueriesIndex("top_queries-2025.12.12-99999", null));
393+
// Generate correct hash values for test dates
394+
LocalDate date1 = LocalDate.parse("2024.01.01", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
395+
LocalDate date2 = LocalDate.parse("2025.12.12", DateTimeFormatter.ofPattern("yyyy.MM.dd", Locale.ROOT));
396+
String hash1 = ExporterReaderUtils.generateLocalIndexDateHash(date1);
397+
String hash2 = ExporterReaderUtils.generateLocalIndexDateHash(date2);
398+
399+
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-" + hash1, null));
400+
assertFalse(isTopQueriesIndex("top_queries-2025.12.12-" + hash2, null));
340401
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-012345", null));
341402
assertFalse(isTopQueriesIndex("top_queries-2024.01.01-0123w", null));
342403
assertFalse(isTopQueriesIndex("top_queries-2024.01.01", null));
343-
assertFalse(isTopQueriesIndex("top_queries-2024.01.32-01234", null));
404+
assertFalse(isTopQueriesIndex("top_queries-2024.01.32-" + hash1, null));
344405
assertFalse(isTopQueriesIndex("top_queries-01234", null));
345-
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-01234", null));
346-
assertFalse(isTopQueriesIndex("2024.01.01-01234", null));
406+
assertFalse(isTopQueriesIndex("top_querie-2024.01.01-" + hash1, null));
407+
assertFalse(isTopQueriesIndex("2024.01.01-" + hash1, null));
347408
assertFalse(isTopQueriesIndex("any_index", null));
348409
assertFalse(isTopQueriesIndex("", null));
349410
assertFalse(isTopQueriesIndex("_customer_index", null));

0 commit comments

Comments
 (0)