All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.fortnox.reactivewizard.jaxrs.JaxRsRequestHandler Maven / Gradle / Ivy

There is a newer version: 24.6.0
Show newest version
package se.fortnox.reactivewizard.jaxrs;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import reactor.netty.http.server.HttpServerRequest;
import reactor.netty.http.server.HttpServerResponse;
import se.fortnox.reactivewizard.ExceptionHandler;
import se.fortnox.reactivewizard.RequestHandler;
import se.fortnox.reactivewizard.jaxrs.response.JaxRsResult;
import se.fortnox.reactivewizard.util.DebugUtil;

/**
 * Handles incoming requests. If the request matches a resource a Flux or Mono which completes the request is returned.
 */
@Singleton
public class JaxRsRequestHandler implements RequestHandler {
    private final JaxRsResources   resources;
    private final ExceptionHandler exceptionHandler;
    private final ByteBufCollector          collector;

    @Inject
    public JaxRsRequestHandler(JaxRsResourcesProvider services,
                               JaxRsResourceFactory jaxRsResourceFactory,
                               ExceptionHandler exceptionHandler,
                               ByteBufCollector collector
    ) {
        this(services.getResources(),
            jaxRsResourceFactory,
            exceptionHandler,
            collector,
            null);
    }

    public JaxRsRequestHandler(Object[] services,
        JaxRsResourceFactory jaxRsResourceFactory,
        ExceptionHandler exceptionHandler,
        Boolean classReloading
    ) {
        this(services, jaxRsResourceFactory, exceptionHandler, new ByteBufCollector(), classReloading);
    }

    public JaxRsRequestHandler(Object[] services,
        JaxRsResourceFactory jaxRsResourceFactory,
        ExceptionHandler exceptionHandler,
        ByteBufCollector collector,
        Boolean classReloading
    ) {
        this.collector = collector;
        this.exceptionHandler = exceptionHandler;
        if (classReloading == null) {
            classReloading = DebugUtil.IS_DEBUG;
        }
        this.resources = new JaxRsResources(services, jaxRsResourceFactory, classReloading);
    }

    /**
     * Handles incoming request if a matching resource is found.
     *
     * @param request The incoming request
     * @param response The response that will be sent
     * @return a Flux/Mono which will complete the request when the Flux/Mono completes or errors, or null if no resource matches the request.
     */
    @Override
    public Publisher apply(HttpServerRequest request, HttpServerResponse response) {
        JaxRsRequest     jaxRsRequest = new JaxRsRequest(request, collector);
        JaxRsResource resource     = resources.findResource(jaxRsRequest);

        if (resource == null) {
            return null;
        }

        preHandle(request, resource);

        long requestStartTime = System.currentTimeMillis();

        Publisher resourceCall;

        resourceCall = resource.call(jaxRsRequest)
            .flatMap(result -> Mono.from(writeResult(response, result)))
            .onErrorResume(e -> Mono.from(exceptionHandler.handleException(request, response, e)))
            .doAfterTerminate(() -> resource.log(request, response, requestStartTime));
        return resourceCall;

    }

    /**
     * Pre handling hook for classes extending this class.
     *
     * @param request the current request
     * @param resource the resource that will we handling the request
     */
    protected void preHandle(HttpServerRequest request, JaxRsResource resource) {
    }

    private Publisher writeResult(HttpServerResponse response, JaxRsResult result) {
        if (result != null) {
            return result.write(response);
        }
        return Mono.empty();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy