@SuppressWarnings("unchecked") AsyncConnect(LettuceConnectionProvider connectionProvider, Class<T> connectionType) { Assert.notNull(connectionProvider, "LettuceConnectionProvider must not be null!"); Assert.notNull(connectionType, "Connection type must not be null!"); this.connectionProvider = connectionProvider; Mono<StatefulConnection> defer = Mono .defer(() -> Mono.fromCompletionStage(connectionProvider.getConnectionAsync(connectionType))); this.connectionPublisher = defer.doOnNext(it -> { if (isClosing(this.state.get())) { it.closeAsync(); } else { connection = it; } }) // .cache() // .handle((connection, sink) -> { if (isClosing(this.state.get())) { sink.error(new IllegalStateException("Unable to connect. Connection is closed!")); } else { sink.next((T) connection); } }); }
@Override public void accept(SynchronousSink<DataBuffer> sink) { boolean release = true; DataBuffer dataBuffer = this.dataBufferFactory.allocateBuffer(this.bufferSize); try { int read; ByteBuffer byteBuffer = dataBuffer.asByteBuffer(0, dataBuffer.capacity()); if ((read = this.channel.read(byteBuffer)) >= 0) { dataBuffer.writePosition(read); release = false; sink.next(dataBuffer); } else { sink.complete(); } } catch (IOException ex) { sink.error(ex); } finally { if (release) { release(dataBuffer); } } } }
private Flux<String> chunks1K() { return Flux.generate(sink -> { StringBuilder sb = new StringBuilder(); do { for (char c : "0123456789".toCharArray()) { sb.append(c); if (sb.length() + 1 == 1024) { sink.next(sb.append("\n").toString()); return; } } } while (true); }); }
@Test public void errorAfterCompleteFused() { StepVerifier.create(Flux.just(1) .handle((v, sink) -> { sink.complete(); sink.error(new NullPointerException("boom")); })) .verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class) .hasMessage("Cannot error after a complete or error")); }
@Test public void contextGetMono() throws InterruptedException { StepVerifier.create(Mono.just(1) .log() .handle((d, c) -> c.next(c.currentContext().get("test") + "" + d)) .handle((d, c) -> c.next(c.currentContext().get("test2") + "" + d)) .subscriberContext(ctx -> ctx.put("test2", "bar")) .subscriberContext(ctx -> ctx.put("test", "foo")) .log()) .expectNext("barfoo1") .verifyComplete(); }
@Test public void generatorMultipleOnErrors() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux.<Integer>generate(o -> { o.error(new RuntimeException("forced failure")); o.error(new RuntimeException("forced failure")); }).subscribe(ts); ts.assertNoValues() .assertNotComplete() .assertError(RuntimeException.class) .assertErrorMessage("forced failure"); }
Flux<String> passThrough(Flux<String> f) { return f.handle((a, b) -> b.next(a)); }
@Test public void completeAfterErrorFused() { StepVerifier.create(Flux.just(1) .handle((v, sink) -> { sink.error(new NullPointerException("boom")); sink.complete(); })) .verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class) .hasMessage("Cannot complete after a complete or error")); }
@Override public void accept(SynchronousSink<DataBuffer> sink) { boolean release = true; DataBuffer dataBuffer = this.dataBufferFactory.allocateBuffer(this.bufferSize); try { int read; ByteBuffer byteBuffer = dataBuffer.asByteBuffer(0, dataBuffer.capacity()); if ((read = this.channel.read(byteBuffer)) >= 0) { dataBuffer.writePosition(read); release = false; sink.next(dataBuffer); } else { sink.complete(); } } catch (IOException ex) { sink.error(ex); } finally { if (release) { release(dataBuffer); } } } }
@Test public void contextTest() { StepVerifier.create(Flux.generate(s -> s.next(s.currentContext() .get(AtomicInteger.class) .incrementAndGet())) .take(10) .subscriberContext(ctx -> ctx.put(AtomicInteger.class, new AtomicInteger()))) .expectNext(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .verifyComplete(); }
@Test public void stateConsumerCalled() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); AtomicInteger stateConsumer = new AtomicInteger(); Flux.<Integer, Integer>generate(() -> 1, (s, o) -> { o.complete(); return s; }, stateConsumer::set).subscribe(ts); ts.assertNoValues() .assertComplete() .assertNoError(); Assert.assertEquals(1, stateConsumer.get()); }
@Test public void errorSignal() { int data = 1; Exception exception = new IllegalStateException(); final AtomicReference<Throwable> throwableInOnOperatorError = new AtomicReference<>(); final AtomicReference<Object> dataInOnOperatorError = new AtomicReference<>(); Hooks.onOperatorError((t, d) -> { throwableInOnOperatorError.set(t); dataInOnOperatorError.set(d); return t; }); AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux.just(data). <Integer>handle((v, s) -> s.error(exception)) .subscribe(ts); ts.await() .assertNoValues() .assertError(IllegalStateException.class) .assertNotComplete(); Assert.assertSame(throwableInOnOperatorError.get(), exception); Assert.assertSame(dataInOnOperatorError.get(), data); }
@Override public Mono<OAuth2AuthorizationRequest> removeAuthorizationRequest( ServerWebExchange exchange) { String state = getStateParameter(exchange); if (state == null) { return Mono.empty(); } return exchange.getSession() .map(WebSession::getAttributes) .handle((sessionAttrs, sink) -> { Map<String, OAuth2AuthorizationRequest> stateToAuthzRequest = sessionAttrsMapStateToAuthorizationRequest(sessionAttrs); if (stateToAuthzRequest == null) { sink.complete(); return; } OAuth2AuthorizationRequest removedValue = stateToAuthzRequest.remove(state); if (stateToAuthzRequest.isEmpty()) { sessionAttrs.remove(this.sessionAttributeName); } if (removedValue == null) { sink.complete(); } else { sink.next(removedValue); } }); }
@Test public void nextAfterErrorFused() { StepVerifier.create(Flux.just(1) .handle((v, sink) -> { sink.error(new NullPointerException("boom")); sink.next(2); })) .verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class) .hasMessage("Cannot emit after a complete or error")); }
@Test public void completeAfterErrorFusedConditional() { StepVerifier.create(Flux.just(1) .filter(i -> true) .handle((v, sink) -> { sink.error(new NullPointerException("boom")); sink.complete(); })) .verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class) .hasMessage("Cannot complete after a complete or error")); }
@Test public void contextGetHideMono() throws InterruptedException { StepVerifier.create(Mono.just(1) .hide() .log() .handle((d, c) -> c.next(c.currentContext().get("test") + "" + d)) .handle((d, c) -> c.next(c.currentContext().get("test2") + "" + d)) .subscriberContext(ctx -> ctx.put("test", "foo")) .subscriberContext(ctx -> ctx.put("test2", "bar")) .log()) .expectNext("barfoo1") .verifyComplete(); }
@Test public void generateEmpty() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux.<Integer>generate(o -> { o.complete(); }).subscribe(ts); ts.assertNoValues() .assertNoError() .assertComplete(); }