99package org .opensearch .rest ;
1010
1111import org .opensearch .client .Request ;
12+ import org .opensearch .client .RequestOptions ;
1213import org .opensearch .client .Response ;
1314import org .opensearch .client .ResponseException ;
1415import org .opensearch .client .StreamingRequest ;
@@ -48,8 +49,10 @@ public void tearDown() throws Exception {
4849 public void testStreamingRequestNoBatching () throws IOException {
4950 final VirtualTimeScheduler scheduler = VirtualTimeScheduler .create (true );
5051
51- final Stream <String > stream = IntStream .range (1 , 6 )
52- .mapToObj (id -> "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" " + id + "\" } }\n " + "{ \" name\" : \" josh\" }\n " );
52+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
53+ { "index": { "_index": "test-streaming", "_id": "%d" } }
54+ { "name": "josh" }
55+ """ , id ));
5356
5457 final Duration delay = Duration .ofMillis (1 );
5558 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
@@ -86,9 +89,87 @@ public void testStreamingRequestNoBatching() throws IOException {
8689 assertThat (count , equalTo (5 ));
8790 }
8891
92+ public void testStreamingRequestOpaqueId () throws IOException {
93+ final VirtualTimeScheduler scheduler = VirtualTimeScheduler .create (true );
94+
95+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
96+ { "index": { "_index": "test-streaming", "_id": "%d" } }
97+ { "name": "josh" }
98+ """ , id ));
99+
100+ final RequestOptions options = RequestOptions .DEFAULT .toBuilder ().addHeader ("X-Opaque-Id" , "1" ).build ();
101+
102+ final Duration delay = Duration .ofMillis (1 );
103+ final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
104+ "POST" ,
105+ "/_bulk/stream" ,
106+ Flux .fromStream (stream ).delayElements (delay , scheduler ).map (s -> ByteBuffer .wrap (s .getBytes (StandardCharsets .UTF_8 )))
107+ );
108+ streamingRequest .addParameter ("refresh" , "true" );
109+ streamingRequest .setOptions (options );
110+
111+ final StreamingResponse <ByteBuffer > streamingResponse = client ().streamRequest (streamingRequest );
112+ scheduler .advanceTimeBy (delay ); /* emit first element */
113+
114+ StepVerifier .create (Flux .from (streamingResponse .getBody ()).map (b -> new String (b .array (), StandardCharsets .UTF_8 )))
115+ .expectNextMatches (s -> s .contains ("\" result\" :\" created\" " ) && s .contains ("\" _id\" :\" 1\" " ))
116+ .then (() -> scheduler .advanceTimeBy (delay ))
117+ .expectNextMatches (s -> s .contains ("\" result\" :\" created\" " ) && s .contains ("\" _id\" :\" 2\" " ))
118+ .then (() -> scheduler .advanceTimeBy (delay ))
119+ .expectNextMatches (s -> s .contains ("\" result\" :\" created\" " ) && s .contains ("\" _id\" :\" 3\" " ))
120+ .then (() -> scheduler .advanceTimeBy (delay ))
121+ .expectNextMatches (s -> s .contains ("\" result\" :\" created\" " ) && s .contains ("\" _id\" :\" 4\" " ))
122+ .then (() -> scheduler .advanceTimeBy (delay ))
123+ .expectNextMatches (s -> s .contains ("\" result\" :\" created\" " ) && s .contains ("\" _id\" :\" 5\" " ))
124+ .then (() -> scheduler .advanceTimeBy (delay ))
125+ .expectComplete ()
126+ .verify ();
127+
128+ assertThat (streamingResponse .getHeader ("X-Opaque-Id" ), equalTo ("1" ));
129+ assertThat (streamingResponse .getStatusLine ().getStatusCode (), equalTo (200 ));
130+ assertThat (streamingResponse .getWarnings (), empty ());
131+
132+ final Request request = new Request ("GET" , "/test-streaming/_count" );
133+ final Response response = client ().performRequest (request );
134+ final ObjectPath objectPath = ObjectPath .createFromResponse (response );
135+ final Integer count = objectPath .evaluate ("count" );
136+ assertThat (count , equalTo (5 ));
137+ }
138+
139+ public void testStreamingRequestOpaqueIdTwice () throws IOException {
140+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
141+ { "index": { "_index": "test-streaming", "_id": "%d" } }
142+ { "name": "josh" }
143+ """ , id ));
144+
145+ final RequestOptions options = RequestOptions .DEFAULT .toBuilder ()
146+ .addHeader ("X-Opaque-Id" , "1" )
147+ .addHeader ("X-Opaque-Id" , "2" )
148+ .build ();
149+
150+ final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
151+ "POST" ,
152+ "/_bulk/stream" ,
153+ Flux .fromStream (stream ).map (s -> ByteBuffer .wrap (s .getBytes (StandardCharsets .UTF_8 )))
154+ );
155+ streamingRequest .addParameter ("refresh" , "true" );
156+ streamingRequest .setOptions (options );
157+
158+ final StreamingResponse <ByteBuffer > streamingResponse = client ().streamRequest (streamingRequest );
159+
160+ StepVerifier .create (Flux .from (streamingResponse .getBody ()).map (b -> new String (b .array (), StandardCharsets .UTF_8 )))
161+ .expectError (ResponseException .class )
162+ .verify ();
163+
164+ assertThat (streamingResponse .getStatusLine ().getStatusCode (), equalTo (400 ));
165+ assertThat (streamingResponse .getWarnings (), empty ());
166+ }
167+
89168 public void testStreamingRequestOneBatchBySize () throws IOException , InterruptedException {
90- final Stream <String > stream = IntStream .range (1 , 6 )
91- .mapToObj (id -> "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" " + id + "\" } }\n " + "{ \" name\" : \" josh\" }\n " );
169+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
170+ { "index": { "_index": "test-streaming", "_id": "%d" } }
171+ { "name": "josh" }
172+ """ , id ));
92173
93174 final Duration delay = Duration .ofMillis (1 );
94175 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
@@ -128,8 +209,10 @@ public void testStreamingRequestOneBatchBySize() throws IOException, Interrupted
128209 }
129210
130211 public void testStreamingRequestManyBatchesBySize () throws IOException {
131- final Stream <String > stream = IntStream .range (1 , 6 )
132- .mapToObj (id -> "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" " + id + "\" } }\n " + "{ \" name\" : \" josh\" }\n " );
212+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
213+ { "index": { "_index": "test-streaming", "_id": "%d" } }
214+ { "name": "josh" }
215+ """ , id ));
133216
134217 final Duration delay = Duration .ofMillis (1 );
135218 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
@@ -171,8 +254,10 @@ public void testStreamingRequestManyBatchesBySize() throws IOException {
171254 }
172255
173256 public void testStreamingRequestManyBatchesByInterval () throws IOException {
174- final Stream <String > stream = IntStream .range (1 , 6 )
175- .mapToObj (id -> "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" " + id + "\" } }\n " + "{ \" name\" : \" josh\" }\n " );
257+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
258+ { "index": { "_index": "test-streaming", "_id": "%d" } }
259+ { "name": "josh" }
260+ """ , id ));
176261
177262 final Duration delay = Duration .ofMillis (500 );
178263 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
@@ -214,8 +299,10 @@ public void testStreamingRequestManyBatchesByInterval() throws IOException {
214299 }
215300
216301 public void testStreamingRequestManyBatchesByIntervalAndSize () throws IOException {
217- final Stream <String > stream = IntStream .range (1 , 6 )
218- .mapToObj (id -> "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" " + id + "\" } }\n " + "{ \" name\" : \" josh\" }\n " );
302+ final Stream <String > stream = IntStream .range (1 , 6 ).mapToObj (id -> String .format (Locale .ENGLISH , """
303+ { "index": { "_index": "test-streaming", "_id": "%d" } }
304+ { "name": "josh" }
305+ """ , id ));
219306
220307 final Duration delay = Duration .ofSeconds (1 );
221308 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
@@ -248,9 +335,10 @@ public void testStreamingRequestManyBatchesByIntervalAndSize() throws IOExceptio
248335 }
249336
250337 public void testStreamingBadRequest () throws IOException {
251- final Stream <String > stream = Stream .of (
252- "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" 1\" } }\n " + "{ \" name\" : \" josh\" }\n "
253- );
338+ final Stream <String > stream = Stream .of ("""
339+ { "index": { "_index": "test-streaming", "_id": "1" } }
340+ { "name": "josh" }
341+ """ );
254342
255343 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
256344 "POST" ,
@@ -272,10 +360,12 @@ public void testStreamingBadRequest() throws IOException {
272360 public void testStreamingBadStream () throws IOException {
273361 final VirtualTimeScheduler scheduler = VirtualTimeScheduler .create (true );
274362
275- final Stream <String > stream = Stream .of (
276- "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" 1\" } }\n " + "{ \" name\" : \" josh\" }\n " ,
277- "{ \" name\" : \" josh\" }\n "
278- );
363+ final Stream <String > stream = Stream .of ("""
364+ { "index": { "_index": "test-streaming", "_id": "1" } }
365+ { "name": "josh" }
366+ """ , """
367+ { "name": "josh" }
368+ """ );
279369
280370 final Duration delay = Duration .ofMillis (1 );
281371 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
@@ -300,13 +390,10 @@ public void testStreamingBadStream() throws IOException {
300390 }
301391
302392 public void testStreamingLargeDocument () throws IOException {
303- final Stream <String > stream = Stream .of (
304- String .format (
305- Locale .getDefault (),
306- "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" 1\" } }\n { \" name\" : \" %s\" }\n " ,
307- randomAlphaOfLength (7000 )
308- )
309- );
393+ final Stream <String > stream = Stream .of (String .format (Locale .getDefault (), """
394+ { "index": { "_index": "test-streaming", "_id": "1" } }
395+ { "name": "%s" }
396+ """ , randomAlphaOfLength (7000 )));
310397
311398 final StreamingRequest <ByteBuffer > streamingRequest = new StreamingRequest <>(
312399 "POST" ,
@@ -329,7 +416,10 @@ public void testStreamingLargeDocumentThatExceedsChunkSize() throws IOException
329416 final Stream <String > stream = Stream .of (
330417 String .format (
331418 Locale .getDefault (),
332- "{ \" index\" : { \" _index\" : \" test-streaming\" , \" _id\" : \" 1\" } }\n { \" name\" : \" %s\" }\n " ,
419+ """
420+ { "index": { "_index": "test-streaming", "_id": "1" } }
421+ { "name": "%s" }
422+ """ ,
333423 randomAlphaOfLength (9000 ) /* the default chunk size limit is set 8k */
334424 )
335425 );
0 commit comments