@@ -2378,6 +2378,64 @@ public void testPit() throws Exception {
2378
2378
}
2379
2379
}
2380
2380
2381
+ public void testScroll () throws Exception {
2382
+ List <String > docIds = setupDataStream ();
2383
+ String dataDocId = "1" ;
2384
+ String failuresDocId = docIds .stream ().filter (id -> false == id .equals (dataDocId )).findFirst ().get ();
2385
+
2386
+ createUser ("user" , PASSWORD , "role" );
2387
+ upsertRole ("""
2388
+ {
2389
+ "cluster": ["all"],
2390
+ "indices": [
2391
+ {
2392
+ "names": ["test*"],
2393
+ "privileges": ["read"]
2394
+ }
2395
+ ]
2396
+ }""" , "role" );
2397
+
2398
+ {
2399
+ // user has no access to failure store, searching failures should not work
2400
+ expectThrows (
2401
+ () -> performRequest ("user" , new Request ("POST" , Strings .format ("/%s/_search?scroll=1m" , "test1::failures" ))),
2402
+ 403
2403
+ );
2404
+
2405
+ // searching data should work
2406
+ final String scrollId = performScrollSearchRequestAndAssertDocs ("test1" , dataDocId );
2407
+
2408
+ // further searches with scroll_id should work, but won't return any more hits
2409
+ assertSearchHasNoHits (performScrollSearchRequest ("user" , scrollId ));
2410
+
2411
+ deleteScroll (scrollId );
2412
+ }
2413
+
2414
+ upsertRole ("""
2415
+ {
2416
+ "cluster": ["all"],
2417
+ "indices": [
2418
+ {
2419
+ "names": ["test*"],
2420
+ "privileges": ["read_failure_store"]
2421
+ }
2422
+ ]
2423
+ }""" , "role" );
2424
+
2425
+ {
2426
+ // user has only read access to failure store, searching data should fail
2427
+ expectThrows (() -> performRequest ("user" , new Request ("POST" , Strings .format ("/%s/_search?scroll=1m" , "test1" ))), 403 );
2428
+
2429
+ // searching failure store should work
2430
+ final String scrollId = performScrollSearchRequestAndAssertDocs ("test1::failures" , failuresDocId );
2431
+
2432
+ // further searches with scroll_id should work, but won't return any more hits
2433
+ assertSearchHasNoHits (performScrollSearchRequest ("user" , scrollId ));
2434
+
2435
+ deleteScroll (scrollId );
2436
+ }
2437
+ }
2438
+
2381
2439
public void testDlsFls () throws Exception {
2382
2440
setupDataStream ();
2383
2441
@@ -2965,6 +3023,61 @@ protected void assertSearchResponseContainsExpectedIndicesAndFields(
2965
3023
}
2966
3024
}
2967
3025
3026
+ private void deleteScroll (String scrollId ) throws IOException {
3027
+ Request deleteScroll = new Request ("DELETE" , "/_search/scroll" );
3028
+ deleteScroll .setJsonEntity (Strings .format ("""
3029
+ {
3030
+ "scroll_id": "%s"
3031
+ }
3032
+ """ , scrollId ));
3033
+ Response deleteScrollResponse = performRequest ("user" , deleteScroll );
3034
+ assertOK (deleteScrollResponse );
3035
+ }
3036
+
3037
+ private String performScrollSearchRequestAndAssertDocs (String indexExpression , String docId ) throws IOException {
3038
+ Response scrollResponse = performRequest ("user" , new Request ("POST" , Strings .format ("/%s/_search?scroll=1m" , indexExpression )));
3039
+ assertOK (scrollResponse );
3040
+
3041
+ final SearchResponse searchResponse = SearchResponseUtils .parseSearchResponse (responseAsParser (scrollResponse ));
3042
+ final String scrollId = searchResponse .getScrollId ();
3043
+ assertThat (scrollId , notNullValue ());
3044
+ try {
3045
+ assertSearchContainsDocs (searchResponse , docId );
3046
+ } finally {
3047
+ searchResponse .decRef ();
3048
+ }
3049
+ return scrollId ;
3050
+ }
3051
+
3052
+ private SearchResponse performScrollSearchRequest (String user , String scrollId ) throws IOException {
3053
+ Request searchRequestWithScrollId = new Request ("POST" , "/_search/scroll" );
3054
+ searchRequestWithScrollId .setJsonEntity (Strings .format ("""
3055
+ {
3056
+ "scroll": "1m",
3057
+ "scroll_id": "%s"
3058
+ }
3059
+ """ , scrollId ));
3060
+ Response response = performRequest (user , searchRequestWithScrollId );
3061
+ assertOK (response );
3062
+ return SearchResponseUtils .parseSearchResponse (responseAsParser (response ));
3063
+ }
3064
+
3065
+ private static void assertSearchContainsDocs (SearchResponse searchResponse , String ... docIds ) {
3066
+ SearchHit [] hits = searchResponse .getHits ().getHits ();
3067
+ assertThat (hits .length , equalTo (docIds .length ));
3068
+ List <String > actualDocIds = Arrays .stream (hits ).map (SearchHit ::getId ).toList ();
3069
+ assertThat (actualDocIds , containsInAnyOrder (docIds ));
3070
+ }
3071
+
3072
+ private static void assertSearchHasNoHits (SearchResponse searchResponse ) {
3073
+ try {
3074
+ SearchHit [] hits = searchResponse .getHits ().getHits ();
3075
+ assertThat (hits .length , equalTo (0 ));
3076
+ } finally {
3077
+ searchResponse .decRef ();
3078
+ }
3079
+ }
3080
+
2968
3081
static void addRandomPragmas (XContentBuilder builder ) throws IOException {
2969
3082
if (Build .current ().isSnapshot ()) {
2970
3083
Settings pragmas = randomPragmas ();
0 commit comments