Search in sources :

Example 26 with ReactiveAdapter

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;
}
Also used : ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 27 with ReactiveAdapter

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());
    }
}
Also used : Arrays(java.util.Arrays) RequestedContentTypeResolver(org.springframework.web.reactive.accept.RequestedContentTypeResolver) ServerHttpResponse(org.springframework.http.server.reactive.ServerHttpResponse) HttpMessageReader(org.springframework.http.codec.HttpMessageReader) WebHandler(org.springframework.web.server.WebHandler) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) ServerWebExchange(org.springframework.web.server.ServerWebExchange) UnsupportedMediaTypeStatusException(org.springframework.web.server.UnsupportedMediaTypeStatusException) Map(java.util.Map) Message(org.springframework.messaging.Message) HeaderContentTypeResolver(org.springframework.web.reactive.accept.HeaderContentTypeResolver) ResolvableType(org.springframework.core.ResolvableType) AbstractIntegrationMessageBuilder(org.springframework.integration.support.AbstractIntegrationMessageBuilder) LinkedHashSet(java.util.LinkedHashSet) ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) HandlerMapping(org.springframework.web.reactive.HandlerMapping) ServerHttpRequest(org.springframework.http.server.reactive.ServerHttpRequest) ReactiveAdapter(org.springframework.core.ReactiveAdapter) HttpHeaders(org.springframework.http.HttpHeaders) Publisher(org.reactivestreams.Publisher) MediaType(org.springframework.http.MediaType) HttpMethod(org.springframework.http.HttpMethod) Set(java.util.Set) BaseHttpInboundEndpoint(org.springframework.integration.http.inbound.BaseHttpInboundEndpoint) MultiValueMap(org.springframework.util.MultiValueMap) NotAcceptableStatusException(org.springframework.web.server.NotAcceptableStatusException) Mono(reactor.core.publisher.Mono) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) ServerCodecConfigurer(org.springframework.http.codec.ServerCodecConfigurer) MessagingGatewaySupport(org.springframework.integration.gateway.MessagingGatewaySupport) HttpStatus(org.springframework.http.HttpStatus) Flux(reactor.core.publisher.Flux) List(java.util.List) HttpEntity(org.springframework.http.HttpEntity) CollectionUtils(org.springframework.util.CollectionUtils) Expression(org.springframework.expression.Expression) ResponseEntity(org.springframework.http.ResponseEntity) Comparator(java.util.Comparator) Collections(java.util.Collections) StandardEvaluationContext(org.springframework.expression.spel.support.StandardEvaluationContext) HttpMessageWriter(org.springframework.http.codec.HttpMessageWriter) Assert(org.springframework.util.Assert) ServerHttpRequest(org.springframework.http.server.reactive.ServerHttpRequest) Mono(reactor.core.publisher.Mono) Flux(reactor.core.publisher.Flux) ServerHttpResponse(org.springframework.http.server.reactive.ServerHttpResponse) HttpMessageReader(org.springframework.http.codec.HttpMessageReader) UnsupportedMediaTypeStatusException(org.springframework.web.server.UnsupportedMediaTypeStatusException) MediaType(org.springframework.http.MediaType) ResolvableType(org.springframework.core.ResolvableType) Map(java.util.Map) MultiValueMap(org.springframework.util.MultiValueMap) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 28 with ReactiveAdapter

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();
}
Also used : ReactiveAdapter(org.springframework.core.ReactiveAdapter) Collection(java.util.Collection) MediaType(org.springframework.http.MediaType) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Mono(reactor.core.publisher.Mono) BindingResult(org.springframework.validation.BindingResult) BindingContext(org.springframework.web.reactive.BindingContext) ApplicationContext(org.springframework.context.ApplicationContext) StandardCharsets(java.nio.charset.StandardCharsets) ArrayList(java.util.ArrayList) ServerWebExchange(org.springframework.web.server.ServerWebExchange) Flux(reactor.core.publisher.Flux) List(java.util.List) Charset(java.nio.charset.Charset) Map(java.util.Map) Log(org.apache.commons.logging.Log) Nullable(org.springframework.lang.Nullable) LogFactory(org.apache.commons.logging.LogFactory) BeanNameAware(org.springframework.beans.factory.BeanNameAware) Collections(java.util.Collections) ApplicationContextAware(org.springframework.context.ApplicationContextAware) ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) BeanUtils(org.springframework.beans.BeanUtils) Assert(org.springframework.util.Assert) Mono(reactor.core.publisher.Mono) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 29 with ReactiveAdapter

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));
}
Also used : Decoder(org.springframework.core.codec.Decoder) Validator(org.springframework.validation.Validator) MethodArgumentNotValidException(org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException) Conventions(org.springframework.core.Conventions) DecodingException(org.springframework.core.codec.DecodingException) ArrayList(java.util.ArrayList) MimeType(org.springframework.util.MimeType) HandlerMethodArgumentResolver(org.springframework.messaging.handler.invocation.reactive.HandlerMethodArgumentResolver) Map(java.util.Map) MethodParameter(org.springframework.core.MethodParameter) DataBufferUtils(org.springframework.core.io.buffer.DataBufferUtils) Nullable(org.springframework.lang.Nullable) Message(org.springframework.messaging.Message) ResolvableType(org.springframework.core.ResolvableType) BeanPropertyBindingResult(org.springframework.validation.BeanPropertyBindingResult) ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) ReactiveAdapter(org.springframework.core.ReactiveAdapter) Validated(org.springframework.validation.annotation.Validated) Publisher(org.reactivestreams.Publisher) AnnotationUtils(org.springframework.core.annotation.AnnotationUtils) ObjectUtils(org.springframework.util.ObjectUtils) Mono(reactor.core.publisher.Mono) MimeTypeUtils(org.springframework.util.MimeTypeUtils) DataBuffer(org.springframework.core.io.buffer.DataBuffer) MessageHeaders(org.springframework.messaging.MessageHeaders) MethodArgumentResolutionException(org.springframework.messaging.handler.invocation.MethodArgumentResolutionException) Consumer(java.util.function.Consumer) Flux(reactor.core.publisher.Flux) List(java.util.List) CollectionUtils(org.springframework.util.CollectionUtils) SmartValidator(org.springframework.validation.SmartValidator) Annotation(java.lang.annotation.Annotation) Payload(org.springframework.messaging.handler.annotation.Payload) Log(org.apache.commons.logging.Log) LogFactory(org.apache.commons.logging.LogFactory) Collections(java.util.Collections) Assert(org.springframework.util.Assert) StringUtils(org.springframework.util.StringUtils) MethodArgumentResolutionException(org.springframework.messaging.handler.invocation.MethodArgumentResolutionException) ResolvableType(org.springframework.core.ResolvableType) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 30 with ReactiveAdapter

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);
}
Also used : ClientTransport(io.rsocket.transport.ClientTransport) NettyDataBufferFactory(org.springframework.core.io.buffer.NettyDataBufferFactory) Decoder(org.springframework.core.codec.Decoder) LoadbalanceTarget(io.rsocket.loadbalance.LoadbalanceTarget) PayloadDecoder(io.rsocket.frame.decoder.PayloadDecoder) WebsocketClientTransport(io.rsocket.transport.netty.client.WebsocketClientTransport) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) MimeType(org.springframework.util.MimeType) WellKnownMimeType(io.rsocket.metadata.WellKnownMimeType) Map(java.util.Map) DefaultPayload(io.rsocket.util.DefaultPayload) DataBufferUtils(org.springframework.core.io.buffer.DataBufferUtils) Nullable(org.springframework.lang.Nullable) URI(java.net.URI) ResolvableType(org.springframework.core.ResolvableType) Encoder(org.springframework.core.codec.Encoder) ReactiveAdapter(org.springframework.core.ReactiveAdapter) RSocketConnector(io.rsocket.core.RSocketConnector) StringDecoder(org.springframework.core.codec.StringDecoder) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) MimeTypeUtils(org.springframework.util.MimeTypeUtils) DataBuffer(org.springframework.core.io.buffer.DataBuffer) Consumer(java.util.function.Consumer) TcpClientTransport(io.rsocket.transport.netty.client.TcpClientTransport) List(java.util.List) LoadbalanceStrategy(io.rsocket.loadbalance.LoadbalanceStrategy) Payload(io.rsocket.Payload) LoadbalanceRSocketClient(io.rsocket.loadbalance.LoadbalanceRSocketClient) CollectionUtils(org.springframework.util.CollectionUtils) RSocketClient(io.rsocket.core.RSocketClient) Collections(java.util.Collections) Assert(org.springframework.util.Assert) Encoder(org.springframework.core.codec.Encoder) DefaultPayload(io.rsocket.util.DefaultPayload) Payload(io.rsocket.Payload) ResolvableType(org.springframework.core.ResolvableType) ReactiveAdapter(org.springframework.core.ReactiveAdapter) DataBuffer(org.springframework.core.io.buffer.DataBuffer)

Aggregations

ReactiveAdapter (org.springframework.core.ReactiveAdapter)41 ResolvableType (org.springframework.core.ResolvableType)16 Mono (reactor.core.publisher.Mono)14 ReactiveAdapterRegistry (org.springframework.core.ReactiveAdapterRegistry)13 List (java.util.List)12 Assert (org.springframework.util.Assert)12 MethodParameter (org.springframework.core.MethodParameter)11 Nullable (org.springframework.lang.Nullable)11 MediaType (org.springframework.http.MediaType)10 Map (java.util.Map)8 Publisher (org.reactivestreams.Publisher)8 Flux (reactor.core.publisher.Flux)8 DataBuffer (org.springframework.core.io.buffer.DataBuffer)7 ArrayList (java.util.ArrayList)6 Collections (java.util.Collections)6 BindingContext (org.springframework.web.reactive.BindingContext)6 ServerWebExchange (org.springframework.web.server.ServerWebExchange)6 Collectors (java.util.stream.Collectors)5 HttpEntity (org.springframework.http.HttpEntity)5 HttpMessageWriter (org.springframework.http.codec.HttpMessageWriter)5