16
16
17
17
package org .springframework .core .io .buffer ;
18
18
19
+ import java .io .IOException ;
19
20
import java .io .OutputStream ;
20
21
import java .net .URI ;
21
22
import java .nio .ByteBuffer ;
22
23
import java .nio .channels .AsynchronousFileChannel ;
24
+ import java .nio .channels .CompletionHandler ;
23
25
import java .nio .channels .FileChannel ;
24
26
import java .nio .channels .ReadableByteChannel ;
25
27
import java .nio .channels .WritableByteChannel ;
29
31
import java .nio .file .Paths ;
30
32
import java .nio .file .StandardOpenOption ;
31
33
import java .time .Duration ;
32
- import java .util .stream . Collectors ;
34
+ import java .util .concurrent . CountDownLatch ;
33
35
34
36
import io .netty .buffer .ByteBuf ;
35
37
import org .junit .Test ;
@@ -160,9 +162,7 @@ public void writeOutputStream() throws Exception {
160
162
.expectComplete ()
161
163
.verify (Duration .ofSeconds (5 ));
162
164
163
- String result = Files .readAllLines (tempFile )
164
- .stream ()
165
- .collect (Collectors .joining ());
165
+ String result = String .join ("" , Files .readAllLines (tempFile ));
166
166
167
167
assertEquals ("foobarbazqux" , result );
168
168
os .close ();
@@ -188,14 +188,60 @@ public void writeWritableByteChannel() throws Exception {
188
188
.expectComplete ()
189
189
.verify (Duration .ofSeconds (5 ));
190
190
191
- String result = Files .readAllLines (tempFile )
192
- .stream ()
193
- .collect (Collectors .joining ());
191
+ String result = String .join ("" , Files .readAllLines (tempFile ));
194
192
195
193
assertEquals ("foobarbazqux" , result );
196
194
channel .close ();
197
195
}
198
196
197
+ @ Test
198
+ public void writeWritableByteChannelErrorInFlux () throws Exception {
199
+ DataBuffer foo = stringBuffer ("foo" );
200
+ DataBuffer bar = stringBuffer ("bar" );
201
+ Flux <DataBuffer > flux = Flux .just (foo , bar ).concatWith (Flux .error (new RuntimeException ()));
202
+
203
+ Path tempFile = Files .createTempFile ("DataBufferUtilsTests" , null );
204
+ WritableByteChannel channel = Files .newByteChannel (tempFile , StandardOpenOption .WRITE );
205
+
206
+ Flux <DataBuffer > writeResult = DataBufferUtils .write (flux , channel );
207
+ StepVerifier .create (writeResult )
208
+ .consumeNextWith (stringConsumer ("foo" ))
209
+ .consumeNextWith (stringConsumer ("bar" ))
210
+ .expectError ()
211
+ .verify (Duration .ofSeconds (5 ));
212
+
213
+ String result = String .join ("" , Files .readAllLines (tempFile ));
214
+
215
+ assertEquals ("foobar" , result );
216
+ channel .close ();
217
+ }
218
+
219
+ @ Test
220
+ public void writeWritableByteChannelErrorInWrite () throws Exception {
221
+ DataBuffer foo = stringBuffer ("foo" );
222
+ DataBuffer bar = stringBuffer ("bar" );
223
+ Flux <DataBuffer > flux = Flux .just (foo , bar );
224
+
225
+ WritableByteChannel channel = mock (WritableByteChannel .class );
226
+ when (channel .write (any ()))
227
+ .thenAnswer (invocation -> {
228
+ ByteBuffer buffer = invocation .getArgument (0 );
229
+ int written = buffer .remaining ();
230
+ buffer .position (buffer .limit ());
231
+ return written ;
232
+ })
233
+ .thenThrow (new IOException ());
234
+
235
+ Flux <DataBuffer > writeResult = DataBufferUtils .write (flux , channel );
236
+ StepVerifier .create (writeResult )
237
+ .consumeNextWith (stringConsumer ("foo" ))
238
+ .consumeNextWith (stringConsumer ("bar" ))
239
+ .expectError (IOException .class )
240
+ .verify ();
241
+
242
+ channel .close ();
243
+ }
244
+
199
245
@ Test
200
246
public void writeAsynchronousFileChannel () throws Exception {
201
247
DataBuffer foo = stringBuffer ("foo" );
@@ -208,7 +254,7 @@ public void writeAsynchronousFileChannel() throws Exception {
208
254
AsynchronousFileChannel channel =
209
255
AsynchronousFileChannel .open (tempFile , StandardOpenOption .WRITE );
210
256
211
- Flux <DataBuffer > writeResult = DataBufferUtils .write (flux , channel , 0 );
257
+ Flux <DataBuffer > writeResult = DataBufferUtils .write (flux , channel );
212
258
StepVerifier .create (writeResult )
213
259
.consumeNextWith (stringConsumer ("foo" ))
214
260
.consumeNextWith (stringConsumer ("bar" ))
@@ -217,14 +263,142 @@ public void writeAsynchronousFileChannel() throws Exception {
217
263
.expectComplete ()
218
264
.verify (Duration .ofSeconds (5 ));
219
265
220
- String result = Files .readAllLines (tempFile )
221
- .stream ()
222
- .collect (Collectors .joining ());
266
+ String result = String .join ("" , Files .readAllLines (tempFile ));
223
267
224
268
assertEquals ("foobarbazqux" , result );
225
269
channel .close ();
226
270
}
227
271
272
+ @ Test
273
+ public void writeAsynchronousFileChannelErrorInFlux () throws Exception {
274
+ DataBuffer foo = stringBuffer ("foo" );
275
+ DataBuffer bar = stringBuffer ("bar" );
276
+ Flux <DataBuffer > flux =
277
+ Flux .just (foo , bar ).concatWith (Mono .error (new RuntimeException ()));
278
+
279
+ Path tempFile = Files .createTempFile ("DataBufferUtilsTests" , null );
280
+ AsynchronousFileChannel channel =
281
+ AsynchronousFileChannel .open (tempFile , StandardOpenOption .WRITE );
282
+
283
+ Flux <DataBuffer > writeResult = DataBufferUtils .write (flux , channel );
284
+ StepVerifier .create (writeResult )
285
+ .consumeNextWith (stringConsumer ("foo" ))
286
+ .consumeNextWith (stringConsumer ("bar" ))
287
+ .expectError (RuntimeException .class )
288
+ .verify ();
289
+
290
+ String result = String .join ("" , Files .readAllLines (tempFile ));
291
+
292
+ assertEquals ("foobar" , result );
293
+ channel .close ();
294
+ }
295
+
296
+
297
+ @ Test
298
+ public void writeAsynchronousFileChannelErrorInWrite () throws Exception {
299
+ DataBuffer foo = stringBuffer ("foo" );
300
+ DataBuffer bar = stringBuffer ("bar" );
301
+ Flux <DataBuffer > flux = Flux .just (foo , bar );
302
+
303
+ AsynchronousFileChannel channel = mock (AsynchronousFileChannel .class );
304
+ doAnswer (invocation -> {
305
+ ByteBuffer buffer = invocation .getArgument (0 );
306
+ long pos = invocation .getArgument (1 );
307
+ CompletionHandler <Integer , ByteBuffer > completionHandler = invocation .getArgument (3 );
308
+
309
+ assertEquals (0 , pos );
310
+
311
+ int written = buffer .remaining ();
312
+ buffer .position (buffer .limit ());
313
+ completionHandler .completed (written , buffer );
314
+
315
+ return null ;
316
+ })
317
+ .doAnswer (invocation -> {
318
+ ByteBuffer buffer = invocation .getArgument (0 );
319
+ CompletionHandler <Integer , ByteBuffer > completionHandler =
320
+ invocation .getArgument (3 );
321
+ completionHandler .failed (new IOException (), buffer );
322
+ return null ;
323
+ })
324
+ .when (channel ).write (isA (ByteBuffer .class ), anyLong (), isA (ByteBuffer .class ),
325
+ isA (CompletionHandler .class ));
326
+
327
+ Flux <DataBuffer > writeResult = DataBufferUtils .write (flux , channel );
328
+ StepVerifier .create (writeResult )
329
+ .consumeNextWith (stringConsumer ("foo" ))
330
+ .consumeNextWith (stringConsumer ("bar" ))
331
+ .expectError (IOException .class )
332
+ .verify ();
333
+
334
+ channel .close ();
335
+ }
336
+
337
+ @ Test
338
+ public void readAndWriteByteChannel () throws Exception {
339
+ Path source = Paths .get (
340
+ DataBufferUtilsTests .class .getResource ("DataBufferUtilsTests.txt" ).toURI ());
341
+ Flux <DataBuffer > sourceFlux =
342
+ DataBufferUtils
343
+ .readByteChannel (() -> FileChannel .open (source , StandardOpenOption .READ ),
344
+ this .bufferFactory , 3 );
345
+
346
+ Path destination = Files .createTempFile ("DataBufferUtilsTests" , null );
347
+ WritableByteChannel channel = Files .newByteChannel (destination , StandardOpenOption .WRITE );
348
+
349
+ DataBufferUtils .write (sourceFlux , channel )
350
+ .subscribe (DataBufferUtils .releaseConsumer (),
351
+ throwable -> fail (throwable .getMessage ()),
352
+ () -> {
353
+ try {
354
+ String expected = String .join ("" , Files .readAllLines (source ));
355
+ String result = String .join ("" , Files .readAllLines (destination ));
356
+
357
+ assertEquals (expected , result );
358
+ channel .close ();
359
+
360
+ }
361
+ catch (IOException e ) {
362
+ fail (e .getMessage ());
363
+ }
364
+ });
365
+ }
366
+
367
+ @ Test
368
+ public void readAndWriteAsynchronousFileChannel () throws Exception {
369
+ Path source = Paths .get (
370
+ DataBufferUtilsTests .class .getResource ("DataBufferUtilsTests.txt" ).toURI ());
371
+ Flux <DataBuffer > sourceFlux = DataBufferUtils .readAsynchronousFileChannel (
372
+ () -> AsynchronousFileChannel .open (source , StandardOpenOption .READ ),
373
+ this .bufferFactory , 3 );
374
+
375
+ Path destination = Files .createTempFile ("DataBufferUtilsTests" , null );
376
+ AsynchronousFileChannel channel =
377
+ AsynchronousFileChannel .open (destination , StandardOpenOption .WRITE );
378
+
379
+ CountDownLatch latch = new CountDownLatch (1 );
380
+
381
+ DataBufferUtils .write (sourceFlux , channel )
382
+ .subscribe (DataBufferUtils ::release ,
383
+ throwable -> fail (throwable .getMessage ()),
384
+ () -> {
385
+ try {
386
+ String expected = String .join ("" , Files .readAllLines (source ));
387
+ String result = String .join ("" , Files .readAllLines (destination ));
388
+
389
+ assertEquals (expected , result );
390
+ channel .close ();
391
+ latch .countDown ();
392
+
393
+ }
394
+ catch (IOException e ) {
395
+ fail (e .getMessage ());
396
+ }
397
+ });
398
+
399
+ latch .await ();
400
+ }
401
+
228
402
@ Test
229
403
public void takeUntilByteCount () {
230
404
@@ -314,7 +488,8 @@ public void SPR16070() throws Exception {
314
488
.thenAnswer (putByte ('c' ))
315
489
.thenReturn (-1 );
316
490
317
- Flux <DataBuffer > read = DataBufferUtils .readByteChannel (() -> channel , this .bufferFactory , 1 );
491
+ Flux <DataBuffer > read =
492
+ DataBufferUtils .readByteChannel (() -> channel , this .bufferFactory , 1 );
318
493
319
494
StepVerifier .create (read )
320
495
.consumeNextWith (stringConsumer ("a" ))
@@ -343,9 +518,10 @@ public void join() {
343
518
344
519
StepVerifier .create (result )
345
520
.consumeNextWith (dataBuffer -> {
346
- assertEquals ("foobarbaz" , DataBufferTestUtils .dumpString (dataBuffer , StandardCharsets .UTF_8 ));
347
- release (dataBuffer );
348
- })
521
+ assertEquals ("foobarbaz" ,
522
+ DataBufferTestUtils .dumpString (dataBuffer , StandardCharsets .UTF_8 ));
523
+ release (dataBuffer );
524
+ })
349
525
.verifyComplete ();
350
526
}
351
527
0 commit comments