Polishing

This commit polishes previous one by also accepting
generic types explicitly declared with a class that
extends DataBuffer allowing to write Flux<DefaultDataBuffer>
for example.

Issue: SPR-14952
This commit is contained in:
Sebastien Deleuze 2016-11-25 09:59:08 +01:00
parent a98be035a3
commit 8d26c738a0
14 changed files with 77 additions and 56 deletions

View File

@ -50,9 +50,9 @@ public class MockServerHttpResponse implements ServerHttpResponse {
private final MultiValueMap<String, ResponseCookie> cookies = new LinkedMultiValueMap<>(); private final MultiValueMap<String, ResponseCookie> cookies = new LinkedMultiValueMap<>();
private Publisher<DataBuffer> body; private Publisher<? extends DataBuffer> body;
private Publisher<? extends Publisher<DataBuffer>> bodyWithFlushes; private Publisher<? extends Publisher<? extends DataBuffer>> bodyWithFlushes;
private DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); private DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
@ -77,22 +77,22 @@ public class MockServerHttpResponse implements ServerHttpResponse {
return this.cookies; return this.cookies;
} }
public Publisher<DataBuffer> getBody() { public Publisher<? extends DataBuffer> getBody() {
return this.body; return this.body;
} }
public Publisher<? extends Publisher<DataBuffer>> getBodyWithFlush() { public Publisher<? extends Publisher<? extends DataBuffer>> getBodyWithFlush() {
return this.bodyWithFlushes; return this.bodyWithFlushes;
} }
@Override @Override
public Mono<Void> writeWith(Publisher<DataBuffer> body) { public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
this.body = body; this.body = body;
return Flux.from(this.body).then(); return Flux.from(this.body).then();
} }
@Override @Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<DataBuffer>> body) { public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
this.bodyWithFlushes = body; this.bodyWithFlushes = body;
return Flux.from(this.bodyWithFlushes).then(); return Flux.from(this.bodyWithFlushes).then();
} }

View File

@ -55,7 +55,7 @@ public interface ReactiveHttpOutputMessage extends HttpMessage {
* @param body the body content publisher * @param body the body content publisher
* @return a {@link Mono} that indicates completion or error * @return a {@link Mono} that indicates completion or error
*/ */
Mono<Void> writeWith(Publisher<DataBuffer> body); Mono<Void> writeWith(Publisher<? extends DataBuffer> body);
/** /**
* Use the given {@link Publisher} of {@code Publishers} to write the body of the * Use the given {@link Publisher} of {@code Publishers} to write the body of the
@ -64,7 +64,7 @@ public interface ReactiveHttpOutputMessage extends HttpMessage {
* @param body the body content publisher * @param body the body content publisher
* @return a {@link Mono} that indicates completion or error * @return a {@link Mono} that indicates completion or error
*/ */
Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<DataBuffer>> body); Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body);
/** /**
* Indicate that message handling is complete, allowing for any cleanup or * Indicate that message handling is complete, allowing for any cleanup or

View File

@ -74,20 +74,20 @@ public class ReactorClientHttpRequest extends AbstractClientHttpRequest {
} }
@Override @Override
public Mono<Void> writeWith(Publisher<DataBuffer> body) { public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
return applyBeforeCommit().then(this.httpRequest return applyBeforeCommit().then(this.httpRequest
.send(Flux.from(body).map(NettyDataBufferFactory::toByteBuf))); .send(Flux.from(body).map(NettyDataBufferFactory::toByteBuf)));
} }
@Override @Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<DataBuffer>> body) { public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
Publisher<Publisher<ByteBuf>> byteBufs = Flux.from(body). Publisher<Publisher<ByteBuf>> byteBufs = Flux.from(body).
map(ReactorClientHttpRequest::toByteBufs); map(ReactorClientHttpRequest::toByteBufs);
return applyBeforeCommit().then(this.httpRequest return applyBeforeCommit().then(this.httpRequest
.sendGroups(byteBufs)); .sendGroups(byteBufs));
} }
private static Publisher<ByteBuf> toByteBufs(Publisher<DataBuffer> dataBuffers) { private static Publisher<ByteBuf> toByteBufs(Publisher<? extends DataBuffer> dataBuffers) {
return Flux.from(dataBuffers). return Flux.from(dataBuffers).
map(NettyDataBufferFactory::toByteBuf); map(NettyDataBufferFactory::toByteBuf);
} }

View File

@ -43,14 +43,14 @@ public abstract class AbstractListenerServerHttpResponse extends AbstractServerH
@Override @Override
protected final Mono<Void> writeWithInternal(Publisher<DataBuffer> body) { protected final Mono<Void> writeWithInternal(Publisher<? extends DataBuffer> body) {
return writeAndFlushWithInternal(Mono.just(body)); return writeAndFlushWithInternal(Mono.just(body));
} }
@Override @Override
protected final Mono<Void> writeAndFlushWithInternal(Publisher<? extends Publisher<DataBuffer>> body) { protected final Mono<Void> writeAndFlushWithInternal(Publisher<? extends Publisher<? extends DataBuffer>> body) {
if (this.writeCalled.compareAndSet(false, true)) { if (this.writeCalled.compareAndSet(false, true)) {
Processor<Publisher<DataBuffer>, Void> bodyProcessor = createBodyFlushProcessor(); Processor<? super Publisher<? extends DataBuffer>, Void> bodyProcessor = createBodyFlushProcessor();
return Mono.from(subscriber -> { return Mono.from(subscriber -> {
body.subscribe(bodyProcessor); body.subscribe(bodyProcessor);
bodyProcessor.subscribe(subscriber); bodyProcessor.subscribe(subscriber);
@ -67,6 +67,6 @@ public abstract class AbstractListenerServerHttpResponse extends AbstractServerH
* that will write the response body with flushes to the underlying output. Called from * that will write the response body with flushes to the underlying output. Called from
* {@link #writeAndFlushWithInternal(Publisher)}. * {@link #writeAndFlushWithInternal(Publisher)}.
*/ */
protected abstract Processor<Publisher<DataBuffer>, Void> createBodyFlushProcessor(); protected abstract Processor<? super Publisher<? extends DataBuffer>, Void> createBodyFlushProcessor();
} }

