Search in sources :

Example 6 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class RoutingInBoundHandler method mapToHttpContent.

private Flux<HttpContent> mapToHttpContent(NettyHttpRequest<?> request, MutableHttpResponse<?> response, Object body, ChannelHandlerContext context) {
    final RouteInfo<?> routeInfo = response.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).orElse(null);
    final boolean hasRouteInfo = routeInfo != null;
    MediaType mediaType = response.getContentType().orElse(null);
    if (mediaType == null && hasRouteInfo) {
        mediaType = routeExecutor.resolveDefaultResponseContentType(request, routeInfo);
    }
    boolean isJson = mediaType != null && mediaType.getExtension().equals(MediaType.EXTENSION_JSON) && isJsonFormattable(hasRouteInfo ? routeInfo.getBodyType() : null);
    NettyByteBufferFactory byteBufferFactory = new NettyByteBufferFactory(context.alloc());
    Flux<Object> bodyPublisher = Flux.from(Publishers.convertPublisher(body, Publisher.class));
    MediaType finalMediaType = mediaType;
    Flux<HttpContent> httpContentPublisher = bodyPublisher.map(message -> {
        HttpContent httpContent;
        if (message instanceof ByteBuf) {
            httpContent = new DefaultHttpContent((ByteBuf) message);
        } else if (message instanceof ByteBuffer) {
            ByteBuffer<?> byteBuffer = (ByteBuffer<?>) message;
            Object nativeBuffer = byteBuffer.asNativeBuffer();
            if (nativeBuffer instanceof ByteBuf) {
                httpContent = new DefaultHttpContent((ByteBuf) nativeBuffer);
            } else {
                httpContent = new DefaultHttpContent(Unpooled.copiedBuffer(byteBuffer.asNioBuffer()));
            }
        } else if (message instanceof byte[]) {
            httpContent = new DefaultHttpContent(Unpooled.copiedBuffer((byte[]) message));
        } else if (message instanceof HttpContent) {
            httpContent = (HttpContent) message;
        } else {
            MediaTypeCodec codec = mediaTypeCodecRegistry.findCodec(finalMediaType, message.getClass()).orElse(new TextPlainCodec(serverConfiguration.getDefaultCharset()));
            if (LOG.isTraceEnabled()) {
                LOG.trace("Encoding emitted response object [{}] using codec: {}", message, codec);
            }
            ByteBuffer<ByteBuf> encoded;
            if (hasRouteInfo) {
                // noinspection unchecked
                final Argument<Object> bodyType = (Argument<Object>) routeInfo.getBodyType();
                if (bodyType.isInstance(message)) {
                    encoded = codec.encode(bodyType, message, byteBufferFactory);
                } else {
                    encoded = codec.encode(message, byteBufferFactory);
                }
            } else {
                encoded = codec.encode(message, byteBufferFactory);
            }
            httpContent = new DefaultHttpContent(encoded.asNativeBuffer());
        }
        return httpContent;
    });
    if (isJson) {
        // if the Publisher is returning JSON then in order for it to be valid JSON for each emitted element
        // we must wrap the JSON in array and delimit the emitted items
        httpContentPublisher = JsonSubscriber.lift(httpContentPublisher);
    }
    httpContentPublisher = httpContentPublisher.contextWrite(reactorContext -> reactorContext.put(ServerRequestContext.KEY, request)).doOnNext(httpContent -> context.read()).doAfterTerminate(() -> cleanupRequest(context, request));
    return httpContentPublisher;
}
Also used : Publishers(io.micronaut.core.async.publisher.Publishers) HttpRequestTerminatedEvent(io.micronaut.http.context.event.HttpRequestTerminatedEvent) HttpHeaders(io.micronaut.http.HttpHeaders) Internal(io.micronaut.core.annotation.Internal) NettyStreamedFileCustomizableResponseType(io.micronaut.http.server.netty.types.files.NettyStreamedFileCustomizableResponseType) ByteBufHolder(io.netty.buffer.ByteBufHolder) HttpStatus(io.micronaut.http.HttpStatus) IdleState(io.netty.handler.timeout.IdleState) NettySystemFileCustomizableResponseType(io.micronaut.http.server.netty.types.files.NettySystemFileCustomizableResponseType) NettyPartData(io.micronaut.http.server.netty.multipart.NettyPartData) TextPlainCodec(io.micronaut.runtime.http.codec.TextPlainCodec) IdleStateEvent(io.netty.handler.timeout.IdleStateEvent) Set(java.util.Set) RequestArgumentSatisfier(io.micronaut.http.server.binding.RequestArgumentSatisfier) SSLException(javax.net.ssl.SSLException) RouteInfo(io.micronaut.web.router.RouteInfo) Writable(io.micronaut.core.io.Writable) Body(io.micronaut.http.annotation.Body) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) Http2Error(io.netty.handler.codec.http2.Http2Error) InternalServerException(io.micronaut.http.server.exceptions.InternalServerException) RouteMatch(io.micronaut.web.router.RouteMatch) NettyByteBufferFactory(io.micronaut.buffer.netty.NettyByteBufferFactory) NettyMutableHttpResponse(io.micronaut.http.netty.NettyMutableHttpResponse) MonoSink(reactor.core.publisher.MonoSink) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) UriRouteMatch(io.micronaut.web.router.UriRouteMatch) HttpData(io.netty.handler.codec.http.multipart.HttpData) Nullable(io.micronaut.core.annotation.Nullable) DuplicateRouteException(io.micronaut.web.router.exceptions.DuplicateRouteException) BiConsumer(java.util.function.BiConsumer) ByteBuffer(io.micronaut.core.io.buffer.ByteBuffer) Argument(io.micronaut.core.type.Argument) HttpRequest(io.micronaut.http.HttpRequest) ConversionService(io.micronaut.core.convert.ConversionService) ServerRequestContext(io.micronaut.http.context.ServerRequestContext) ErrorResponseProcessor(io.micronaut.http.server.exceptions.response.ErrorResponseProcessor) MediaTypeCodecRegistry(io.micronaut.http.codec.MediaTypeCodecRegistry) HttpContent(io.netty.handler.codec.http.HttpContent) FileUpload(io.netty.handler.codec.http.multipart.FileUpload) ClosedChannelException(java.nio.channels.ClosedChannelException) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) IOException(java.io.IOException) NettyHttpResponseBuilder(io.micronaut.http.netty.NettyHttpResponseBuilder) File(java.io.File) AbstractNettyHttpRequest(io.micronaut.http.netty.AbstractNettyHttpRequest) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) Flux(reactor.core.publisher.Flux) AtomicLong(java.util.concurrent.atomic.AtomicLong) Paths(java.nio.file.Paths) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) Future(io.netty.util.concurrent.Future) RouteExecutor(io.micronaut.http.server.RouteExecutor) Sinks(reactor.core.publisher.Sinks) StreamingFileUpload(io.micronaut.http.multipart.StreamingFileUpload) URL(java.net.URL) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) NettyHttpServerConfiguration(io.micronaut.http.server.netty.configuration.NettyHttpServerConfiguration) FileCustomizableResponseType(io.micronaut.http.server.types.files.FileCustomizableResponseType) Unpooled(io.netty.buffer.Unpooled) CompletionAwareSubscriber(io.micronaut.core.async.subscriber.CompletionAwareSubscriber) PartData(io.micronaut.http.multipart.PartData) NettyCustomizableResponseTypeHandler(io.micronaut.http.server.netty.types.NettyCustomizableResponseTypeHandler) StaticResourceResolver(io.micronaut.web.router.resource.StaticResourceResolver) MediaType(io.micronaut.http.MediaType) Http2Exception(io.netty.handler.codec.http2.Http2Exception) ReferenceCounted(io.micronaut.core.io.buffer.ReferenceCounted) HttpResponse(io.micronaut.http.HttpResponse) ClassUtils(io.micronaut.core.reflect.ClassUtils) Collection(java.util.Collection) MethodBasedRouteMatch(io.micronaut.web.router.MethodBasedRouteMatch) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) NettyCustomizableResponseTypeHandlerRegistry(io.micronaut.http.server.netty.types.NettyCustomizableResponseTypeHandlerRegistry) TooLongFrameException(io.netty.handler.codec.TooLongFrameException) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) Collectors(java.util.stream.Collectors) ByteBufOutputStream(io.netty.buffer.ByteBufOutputStream) Attribute(io.netty.handler.codec.http.multipart.Attribute) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) DecoderResult(io.netty.handler.codec.DecoderResult) List(java.util.List) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) Optional(java.util.Optional) HttpAttributes(io.micronaut.http.HttpAttributes) Pattern(java.util.regex.Pattern) HttpVersion(io.netty.handler.codec.http.HttpVersion) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) Sharable(io.netty.channel.ChannelHandler.Sharable) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HashSet(java.util.HashSet) ErrorContext(io.micronaut.http.server.exceptions.response.ErrorContext) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) Subscriber(org.reactivestreams.Subscriber) ExecutorService(java.util.concurrent.ExecutorService) HttpMethod(io.micronaut.http.HttpMethod) MediaTypeCodec(io.micronaut.http.codec.MediaTypeCodec) Logger(org.slf4j.Logger) HttpHeaderValues(io.netty.handler.codec.http.HttpHeaderValues) ApplicationEventPublisher(io.micronaut.context.event.ApplicationEventPublisher) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) NettyStreamingFileUpload(io.micronaut.http.server.netty.multipart.NettyStreamingFileUpload) LongConsumer(java.util.function.LongConsumer) NonNull(io.micronaut.core.annotation.NonNull) CollectionUtils(io.micronaut.core.util.CollectionUtils) Subscription(org.reactivestreams.Subscription) Router(io.micronaut.web.router.Router) Collections(java.util.Collections) JsonSubscriber(io.micronaut.http.netty.stream.JsonSubscriber) NettyByteBufferFactory(io.micronaut.buffer.netty.NettyByteBufferFactory) Argument(io.micronaut.core.type.Argument) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) Publisher(org.reactivestreams.Publisher) ApplicationEventPublisher(io.micronaut.context.event.ApplicationEventPublisher) ByteBuf(io.netty.buffer.ByteBuf) ByteBuffer(io.micronaut.core.io.buffer.ByteBuffer) TextPlainCodec(io.micronaut.runtime.http.codec.TextPlainCodec) MediaType(io.micronaut.http.MediaType) RouteInfo(io.micronaut.web.router.RouteInfo) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) MediaTypeCodec(io.micronaut.http.codec.MediaTypeCodec)

Example 7 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class RoutingInBoundHandler method encodeResponseBody.

private void encodeResponseBody(ChannelHandlerContext context, HttpRequest<?> request, MutableHttpResponse<?> message, @Nullable Argument<Object> bodyType, Object body) {
    if (body == null) {
        return;
    }
    Optional<NettyCustomizableResponseTypeHandler> typeHandler = customizableResponseTypeHandlerRegistry.findTypeHandler(body.getClass());
    if (typeHandler.isPresent()) {
        NettyCustomizableResponseTypeHandler th = typeHandler.get();
        setBodyContent(message, new NettyCustomizableResponseTypeHandlerInvoker(th, body));
    } else {
        MediaType mediaType = message.getContentType().orElse(null);
        if (mediaType == null) {
            mediaType = message.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).map(routeInfo -> routeExecutor.resolveDefaultResponseContentType(request, routeInfo)).orElse(MediaType.APPLICATION_JSON_TYPE);
            message.contentType(mediaType);
        }
        if (body instanceof CharSequence) {
            ByteBuf byteBuf = Unpooled.wrappedBuffer(body.toString().getBytes(message.getCharacterEncoding()));
            setResponseBody(message, byteBuf);
        } else if (body instanceof byte[]) {
            ByteBuf byteBuf = Unpooled.wrappedBuffer((byte[]) body);
            setResponseBody(message, byteBuf);
        } else if (body instanceof ByteBuffer) {
            ByteBuffer<?> byteBuffer = (ByteBuffer) body;
            Object nativeBuffer = byteBuffer.asNativeBuffer();
            if (nativeBuffer instanceof ByteBuf) {
                setResponseBody(message, (ByteBuf) nativeBuffer);
            } else if (nativeBuffer instanceof java.nio.ByteBuffer) {
                ByteBuf byteBuf = Unpooled.wrappedBuffer((java.nio.ByteBuffer) nativeBuffer);
                setResponseBody(message, byteBuf);
            }
        } else if (body instanceof ByteBuf) {
            setResponseBody(message, (ByteBuf) body);
        } else {
            Optional<MediaTypeCodec> registeredCodec = mediaTypeCodecRegistry.findCodec(mediaType, body.getClass());
            if (registeredCodec.isPresent()) {
                MediaTypeCodec codec = registeredCodec.get();
                encodeBodyWithCodec(message, bodyType, body, codec, context, request);
            } else {
                MediaTypeCodec defaultCodec = new TextPlainCodec(serverConfiguration.getDefaultCharset());
                encodeBodyWithCodec(message, bodyType, body, defaultCodec, context, request);
            }
        }
    }
}
Also used : Optional(java.util.Optional) NettyCustomizableResponseTypeHandler(io.micronaut.http.server.netty.types.NettyCustomizableResponseTypeHandler) ByteBuf(io.netty.buffer.ByteBuf) ByteBuffer(io.micronaut.core.io.buffer.ByteBuffer) TextPlainCodec(io.micronaut.runtime.http.codec.TextPlainCodec) MediaType(io.micronaut.http.MediaType) RouteInfo(io.micronaut.web.router.RouteInfo) MediaTypeCodec(io.micronaut.http.codec.MediaTypeCodec)

