use of org.springframework.core.ReactiveAdapter in project spring-data-commons by spring-projects.
the class ReactiveWrapperConverters method getRequiredAdapter.
/**
* Returns the {@link ReactiveAdapter} for the given type.
*
* @param type must not be {@literal null}.
* @return
* @throws IllegalStateException if no adapter registry could be found.
* @throws IllegalArgumentException if no adapter could be found for the given type.
*/
private static ReactiveAdapter getRequiredAdapter(Class<?> type) {
ReactiveAdapterRegistry registry = REACTIVE_ADAPTER_REGISTRY;
if (registry == null) {
throw new IllegalStateException("No reactive adapter registry found!");
}
ReactiveAdapter adapter = registry.getAdapter(type);
if (adapter == null) {
throw new IllegalArgumentException(String.format("Expected to find reactive adapter for %s but couldn't!", type));
}
return adapter;
}
use of org.springframework.core.ReactiveAdapter in project spring-integration by spring-projects.
the class WebFluxInboundEndpoint method extractRequestBody.
@SuppressWarnings("unchecked")
private <T> Mono<T> extractRequestBody(ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
if (isReadable(request)) {
MediaType contentType;
if (request.getHeaders().getContentType() == null) {
contentType = MediaType.APPLICATION_OCTET_STREAM;
} else {
contentType = request.getHeaders().getContentType();
}
if (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(contentType)) {
return (Mono<T>) exchange.getFormData();
} else if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
return (Mono<T>) exchange.getMultipartData();
} else {
ResolvableType bodyType = getRequestPayloadType();
if (bodyType == null) {
bodyType = "text".equals(contentType.getType()) ? ResolvableType.forClass(String.class) : ResolvableType.forClass(byte[].class);
}
Class<?> resolvedType = bodyType.resolve();
ReactiveAdapter adapter = (resolvedType != null ? this.adapterRegistry.getAdapter(resolvedType) : null);
ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType);
HttpMessageReader<?> httpMessageReader = this.codecConfigurer.getReaders().stream().filter(reader -> reader.canRead(elementType, contentType)).findFirst().orElseThrow(() -> new UnsupportedMediaTypeStatusException("Could not convert request: no suitable HttpMessageReader found for expected type [" + elementType + "] and content type [" + contentType + "]"));
Map<String, Object> readHints = Collections.emptyMap();
if (adapter != null && adapter.isMultiValue()) {
Flux<?> flux = httpMessageReader.read(bodyType, elementType, request, response, readHints);
return (Mono<T>) Mono.just(adapter.fromPublisher(flux));
} else {
Mono<?> mono = httpMessageReader.readMono(bodyType, elementType, request, response, readHints);
if (adapter != null) {
return (Mono<T>) Mono.just(adapter.fromPublisher(mono));
} else {
return (Mono<T>) mono;
}
}
}
} else {
return (Mono<T>) Mono.just(exchange.getRequest().getQueryParams());
}
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class AbstractView method resolveAsyncAttributes.
/**
* Use the configured {@link ReactiveAdapterRegistry} to adapt asynchronous
* attributes to {@code Mono<T>} or {@code Mono<List<T>>} and then wait to
* resolve them into actual values. When the returned {@code Mono<Void>}
* completes, the asynchronous attributes in the model will have been
* replaced with their corresponding resolved values.
* @return result a {@code Mono} that completes when the model is ready
* @since 5.1.8
*/
protected Mono<Void> resolveAsyncAttributes(Map<String, Object> model, ServerWebExchange exchange) {
List<Mono<?>> asyncAttributes = null;
for (Map.Entry<String, ?> entry : model.entrySet()) {
Object value = entry.getValue();
if (value == null) {
continue;
}
ReactiveAdapter adapter = this.adapterRegistry.getAdapter(null, value);
if (adapter != null) {
if (asyncAttributes == null) {
asyncAttributes = new ArrayList<>();
}
String name = entry.getKey();
if (adapter.isMultiValue()) {
asyncAttributes.add(Flux.from(adapter.toPublisher(value)).collectList().doOnSuccess(result -> model.put(name, result)));
} else {
asyncAttributes.add(Mono.from(adapter.toPublisher(value)).doOnSuccess(result -> {
if (result != null) {
model.put(name, result);
addBindingResult(name, result, model, exchange);
} else {
model.remove(name);
}
}));
}
}
}
return asyncAttributes != null ? Mono.when(asyncAttributes) : Mono.empty();
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class PayloadMethodArgumentResolver method decodeContent.
private Mono<Object> decodeContent(MethodParameter parameter, Message<?> message, boolean isContentRequired, Flux<DataBuffer> content, MimeType mimeType) {
ResolvableType targetType = ResolvableType.forMethodParameter(parameter);
Class<?> resolvedType = targetType.resolve();
ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
ResolvableType elementType = (adapter != null ? targetType.getGeneric() : targetType);
isContentRequired = isContentRequired || (adapter != null && !adapter.supportsEmpty());
Consumer<Object> validator = getValidator(message, parameter);
Map<String, Object> hints = Collections.emptyMap();
for (Decoder<?> decoder : this.decoders) {
if (decoder.canDecode(elementType, mimeType)) {
if (adapter != null && adapter.isMultiValue()) {
Flux<?> flux = content.filter(this::nonEmptyDataBuffer).map(buffer -> decoder.decode(buffer, elementType, mimeType, hints)).onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
if (isContentRequired) {
flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(parameter, message)));
}
if (validator != null) {
flux = flux.doOnNext(validator);
}
return Mono.just(adapter.fromPublisher(flux));
} else {
// Single-value (with or without reactive type wrapper)
Mono<?> mono = content.next().filter(this::nonEmptyDataBuffer).map(buffer -> decoder.decode(buffer, elementType, mimeType, hints)).onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex)));
if (isContentRequired) {
mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(parameter, message)));
}
if (validator != null) {
mono = mono.doOnNext(validator);
}
return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
}
}
}
return Mono.error(new MethodArgumentResolutionException(message, parameter, "Cannot decode to [" + targetType + "]" + message));
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class DefaultRSocketRequesterBuilder method getSetupPayload.
private Mono<Payload> getSetupPayload(MimeType dataMimeType, MimeType metaMimeType, RSocketStrategies strategies) {
Object data = this.setupData;
boolean hasMetadata = (this.setupRoute != null || !CollectionUtils.isEmpty(this.setupMetadata));
if (!hasMetadata && data == null) {
return Mono.just(EMPTY_SETUP_PAYLOAD);
}
Mono<DataBuffer> dataMono = Mono.empty();
if (data != null) {
ReactiveAdapter adapter = strategies.reactiveAdapterRegistry().getAdapter(data.getClass());
Assert.isTrue(adapter == null || !adapter.isMultiValue(), "Expected single value: " + data);
Mono<?> mono = (adapter != null ? Mono.from(adapter.toPublisher(data)) : Mono.just(data));
dataMono = mono.map(value -> {
ResolvableType type = ResolvableType.forClass(value.getClass());
Encoder<Object> encoder = strategies.encoder(type, dataMimeType);
Assert.notNull(encoder, () -> "No encoder for " + dataMimeType + ", " + type);
return encoder.encodeValue(value, strategies.dataBufferFactory(), type, dataMimeType, HINTS);
});
}
Mono<DataBuffer> metaMono = Mono.empty();
if (hasMetadata) {
metaMono = new MetadataEncoder(metaMimeType, strategies).metadataAndOrRoute(this.setupMetadata, this.setupRoute, this.setupRouteVars).encode();
}
Mono<DataBuffer> emptyBuffer = Mono.fromCallable(() -> strategies.dataBufferFactory().wrap(EMPTY_BYTE_ARRAY));
dataMono = dataMono.switchIfEmpty(emptyBuffer);
metaMono = metaMono.switchIfEmpty(emptyBuffer);
return Mono.zip(dataMono, metaMono).map(tuple -> PayloadUtils.createPayload(tuple.getT1(), tuple.getT2())).doOnDiscard(DataBuffer.class, DataBufferUtils::release).doOnDiscard(Payload.class, Payload::release);
}
Aggregations