@Test // SPR-16494 @Ignore // https://github.com/reactor/reactor-netty/issues/283 public void serverDetectsClientDisconnect() { assumeTrue(this.server instanceof ReactorHttpServer); Flux<String> result = this.webClient.get() .uri("/infinite") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext("foo 0") .expectNext("foo 1") .thenCancel() .verify(Duration.ofSeconds(5L)); SseController controller = this.wac.getBean(SseController.class); controller.cancellation.block(Duration.ofSeconds(5)); }
@Override public void decode() { Flux<DataBuffer> input = Flux.just(this.pojo1, this.pojo2) .map(this::writeObject) .flatMap(this::dataBuffer); testDecodeAll(input, Pojo.class, step -> step .expectNext(pojo1) .expectNext(pojo2) .verifyComplete()); }
@Test public void decodeMergedChunks() throws IOException { DataBuffer buffer = this.bufferFactory.allocateBuffer(); this.testMsg1.writeDelimitedTo(buffer.asOutputStream()); this.testMsg1.writeDelimitedTo(buffer.asOutputStream()); ResolvableType elementType = forClass(Msg.class); Flux<Message> messages = this.decoder.decode(Mono.just(buffer), elementType, null, emptyMap()); StepVerifier.create(messages) .expectNext(testMsg1) .expectNext(testMsg1) .verifyComplete(); }
.expectNext(bigMessage) .verifyComplete());
@Test public void decodeSplitChunks() { Flux<DataBuffer> input = Flux.just(this.testMsg1, this.testMsg2) .flatMap(msg -> Mono.defer(() -> { DataBuffer buffer = this.bufferFactory.allocateBuffer(); try { msg.writeDelimitedTo(buffer.asOutputStream()); return Mono.just(buffer); } catch (IOException e) { release(buffer); return Mono.error(e); } })) .flatMap(buffer -> { int len = buffer.readableByteCount() / 2; Flux<DataBuffer> result = Flux.just( DataBufferUtils.retain(buffer.slice(0, len)), DataBufferUtils .retain(buffer.slice(len, buffer.readableByteCount() - len)) ); release(buffer); return result; }); testDecode(input, Msg.class, step -> step .expectNext(this.testMsg1) .expectNext(this.testMsg2) .verifyComplete()); }
@Test public void decodeNewLine() { Flux<DataBuffer> input = Flux.just( stringBuffer("\r\nabc\n"), stringBuffer("def"), stringBuffer("ghi\r\n\n"), stringBuffer("jkl"), stringBuffer("mno\npqr\n"), stringBuffer("stu"), stringBuffer("vw"), stringBuffer("xyz") ); testDecode(input, String.class, step -> step .expectNext("") .expectNext("abc") .expectNext("defghi") .expectNext("") .expectNext("jklmno") .expectNext("pqr") .expectNext("stuvwxyz") .expectComplete() .verify()); }
@Test public void decodeNewLineIncludeDelimiters() { this.decoder = StringDecoder.allMimeTypes(StringDecoder.DEFAULT_DELIMITERS, false); Flux<DataBuffer> input = Flux.just( stringBuffer("\r\nabc\n"), stringBuffer("def"), stringBuffer("ghi\r\n\n"), stringBuffer("jkl"), stringBuffer("mno\npqr\n"), stringBuffer("stu"), stringBuffer("vw"), stringBuffer("xyz") ); testDecode(input, String.class, step -> step .expectNext("\r\n") .expectNext("abc\n") .expectNext("defghi\r\n") .expectNext("\n") .expectNext("jklmno\n") .expectNext("pqr\n") .expectNext("stuvwxyz") .expectComplete() .verify()); }
@Override @Test public void decode() { Flux<DataBuffer> input = Flux.just(this.testMsg1, this.testMsg2) .flatMap(msg -> Mono.defer(() -> { DataBuffer buffer = this.bufferFactory.allocateBuffer(); try { msg.writeDelimitedTo(buffer.asOutputStream()); return Mono.just(buffer); } catch (IOException e) { release(buffer); return Mono.error(e); } })); testDecodeAll(input, Msg.class, step -> step .expectNext(this.testMsg1) .expectNext(this.testMsg2) .verifyComplete()); }
@Test public void values() { Flux<Msg> result = this.webClient.get() .uri("/messages") .exchange() .doOnNext(response -> { Assert.assertEquals("true", response.headers().contentType().get().getParameters().get("delimited")); Assert.assertEquals("sample.proto", response.headers().header("X-Protobuf-Schema").get(0)); Assert.assertEquals("Msg", response.headers().header("X-Protobuf-Message").get(0)); }) .flatMapMany(response -> response.bodyToFlux(Msg.class)); StepVerifier.create(result) .expectNext(TEST_MSG) .expectNext(TEST_MSG) .expectNext(TEST_MSG) .verifyComplete(); }
@Test public void streaming() { Flux<Msg> result = this.webClient.get() .uri("/message-stream") .exchange() .doOnNext(response -> { Assert.assertEquals("true", response.headers().contentType().get().getParameters().get("delimited")); Assert.assertEquals("sample.proto", response.headers().header("X-Protobuf-Schema").get(0)); Assert.assertEquals("Msg", response.headers().header("X-Protobuf-Message").get(0)); }) .flatMapMany(response -> response.bodyToFlux(Msg.class)); StepVerifier.create(result) .expectNext(Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(0).build()).build()) .expectNext(Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(1).build()).build()) .thenCancel() .verify(); }
@Test public void sseAsString() { Flux<String> result = this.webClient.get() .uri("/string") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext("foo 0") .expectNext("foo 1") .thenCancel() .verify(Duration.ofSeconds(5L)); }
@Test public void smileStreaming() { Flux<Person> result = this.webClient.get() .uri("/stream") .accept(new MediaType("application", "stream+x-jackson-smile")) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .thenCancel() .verify(); }
@Test public void sseAsString() { Flux<String> result = this.webClient.get() .uri("/string") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext("foo 0") .expectNext("foo 1") .expectComplete() .verify(Duration.ofSeconds(5L)); }
@Test public void httpEntityWithFluxBody() throws Exception { ServerWebExchange exchange = postExchange("line1\nline2\nline3\n"); ResolvableType type = httpEntityType(Flux.class, String.class); HttpEntity<Flux<String>> httpEntity = resolveValue(exchange, type); assertEquals(exchange.getRequest().getHeaders(), httpEntity.getHeaders()); StepVerifier.create(httpEntity.getBody()) .expectNext("line1") .expectNext("line2") .expectNext("line3") .expectComplete() .verify(); }
@Test public void sseAsPerson() { Flux<Person> result = this.webClient.get() .uri("/person") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .thenCancel() .verify(Duration.ofSeconds(5L)); }
@Test public void jsonStreaming() { Flux<Person> result = this.webClient.get() .uri("/stream") .accept(APPLICATION_STREAM_JSON) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .thenCancel() .verify(); }
@Test public void sseAsPerson() { Flux<Person> result = this.webClient.get() .uri("/person") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .expectComplete() .verify(Duration.ofSeconds(5L)); }
@Test public void decodeMultipleXmlTypeElement() throws Exception { Mono<DataBuffer> source = stringBuffer(POJO_CHILD); Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(TypePojo.class), null, Collections.emptyMap()); StepVerifier.create(output) .expectNext(new TypePojo("foo", "bar")) .expectNext(new TypePojo("foofoo", "barbar")) .expectComplete() .verify(); }
@Override @Test public void decode() { Flux<DataBuffer> input = Flux.concat( stringBuffer("[{\"bar\":\"b1\",\"foo\":\"f1\"},"), stringBuffer("{\"bar\":\"b2\",\"foo\":\"f2\"}]")); testDecodeAll(input, Pojo.class, step -> step .expectNext(pojo1) .expectNext(pojo2) .verifyComplete()); }
@Test public void decodeMultipleXmlRootElement() throws Exception { Mono<DataBuffer> source = stringBuffer(POJO_CHILD); Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(Pojo.class), null, Collections.emptyMap()); StepVerifier.create(output) .expectNext(new Pojo("foo", "bar")) .expectNext(new Pojo("foofoo", "barbar")) .expectComplete() .verify(); }