Aggregations

RouteInfo (io.micronaut.web.router.RouteInfo)7 MutableHttpResponse (io.micronaut.http.MutableHttpResponse)5 Argument (io.micronaut.core.type.Argument)4 HttpStatus (io.micronaut.http.HttpStatus)4 MediaType (io.micronaut.http.MediaType)4 Internal (io.micronaut.core.annotation.Internal)3 NonNull (io.micronaut.core.annotation.NonNull)3 Nullable (io.micronaut.core.annotation.Nullable)3 Publishers (io.micronaut.core.async.publisher.Publishers)3 ReferenceCounted (io.micronaut.core.io.buffer.ReferenceCounted)3 HttpAttributes (io.micronaut.http.HttpAttributes)3 HttpHeaders (io.micronaut.http.HttpHeaders)3 HttpMethod (io.micronaut.http.HttpMethod)3 HttpRequest (io.micronaut.http.HttpRequest)3 HttpResponse (io.micronaut.http.HttpResponse)3 MutableHttpHeaders (io.micronaut.http.MutableHttpHeaders)3 MediaTypeCodec (io.micronaut.http.codec.MediaTypeCodec)3 ServerRequestContext (io.micronaut.http.context.ServerRequestContext)3 RequestArgumentSatisfier (io.micronaut.http.server.binding.RequestArgumentSatisfier)3 ErrorContext (io.micronaut.http.server.exceptions.response.ErrorContext)3