@Override @SuppressWarnings({"rawtypes", "unchecked"}) // on JDK 9 where XMLEventReader is Iterator<Object> public Flux<XMLEvent> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { Flux<DataBuffer> flux = Flux.from(inputStream); if (this.useAalto) { AaltoDataBufferToXmlEvent aaltoMapper = new AaltoDataBufferToXmlEvent(); return flux.flatMap(aaltoMapper) .doFinally(signalType -> aaltoMapper.endOfInput()); } else { Mono<DataBuffer> singleBuffer = DataBufferUtils.join(flux); return singleBuffer. flatMapMany(dataBuffer -> { try { InputStream is = dataBuffer.asInputStream(); Iterator eventReader = inputFactory.createXMLEventReader(is); return Flux.fromIterable((Iterable<XMLEvent>) () -> eventReader) .doFinally(t -> DataBufferUtils.release(dataBuffer)); } catch (XMLStreamException ex) { return Mono.error(ex); } }); } }
@Test public void severalInARowExecutedInReverseOrder() { Queue<String> finallyOrder = new ConcurrentLinkedDeque<>(); Flux.just("b") .hide() .doFinally(s -> finallyOrder.offer("FIRST")) .doFinally(s -> finallyOrder.offer("SECOND")) .blockLast(); Assertions.assertThat(finallyOrder) .containsExactly("SECOND", "FIRST"); }
@Test public void severalInARowExecutedInReverseOrder() { Queue<String> finallyOrder = new ConcurrentLinkedDeque<>(); Flux.just("b") .hide() .doFinally(s -> finallyOrder.offer("FIRST")) .doFinally(s -> finallyOrder.offer("SECOND")) .blockLast(); Assertions.assertThat(finallyOrder) .containsExactly("SECOND", "FIRST"); }
@Test(expected = NullPointerException.class) public void nullCallback() { Flux.just(1).doFinally(null); }
@Override public Flux<? extends Message<String, V>> listenTo(Topic... topics) { ReactiveRedisMessageListenerContainer container = new ReactiveRedisMessageListenerContainer(getConnectionFactory()); return container .receive(Arrays.asList(topics), getSerializationContext().getStringSerializationPair(), getSerializationContext().getValueSerializationPair()) // .doFinally((signalType) -> container.destroyLater().subscribeOn(Schedulers.elastic())); }
@Test public void errorHandlingDoFinally() { LongAdder statsCancel = new LongAdder(); // <1> Flux<String> flux = Flux.just("foo", "bar") .doFinally(type -> { if (type == SignalType.CANCEL) // <2> statsCancel.increment(); // <3> }) .take(1); // <4> StepVerifier.create(flux) .expectNext("foo") .verifyComplete(); assertThat(statsCancel.intValue()).isEqualTo(1); }
@Test public void normalError() { StepVerifier.create(Flux.error(new IllegalArgumentException()).doFinally(this)) .expectNoFusionSupport() .expectError(IllegalArgumentException.class) .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_ERROR, signalType); }
@Test public void normalErrorConditional() { StepVerifier.create(Flux.error(new IllegalArgumentException()) .hide() .doFinally(this) .filter(i -> true)) .expectNoFusionSupport() .expectError(IllegalArgumentException.class) .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_ERROR, signalType); }
@Test public void normalEmpty() { StepVerifier.create(Flux.empty().doFinally(this)) .expectNoFusionSupport() .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void syncFusedThreadBarrier() { StepVerifier.create(Flux.range(1, 5).doFinally(this)) .expectFusion(SYNC | THREAD_BARRIER , NONE) .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void syncFused() { StepVerifier.create(Flux.range(1, 5).doFinally(this)) .expectFusion(SYNC) .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void normalJust() { StepVerifier.create(Flux.just(1).hide().doFinally(this)) .expectNoFusionSupport() .expectNext(1) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void syncFusedThreadBarrierConditional() { StepVerifier.create(Flux.range(1, 5) .doFinally(this) .filter(i -> true)) .expectFusion(SYNC | THREAD_BARRIER, NONE) .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void normalEmptyConditional() { StepVerifier.create(Flux.empty() .hide() .doFinally(this) .filter(i -> true)) .expectNoFusionSupport() .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void normalTake() { StepVerifier.create(Flux.range(1, 5) .hide() .doFinally(this)) .expectNoFusionSupport() .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void syncFusedConditional() { StepVerifier.create(Flux.range(1, 5) .doFinally(this) .filter(i -> true)) .expectFusion(SYNC) .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void normalTakeConditional() { StepVerifier.create(Flux.range(1, 5) .hide() .doFinally(this) .filter(i -> true)) .expectNoFusionSupport() .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void normalCancel() { StepVerifier.create(Flux.range(1, 10).hide().doFinally(this).take(5)) .expectNoFusionSupport() .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.CANCEL, signalType); }
@Test public void normalJustConditional() { StepVerifier.create(Flux.just(1) .hide() .doFinally(this) .filter(i -> true)) .expectNoFusionSupport() .expectNext(1) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
@Test public void normalCancelConditional() { StepVerifier.create(Flux.range(1, 10) .hide() .doFinally(this) .filter(i -> true) .take(5)) .expectNoFusionSupport() .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.CANCEL, signalType); }