View File

@ -41,7 +41,7 @@ import org.springframework.core.io.buffer.DataBuffer;
* @see UndertowHttpHandlerAdapter * @see UndertowHttpHandlerAdapter
* @see ServerHttpResponse#writeAndFlushWith(Publisher) * @see ServerHttpResponse#writeAndFlushWith(Publisher)
*/ */
abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher<DataBuffer>, Void> { abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher<? extends DataBuffer>, Void> {
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
@ -65,7 +65,7 @@ abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher
} }
@Override @Override
public final void onNext(Publisher<DataBuffer> publisher) { public final void onNext(Publisher<? extends DataBuffer> publisher) {
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace(this.state + " onNext: " + publisher); logger.trace(this.state + " onNext: " + publisher);
} }
@ -100,7 +100,7 @@ abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher
/** /**
* Creates a new processor for subscribing to a body chunk. * Creates a new processor for subscribing to a body chunk.
*/ */
protected abstract Processor<DataBuffer, Void> createBodyProcessor(); protected abstract Processor<? super DataBuffer, Void> createBodyProcessor();
/** /**
* Flushes the output. * Flushes the output.
@ -144,9 +144,9 @@ abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher
REQUESTED { REQUESTED {
@Override @Override
public void onNext(AbstractResponseBodyFlushProcessor processor, Publisher<DataBuffer> chunk) { public void onNext(AbstractResponseBodyFlushProcessor processor, Publisher<? extends DataBuffer> chunk) {
if (processor.changeState(this, RECEIVED)) { if (processor.changeState(this, RECEIVED)) {
Processor<DataBuffer, Void> chunkProcessor = processor.createBodyProcessor(); Processor<? super DataBuffer, Void> chunkProcessor = processor.createBodyProcessor();
chunk.subscribe(chunkProcessor); chunk.subscribe(chunkProcessor);
chunkProcessor.subscribe(new WriteSubscriber(processor)); chunkProcessor.subscribe(new WriteSubscriber(processor));
} }
@ -192,7 +192,7 @@ abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher
@Override @Override
public void onNext(AbstractResponseBodyFlushProcessor processor, public void onNext(AbstractResponseBodyFlushProcessor processor,
Publisher<DataBuffer> publisher) { Publisher<? extends DataBuffer> publisher) {
// ignore // ignore
} }
@ -212,7 +212,7 @@ abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher
subscription.cancel(); subscription.cancel();
} }
public void onNext(AbstractResponseBodyFlushProcessor processor, Publisher<DataBuffer> publisher) { public void onNext(AbstractResponseBodyFlushProcessor processor, Publisher<? extends DataBuffer> publisher) {
throw new IllegalStateException(toString()); throw new IllegalStateException(toString());
} }

View File

@ -125,13 +125,13 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
} }
@Override @Override
public final Mono<Void> writeWith(Publisher<DataBuffer> body) { public final Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
return new ChannelSendOperator<>(body, return new ChannelSendOperator<>(body,
writePublisher -> doCommit(() -> writeWithInternal(writePublisher))); writePublisher -> doCommit(() -> writeWithInternal(writePublisher)));
} }
@Override @Override
public final Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<DataBuffer>> body) { public final Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return new ChannelSendOperator<>(body, return new ChannelSendOperator<>(body,
writePublisher -> doCommit(() -> writeAndFlushWithInternal(writePublisher))); writePublisher -> doCommit(() -> writeAndFlushWithInternal(writePublisher)));
} }
@ -186,14 +186,14 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
* Implement this method to write to the underlying the response. * Implement this method to write to the underlying the response.
* @param body the publisher to write with * @param body the publisher to write with
*/ */
protected abstract Mono<Void> writeWithInternal(Publisher<DataBuffer> body); protected abstract Mono<Void> writeWithInternal(Publisher<? extends DataBuffer> body);
/** /**
* Implement this method to write to the underlying the response, and flush after * Implement this method to write to the underlying the response, and flush after
* each {@code Publisher<DataBuffer>}. * each {@code Publisher<DataBuffer>}.
* @param body the publisher to write and flush with * @param body the publisher to write and flush with
*/ */
protected abstract Mono<Void> writeAndFlushWithInternal(Publisher<? extends Publisher<DataBuffer>> body); protected abstract Mono<Void> writeAndFlushWithInternal(Publisher<? extends Publisher<? extends DataBuffer>> body);
/** /**
* Implement this method to write the status code to the underlying response. * Implement this method to write the status code to the underlying response.

View File

@ -70,13 +70,13 @@ public class ReactorServerHttpResponse extends AbstractServerHttpResponse
} }
@Override @Override
protected Mono<Void> writeWithInternal(Publisher<DataBuffer> publisher) { protected Mono<Void> writeWithInternal(Publisher<? extends DataBuffer> publisher) {
Publisher<ByteBuf> body = toByteBufs(publisher); Publisher<ByteBuf> body = toByteBufs(publisher);
return this.response.send(body); return this.response.send(body);
} }
@Override @Override
protected Mono<Void> writeAndFlushWithInternal(Publisher<? extends Publisher<DataBuffer>> publisher) { protected Mono<Void> writeAndFlushWithInternal(Publisher<? extends Publisher<? extends DataBuffer>> publisher) {
Publisher<Publisher<ByteBuf>> body = Flux.from(publisher) Publisher<Publisher<ByteBuf>> body = Flux.from(publisher)
.map(ReactorServerHttpResponse::toByteBufs); .map(ReactorServerHttpResponse::toByteBufs);
return this.response.sendGroups(body); return this.response.sendGroups(body);
@ -117,7 +117,7 @@ public class ReactorServerHttpResponse extends AbstractServerHttpResponse
return doCommit(() -> this.response.sendFile(file, position, count)); return doCommit(() -> this.response.sendFile(file, position, count));
} }
private static Publisher<ByteBuf> toByteBufs(Publisher<DataBuffer> dataBuffers) { private static Publisher<ByteBuf> toByteBufs(Publisher<? extends DataBuffer> dataBuffers) {
return Flux.from(dataBuffers).map(NettyDataBufferFactory::toByteBuf); return Flux.from(dataBuffers).map(NettyDataBufferFactory::toByteBuf);
} }

View File

@ -71,7 +71,7 @@ public class RxNettyServerHttpResponse extends AbstractServerHttpResponse {
} }
@Override @Override
protected Mono<Void> writeWithInternal(Publisher<DataBuffer> body) { protected Mono<Void> writeWithInternal(Publisher<? extends DataBuffer> body) {
Observable<ByteBuf> content = RxReactiveStreams.toObservable(body) Observable<ByteBuf> content = RxReactiveStreams.toObservable(body)
.map(NettyDataBufferFactory::toByteBuf); .map(NettyDataBufferFactory::toByteBuf);
return Flux.from(RxReactiveStreams.toPublisher(this.response.write(content))) return Flux.from(RxReactiveStreams.toPublisher(this.response.write(content)))
@ -80,7 +80,7 @@ public class RxNettyServerHttpResponse extends AbstractServerHttpResponse {
@Override @Override
protected Mono<Void> writeAndFlushWithInternal( protected Mono<Void> writeAndFlushWithInternal(
Publisher<? extends Publisher<DataBuffer>> body) { Publisher<? extends Publisher<? extends DataBuffer>> body) {
Flux<ByteBuf> bodyWithFlushSignals = Flux.from(body). Flux<ByteBuf> bodyWithFlushSignals = Flux.from(body).
flatMap(publisher -> Flux.from(publisher). flatMap(publisher -> Flux.from(publisher).
map(NettyDataBufferFactory::toByteBuf). map(NettyDataBufferFactory::toByteBuf).

View File

@ -122,7 +122,7 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons
} }
@Override @Override
protected Processor<Publisher<DataBuffer>, Void> createBodyFlushProcessor() { protected Processor<? super Publisher<? extends DataBuffer>, Void> createBodyFlushProcessor() {
ResponseBodyFlushProcessor processor = new ResponseBodyFlushProcessor(); ResponseBodyFlushProcessor processor = new ResponseBodyFlushProcessor();
this.bodyFlushProcessor = processor; this.bodyFlushProcessor = processor;
return processor; return processor;
@ -261,7 +261,7 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons
private class ResponseBodyFlushProcessor extends AbstractResponseBodyFlushProcessor { private class ResponseBodyFlushProcessor extends AbstractResponseBodyFlushProcessor {
@Override @Override
protected Processor<DataBuffer, Void> createBodyProcessor() { protected Processor<? super DataBuffer, Void> createBodyProcessor() {
try { try {
bodyProcessor = new ResponseBodyProcessor(outputStream(), bufferSize); bodyProcessor = new ResponseBodyProcessor(outputStream(), bufferSize);
return bodyProcessor; return bodyProcessor;

View File

@ -29,6 +29,7 @@ import io.undertow.server.handlers.Cookie;
import io.undertow.server.handlers.CookieImpl; import io.undertow.server.handlers.CookieImpl;
import io.undertow.util.HttpString; import io.undertow.util.HttpString;
import org.reactivestreams.Processor; import org.reactivestreams.Processor;
import org.reactivestreams.Publisher;
import org.xnio.ChannelListener; import org.xnio.ChannelListener;
import org.xnio.channels.StreamSinkChannel; import org.xnio.channels.StreamSinkChannel;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -123,7 +124,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
} }
@Override @Override
protected AbstractResponseBodyFlushProcessor createBodyFlushProcessor() { protected Processor<? super Publisher<? extends DataBuffer>, Void> createBodyFlushProcessor() {
return new ResponseBodyFlushProcessor(); return new ResponseBodyFlushProcessor();
} }
@ -209,7 +210,7 @@ public class UndertowServerHttpResponse extends AbstractListenerServerHttpRespon
private class ResponseBodyFlushProcessor extends AbstractResponseBodyFlushProcessor { private class ResponseBodyFlushProcessor extends AbstractResponseBodyFlushProcessor {
@Override @Override
protected Processor<DataBuffer, Void> createBodyProcessor() { protected Processor<? super DataBuffer, Void> createBodyProcessor() {
return UndertowServerHttpResponse.this.createBodyProcessor(); return UndertowServerHttpResponse.this.createBodyProcessor();
} }

View File

@ -72,7 +72,7 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
messageWriter.write(source, ResolvableType.forClass(ServerSentEvent.class), messageWriter.write(source, ResolvableType.forClass(ServerSentEvent.class),
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()); new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap());
Publisher<? extends Publisher<DataBuffer>> result = Flux.from(outputMessage.getBodyWithFlush()); Publisher<? extends Publisher<? extends DataBuffer>> result = Flux.from(outputMessage.getBodyWithFlush());
StepVerifier.create(result) StepVerifier.create(result)
.consumeNextWith(sseConsumer("id:c42\n" + "event:foo\n" + "retry:123\n" + .consumeNextWith(sseConsumer("id:c42\n" + "event:foo\n" + "retry:123\n" +
":bla\n:bla bla\n:bla bla bla\n" + "data:bar\n")) ":bla\n:bla bla\n:bla bla bla\n" + "data:bar\n"))
@ -87,7 +87,7 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
messageWriter.write(source, ResolvableType.forClass(String.class), messageWriter.write(source, ResolvableType.forClass(String.class),
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()); new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap());
Publisher<? extends Publisher<DataBuffer>> result = outputMessage.getBodyWithFlush(); Publisher<? extends Publisher<? extends DataBuffer>> result = outputMessage.getBodyWithFlush();
StepVerifier.create(result) StepVerifier.create(result)
.consumeNextWith(sseConsumer("data:foo\n")) .consumeNextWith(sseConsumer("data:foo\n"))
.consumeNextWith(sseConsumer("data:bar\n")) .consumeNextWith(sseConsumer("data:bar\n"))
@ -102,7 +102,7 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
messageWriter.write(source, ResolvableType.forClass(String.class), messageWriter.write(source, ResolvableType.forClass(String.class),
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()); new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap());
Publisher<? extends Publisher<DataBuffer>> result = outputMessage.getBodyWithFlush(); Publisher<? extends Publisher<? extends DataBuffer>> result = outputMessage.getBodyWithFlush();
StepVerifier.create(result) StepVerifier.create(result)
.consumeNextWith(sseConsumer("data:foo\ndata:bar\n")) .consumeNextWith(sseConsumer("data:foo\ndata:bar\n"))
.consumeNextWith(sseConsumer("data:foo\ndata:baz\n")) .consumeNextWith(sseConsumer("data:foo\ndata:baz\n"))
@ -118,7 +118,7 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
messageWriter.write(source, ResolvableType.forClass(Pojo.class), messageWriter.write(source, ResolvableType.forClass(Pojo.class),
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()); new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap());
Publisher<? extends Publisher<DataBuffer>> result = outputMessage.getBodyWithFlush(); Publisher<? extends Publisher<? extends DataBuffer>> result = outputMessage.getBodyWithFlush();
StepVerifier.create(result) StepVerifier.create(result)
.consumeNextWith(sseConsumer("data:", "{\"foo\":\"foofoo\",\"bar\":\"barbar\"}", "\n")) .consumeNextWith(sseConsumer("data:", "{\"foo\":\"foofoo\",\"bar\":\"barbar\"}", "\n"))
.consumeNextWith(sseConsumer("data:", "{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}", "\n")) .consumeNextWith(sseConsumer("data:", "{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}", "\n"))
@ -127,7 +127,7 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
} }
private Consumer<Publisher<DataBuffer>> sseConsumer(String... expected) { private Consumer<Publisher<? extends DataBuffer>> sseConsumer(String... expected) {
return publisher -> { return publisher -> {
StepVerifier.Step<DataBuffer> builder = StepVerifier.create(publisher); StepVerifier.Step<DataBuffer> builder = StepVerifier.create(publisher);
for (String value : expected) { for (String value : expected) {

View File

@ -27,6 +27,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseCookie;
@ -56,6 +57,20 @@ public class ServerHttpResponseTests {
assertEquals("c", new String(response.body.get(2).asByteBuffer().array(), StandardCharsets.UTF_8)); assertEquals("c", new String(response.body.get(2).asByteBuffer().array(), StandardCharsets.UTF_8));
} }
@Test // SPR-14952
public void writeAndFlushWithFluxOfDefaultDataBuffer() throws Exception {
TestServerHttpResponse response = new TestServerHttpResponse();
Flux<Flux<DefaultDataBuffer>> flux = Flux.just(Flux.just(wrap("foo")));
response.writeAndFlushWith(flux).block();
assertTrue(response.statusCodeWritten);
assertTrue(response.headersWritten);
assertTrue(response.cookiesWritten);
assertEquals(1, response.body.size());
assertEquals("foo", new String(response.body.get(0).asByteBuffer().array(), StandardCharsets.UTF_8));
}
@Test @Test
public void writeWithError() throws Exception { public void writeWithError() throws Exception {
TestServerHttpResponse response = new TestServerHttpResponse(); TestServerHttpResponse response = new TestServerHttpResponse();
@ -119,7 +134,7 @@ public class ServerHttpResponseTests {
private DataBuffer wrap(String a) { private DefaultDataBuffer wrap(String a) {
return new DefaultDataBufferFactory().wrap(ByteBuffer.wrap(a.getBytes(StandardCharsets.UTF_8))); return new DefaultDataBufferFactory().wrap(ByteBuffer.wrap(a.getBytes(StandardCharsets.UTF_8)));
} }
@ -157,7 +172,7 @@ public class ServerHttpResponseTests {
} }
@Override @Override
protected Mono<Void> writeWithInternal(Publisher<DataBuffer> body) { protected Mono<Void> writeWithInternal(Publisher<? extends DataBuffer> body) {
return Flux.from(body).map(b -> { return Flux.from(body).map(b -> {
this.body.add(b); this.body.add(b);
return b; return b;
@ -166,8 +181,13 @@ public class ServerHttpResponseTests {
@Override @Override
protected Mono<Void> writeAndFlushWithInternal( protected Mono<Void> writeAndFlushWithInternal(
Publisher<? extends Publisher<DataBuffer>> body) { Publisher<? extends Publisher<? extends DataBuffer>> bodyWithFlush) {
return Mono.error(new UnsupportedOperationException()); return Flux.from(bodyWithFlush).flatMap(body ->
Flux.from(body).map(b -> {
this.body.add(b);
return b;
})
).then();
} }
} }

View File

@ -49,9 +49,9 @@ public class MockServerHttpResponse implements ServerHttpResponse {
private final MultiValueMap<String, ResponseCookie> cookies = new LinkedMultiValueMap<>(); private final MultiValueMap<String, ResponseCookie> cookies = new LinkedMultiValueMap<>();
private Publisher<DataBuffer> body; private Publisher<? extends DataBuffer> body;
private Publisher<? extends Publisher<DataBuffer>> bodyWithFlushes; private Publisher<? extends Publisher<? extends DataBuffer>> bodyWithFlushes;
private DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); private DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
@ -77,22 +77,22 @@ public class MockServerHttpResponse implements ServerHttpResponse {
return this.cookies; return this.cookies;
} }
public Publisher<DataBuffer> getBody() { public Publisher<? extends DataBuffer> getBody() {
return this.body; return this.body;
} }
public Publisher<? extends Publisher<DataBuffer>> getBodyWithFlush() { public Publisher<? extends Publisher<? extends DataBuffer>> getBodyWithFlush() {
return this.bodyWithFlushes; return this.bodyWithFlushes;
} }
@Override @Override
public Mono<Void> writeWith(Publisher<DataBuffer> body) { public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
this.body = body; this.body = body;
return Flux.from(this.body).then(); return Flux.from(this.body).then();
} }
@Override @Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<DataBuffer>> body) { public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
this.bodyWithFlushes = body; this.bodyWithFlushes = body;
return Flux.from(this.bodyWithFlushes).then(); return Flux.from(this.bodyWithFlushes).then();
} }

View File

@ -41,9 +41,9 @@ public class MockClientHttpRequest extends AbstractClientHttpRequest {
private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
private Publisher<DataBuffer> body; private Publisher<? extends DataBuffer> body;
private Publisher<? extends Publisher<DataBuffer>> bodyWithFlushes; private Publisher<? extends Publisher<? extends DataBuffer>> bodyWithFlushes;
public MockClientHttpRequest() { public MockClientHttpRequest() {
@ -90,22 +90,22 @@ public class MockClientHttpRequest extends AbstractClientHttpRequest {
} }
@Override @Override
public Mono<Void> writeWith(Publisher<DataBuffer> body) { public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
this.body = body; this.body = body;
return applyBeforeCommit().then(Flux.from(this.body).then()); return applyBeforeCommit().then(Flux.from(this.body).then());
} }
@Override @Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<DataBuffer>> body) { public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
this.bodyWithFlushes = body; this.bodyWithFlushes = body;
return applyBeforeCommit().then(Flux.from(this.bodyWithFlushes).then()); return applyBeforeCommit().then(Flux.from(this.bodyWithFlushes).then());
} }
public Publisher<DataBuffer> getBody() { public Publisher<? extends DataBuffer> getBody() {
return body; return body;
} }
public Publisher<? extends Publisher<DataBuffer>> getBodyWithFlush() { public Publisher<? extends Publisher<? extends DataBuffer>> getBodyWithFlush() {
return bodyWithFlushes; return bodyWithFlushes;
} }