Fix empty payload handling in RSocketRequester
Closes gh-24088
This commit is contained in:
@@ -57,7 +57,7 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
|
||||
private final RSocketStrategies strategies;
|
||||
|
||||
private final DataBuffer emptyDataBuffer;
|
||||
private final Mono<DataBuffer> emptyBufferMono;
|
||||
|
||||
|
||||
DefaultRSocketRequester(
|
||||
@@ -73,7 +73,7 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
this.dataMimeType = dataMimeType;
|
||||
this.metadataMimeType = metadataMimeType;
|
||||
this.strategies = strategies;
|
||||
this.emptyDataBuffer = this.strategies.dataBufferFactory().wrap(new byte[0]);
|
||||
this.emptyBufferMono = Mono.just(this.strategies.dataBufferFactory().wrap(new byte[0]));
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
}
|
||||
|
||||
if (isVoid(elementType) || (adapter != null && adapter.isNoValue())) {
|
||||
this.payloadMono = firstPayload(Mono.when(publisher).then(Mono.just(emptyDataBuffer)));
|
||||
this.payloadMono = Mono.when(publisher).then(firstPayload(emptyBufferMono));
|
||||
this.payloadFlux = null;
|
||||
return;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
if (adapter != null && !adapter.isMultiValue()) {
|
||||
Mono<DataBuffer> data = Mono.from(publisher)
|
||||
.map(value -> encodeData(value, elementType, encoder))
|
||||
.defaultIfEmpty(emptyDataBuffer);
|
||||
.switchIfEmpty(emptyBufferMono);
|
||||
this.payloadMono = firstPayload(data);
|
||||
this.payloadFlux = null;
|
||||
return;
|
||||
@@ -213,7 +213,7 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
this.payloadMono = null;
|
||||
this.payloadFlux = Flux.from(publisher)
|
||||
.map(value -> encodeData(value, elementType, encoder))
|
||||
.defaultIfEmpty(emptyDataBuffer)
|
||||
.switchIfEmpty(emptyBufferMono)
|
||||
.switchOnFirst((signal, inner) -> {
|
||||
DataBuffer data = signal.get();
|
||||
if (data != null) {
|
||||
@@ -250,12 +250,7 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
|
||||
@Override
|
||||
public Mono<Void> send() {
|
||||
return getPayloadMonoRequired().flatMap(rsocket::fireAndForget);
|
||||
}
|
||||
|
||||
private Mono<Payload> getPayloadMonoRequired() {
|
||||
Assert.state(this.payloadFlux == null, "No RSocket interaction model for Flux request to Mono response.");
|
||||
return this.payloadMono != null ? this.payloadMono : firstPayload(Mono.just(emptyDataBuffer));
|
||||
return getPayloadMono().flatMap(rsocket::fireAndForget);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -268,6 +263,19 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
return retrieveMono(ResolvableType.forType(dataTypeRef));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Mono<T> retrieveMono(ResolvableType elementType) {
|
||||
Mono<Payload> payloadMono = getPayloadMono().flatMap(rsocket::requestResponse);
|
||||
|
||||
if (isVoid(elementType)) {
|
||||
return (Mono<T>) payloadMono.then();
|
||||
}
|
||||
|
||||
Decoder<?> decoder = strategies.decoder(elementType, dataMimeType);
|
||||
return (Mono<T>) payloadMono.map(this::retainDataAndReleasePayload)
|
||||
.map(dataBuffer -> decoder.decode(dataBuffer, elementType, dataMimeType, EMPTY_HINTS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Flux<T> retrieveFlux(Class<T> dataType) {
|
||||
return retrieveFlux(ResolvableType.forClass(dataType));
|
||||
@@ -278,24 +286,12 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
return retrieveFlux(ResolvableType.forType(dataTypeRef));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Mono<T> retrieveMono(ResolvableType elementType) {
|
||||
Mono<Payload> payloadMono = getPayloadMonoRequired().flatMap(rsocket::requestResponse);
|
||||
|
||||
if (isVoid(elementType)) {
|
||||
return (Mono<T>) payloadMono.then();
|
||||
}
|
||||
|
||||
Decoder<?> decoder = strategies.decoder(elementType, dataMimeType);
|
||||
return (Mono<T>) payloadMono.map(this::retainDataAndReleasePayload)
|
||||
.map(dataBuffer -> decoder.decode(dataBuffer, elementType, dataMimeType, EMPTY_HINTS));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Flux<T> retrieveFlux(ResolvableType elementType) {
|
||||
Flux<Payload> payloadFlux = this.payloadMono != null ?
|
||||
this.payloadMono.flatMapMany(rsocket::requestStream) :
|
||||
rsocket.requestChannel(this.payloadFlux);
|
||||
|
||||
Flux<Payload> payloadFlux = (this.payloadFlux != null ?
|
||||
rsocket.requestChannel(this.payloadFlux) :
|
||||
getPayloadMono().flatMapMany(rsocket::requestStream));
|
||||
|
||||
if (isVoid(elementType)) {
|
||||
return payloadFlux.thenMany(Flux.empty());
|
||||
@@ -306,6 +302,11 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
(T) decoder.decode(dataBuffer, elementType, dataMimeType, EMPTY_HINTS));
|
||||
}
|
||||
|
||||
private Mono<Payload> getPayloadMono() {
|
||||
Assert.state(this.payloadFlux == null, "No RSocket interaction with Flux request and Mono response.");
|
||||
return this.payloadMono != null ? this.payloadMono : firstPayload(emptyBufferMono);
|
||||
}
|
||||
|
||||
private DataBuffer retainDataAndReleasePayload(Payload payload) {
|
||||
return PayloadUtils.retainDataAndReleasePayload(payload, bufferFactory());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user