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:
parent
a98be035a3
commit
8d26c738a0
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue