Search in sources :

Example 1 with Handler

use of io.gravitee.gateway.api.handler.Handler in project gravitee-gateway by gravitee-io.

the class ApiReactorHandler method doHandle.

@Override
protected void doHandle(Request serverRequest, Response serverResponse, Handler<Response> handler) {
    // Prepare request execution context
    ExecutionContext executionContext = executionContextFactory.create(serverRequest);
    executionContext.setAttribute(ExecutionContext.ATTR_CONTEXT_PATH, serverRequest.contextPath());
    try {
        // Set execution context attributes and metrics specific to this handler
        serverRequest.metrics().setApi(api.getId());
        executionContext.setAttribute(ExecutionContext.ATTR_API, api.getId());
        executionContext.setAttribute(ExecutionContext.ATTR_INVOKER, invoker);
        // Enable logging at client level
        if (api.getProxy().getLoggingMode().isClientMode()) {
            serverRequest = new LoggableClientRequest(serverRequest);
            serverResponse = new LoggableClientResponse(serverRequest, serverResponse);
        }
        Cors cors = api.getProxy().getCors();
        if (cors != null && cors.isEnabled()) {
            Request finalServerRequest = serverRequest;
            Response finalServerResponse = serverResponse;
            new CorsHandler(cors).responseHandler(new Handler<Response>() {

                @Override
                public void handle(Response response) {
                    handleClientRequest(finalServerRequest, finalServerResponse, executionContext, new CorsResponseHandler(handler));
                }
            }).handle(serverRequest, serverResponse, handler);
        } else {
            handleClientRequest(serverRequest, serverResponse, executionContext, handler);
        }
    } catch (Exception ex) {
        logger.error("An unexpected error occurs while processing request", ex);
        serverRequest.metrics().setMessage(Throwables.getStackTraceAsString(ex));
        // Send an INTERNAL_SERVER_ERROR (500)
        serverResponse.status(HttpStatusCode.INTERNAL_SERVER_ERROR_500);
        serverResponse.headers().set(HttpHeaders.CONNECTION, HttpHeadersValues.CONNECTION_CLOSE);
        serverResponse.end();
        handler.handle(serverResponse);
    }
}
Also used : LoggableClientResponse(io.gravitee.gateway.handlers.api.logging.LoggableClientResponse) Response(io.gravitee.gateway.api.Response) ProxyResponse(io.gravitee.gateway.api.proxy.ProxyResponse) ExecutionContext(io.gravitee.gateway.api.ExecutionContext) LoggableClientRequest(io.gravitee.gateway.handlers.api.logging.LoggableClientRequest) LoggableClientRequest(io.gravitee.gateway.handlers.api.logging.LoggableClientRequest) Request(io.gravitee.gateway.api.Request) CorsHandler(io.gravitee.gateway.handlers.api.cors.CorsHandler) Handler(io.gravitee.gateway.api.handler.Handler) CorsResponseHandler(io.gravitee.gateway.handlers.api.cors.CorsResponseHandler) AbstractReactorHandler(io.gravitee.gateway.reactor.handler.AbstractReactorHandler) CorsHandler(io.gravitee.gateway.handlers.api.cors.CorsHandler) LoggableClientResponse(io.gravitee.gateway.handlers.api.logging.LoggableClientResponse) Cors(io.gravitee.definition.model.Cors) CorsResponseHandler(io.gravitee.gateway.handlers.api.cors.CorsResponseHandler) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 2 with Handler

use of io.gravitee.gateway.api.handler.Handler in project gravitee-gateway by gravitee-io.

the class FailoverInvoker method invoke.

@Override
public Request invoke(ExecutionContext executionContext, Request serverRequest, ReadStream<Buffer> stream, Handler<ProxyConnection> connectionHandler) {
    final Request failoverServerRequest = new FailoverRequest(serverRequest);
    circuitBreaker.execute(new io.vertx.core.Handler<Future<ProxyConnection>>() {

        @Override
        public void handle(Future<ProxyConnection> event) {
            invoker.invoke(executionContext, failoverServerRequest, stream, proxyConnection -> {
                proxyConnection.exceptionHandler(event::fail);
                proxyConnection.responseHandler(response -> event.complete(new FailoverProxyConnection(proxyConnection, response)));
            });
        }
    }).setHandler(new io.vertx.core.Handler<AsyncResult<ProxyConnection>>() {

        @Override
        public void handle(AsyncResult<ProxyConnection> event) {
            if (event.failed()) {
                FailoverConnection connection = new FailoverConnection();
                connectionHandler.handle(connection);
                connection.sendBadGatewayResponse();
            } else {
                FailoverProxyConnection proxyConnection = (FailoverProxyConnection) event.result();
                connectionHandler.handle(proxyConnection);
                proxyConnection.sendResponse();
            }
        }
    });
    return failoverServerRequest;
}
Also used : Request(io.gravitee.gateway.api.Request) Handler(io.gravitee.gateway.api.handler.Handler) ProxyConnection(io.gravitee.gateway.api.proxy.ProxyConnection) Future(io.vertx.core.Future) AsyncResult(io.vertx.core.AsyncResult)

Example 3 with Handler

use of io.gravitee.gateway.api.handler.Handler in project gravitee-gateway by gravitee-io.

the class DefaultInvoker method invoke.

@Override
public Request invoke(ExecutionContext executionContext, Request serverRequest, ReadStream<Buffer> stream, Handler<ProxyConnection> connectionHandler) {
    TargetEndpoint targetEndpoint = selectEndpoint(serverRequest, executionContext);
    if (!targetEndpoint.isReachable()) {
        DirectProxyConnection statusOnlyConnection = new DirectProxyConnection(HttpStatusCode.SERVICE_UNAVAILABLE_503);
        connectionHandler.handle(statusOnlyConnection);
        statusOnlyConnection.sendResponse();
    } else {
        // Remove duplicate slash
        String uri = DUPLICATE_SLASH_REMOVER.matcher(targetEndpoint.uri).replaceAll(URI_PATH_SEPARATOR);
        URI requestUri = null;
        try {
            requestUri = encodeQueryParameters(serverRequest, uri);
        } catch (Exception ex) {
            serverRequest.metrics().setMessage(getStackTraceAsString(ex));
            // Request URI is not correct nor correctly encoded, returning a bad request
            DirectProxyConnection statusOnlyConnection = new DirectProxyConnection(HttpStatusCode.BAD_REQUEST_400);
            connectionHandler.handle(statusOnlyConnection);
            statusOnlyConnection.sendResponse();
        }
        if (requestUri != null) {
            uri = requestUri.toString();
            // Add the endpoint reference in metrics to know which endpoint has been invoked while serving the request
            serverRequest.metrics().setEndpoint(uri);
            final HttpMethod httpMethod = extractHttpMethod(executionContext, serverRequest);
            ProxyRequest proxyRequest = ProxyRequestBuilder.from(serverRequest).uri(requestUri).method(httpMethod).headers(setProxyHeaders(serverRequest.headers(), requestUri, targetEndpoint.endpoint)).build();
            ProxyConnection proxyConnection = targetEndpoint.endpoint.connector().request(proxyRequest);
            // Enable logging at proxy level
            if (api.getProxy().getLoggingMode().isProxyMode()) {
                proxyConnection = new LoggableProxyConnection(proxyConnection, proxyRequest);
            }
            connectionHandler.handle(proxyConnection);
            // Plug underlying stream to connection stream
            ProxyConnection finalProxyConnection = proxyConnection;
            stream.bodyHandler(buffer -> {
                finalProxyConnection.write(buffer);
                if (finalProxyConnection.writeQueueFull()) {
                    serverRequest.pause();
                    finalProxyConnection.drainHandler(aVoid -> serverRequest.resume());
                }
            }).endHandler(aVoid -> finalProxyConnection.end());
        }
    }
    // Resume the incoming request to handle content and end
    serverRequest.resume();
    return serverRequest;
}
Also used : java.util(java.util) HttpHeaders(io.gravitee.common.http.HttpHeaders) URISyntaxException(java.net.URISyntaxException) ProxyRequest(io.gravitee.gateway.api.proxy.ProxyRequest) Autowired(org.springframework.beans.factory.annotation.Autowired) Invoker(io.gravitee.gateway.api.Invoker) LoggableProxyConnection(io.gravitee.gateway.http.core.invoker.logging.LoggableProxyConnection) HttpStatusCode(io.gravitee.common.http.HttpStatusCode) ProxyRequestBuilder(io.gravitee.gateway.api.proxy.builder.ProxyRequestBuilder) Endpoint(io.gravitee.gateway.api.endpoint.Endpoint) Request(io.gravitee.gateway.api.Request) ReadStream(io.gravitee.gateway.api.stream.ReadStream) URI(java.net.URI) Api(io.gravitee.definition.model.Api) PrintWriter(java.io.PrintWriter) QueryStringEncoder(io.netty.handler.codec.http.QueryStringEncoder) ExecutionContext(io.gravitee.gateway.api.ExecutionContext) MalformedURLException(java.net.MalformedURLException) UrlEscapers(com.google.common.net.UrlEscapers) StringWriter(java.io.StringWriter) DirectProxyConnection(io.gravitee.gateway.http.core.direct.DirectProxyConnection) ProxyConnection(io.gravitee.gateway.api.proxy.ProxyConnection) EndpointManager(io.gravitee.gateway.api.endpoint.EndpointManager) Buffer(io.gravitee.gateway.api.buffer.Buffer) Handler(io.gravitee.gateway.api.handler.Handler) HttpMethod(io.gravitee.common.http.HttpMethod) QueryStringDecoder(io.netty.handler.codec.http.QueryStringDecoder) Pattern(java.util.regex.Pattern) DirectProxyConnection(io.gravitee.gateway.http.core.direct.DirectProxyConnection) LoggableProxyConnection(io.gravitee.gateway.http.core.invoker.logging.LoggableProxyConnection) DirectProxyConnection(io.gravitee.gateway.http.core.direct.DirectProxyConnection) ProxyConnection(io.gravitee.gateway.api.proxy.ProxyConnection) LoggableProxyConnection(io.gravitee.gateway.http.core.invoker.logging.LoggableProxyConnection) ProxyRequest(io.gravitee.gateway.api.proxy.ProxyRequest) URI(java.net.URI) URISyntaxException(java.net.URISyntaxException) MalformedURLException(java.net.MalformedURLException) HttpMethod(io.gravitee.common.http.HttpMethod)

Example 4 with Handler

use of io.gravitee.gateway.api.handler.Handler in project gravitee-gateway by gravitee-io.

the class ApiReactorHandler method handleClientRequest.

private void handleClientRequest(Request serverRequest, Response serverResponse, ExecutionContext executionContext, Handler<Response> handler) {
    serverRequest.pause();
    // Apply request policies
    RequestPolicyChainProcessor requestPolicyChain = new RequestPolicyChainProcessor(policyResolvers);
    requestPolicyChain.setResultHandler(requestPolicyChainResult -> {
        if (requestPolicyChainResult.isFailure()) {
            sendPolicyFailure(requestPolicyChainResult.getPolicyResult(), serverResponse);
            handler.handle(serverResponse);
        } else {
            // Call an invoker to get a proxy connection (connection to an underlying backend, mainly HTTP)
            Invoker upstreamInvoker = (Invoker) executionContext.getAttribute(ExecutionContext.ATTR_INVOKER);
            long serviceInvocationStart = System.currentTimeMillis();
            AtomicReference<ProxyConnection> proxyConnection = new AtomicReference<>();
            Request invokeRequest = upstreamInvoker.invoke(executionContext, serverRequest, requestPolicyChainResult.getPolicyChain(), connection -> {
                proxyConnection.set(connection);
                connection.responseHandler(proxyResponse -> handleProxyResponse(serverRequest, serverResponse, executionContext, proxyResponse, serviceInvocationStart, handler));
                requestPolicyChain.setStreamErrorHandler(result -> {
                    connection.cancel();
                    sendPolicyFailure(result.getPolicyResult(), serverResponse);
                    handler.handle(serverResponse);
                });
            });
            // Plug server request stream to request policy chain stream
            invokeRequest.bodyHandler(chunk -> requestPolicyChainResult.getPolicyChain().write(chunk)).endHandler(aVoid -> requestPolicyChainResult.getPolicyChain().end());
        }
    });
    requestPolicyChain.execute(serverRequest, serverResponse, executionContext);
}
Also used : JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) CorsHandler(io.gravitee.gateway.handlers.api.cors.CorsHandler) HttpHeaders(io.gravitee.common.http.HttpHeaders) PolicyChain(io.gravitee.gateway.policy.impl.PolicyChain) LoggerFactory(org.slf4j.LoggerFactory) HttpHeadersValues(io.gravitee.common.http.HttpHeadersValues) Autowired(org.springframework.beans.factory.annotation.Autowired) Invoker(io.gravitee.gateway.api.Invoker) PolicyManager(io.gravitee.gateway.policy.PolicyManager) AtomicReference(java.util.concurrent.atomic.AtomicReference) InitializingBean(org.springframework.beans.factory.InitializingBean) ArrayList(java.util.ArrayList) HttpStatusCode(io.gravitee.common.http.HttpStatusCode) LoggableClientResponse(io.gravitee.gateway.handlers.api.logging.LoggableClientResponse) RequestPolicyChainProcessor(io.gravitee.gateway.policy.impl.RequestPolicyChainProcessor) LoggableClientRequest(io.gravitee.gateway.handlers.api.logging.LoggableClientRequest) Response(io.gravitee.gateway.api.Response) StreamType(io.gravitee.gateway.policy.StreamType) Reactable(io.gravitee.gateway.reactor.Reactable) Request(io.gravitee.gateway.api.Request) DefaultInvoker(io.gravitee.gateway.http.core.invoker.DefaultInvoker) Logger(org.slf4j.Logger) ExecutionContext(io.gravitee.gateway.api.ExecutionContext) PolicyChainResolver(io.gravitee.gateway.policy.PolicyChainResolver) TemplateContext(io.gravitee.gateway.api.expression.TemplateContext) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) DirectProxyConnection(io.gravitee.gateway.http.core.direct.DirectProxyConnection) Throwables(com.google.common.base.Throwables) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ProxyConnection(io.gravitee.gateway.api.proxy.ProxyConnection) Buffer(io.gravitee.gateway.api.buffer.Buffer) Handler(io.gravitee.gateway.api.handler.Handler) CorsResponseHandler(io.gravitee.gateway.handlers.api.cors.CorsResponseHandler) EndpointLifecycleManager(io.gravitee.gateway.http.core.endpoint.EndpointLifecycleManager) ResourceLifecycleManager(io.gravitee.gateway.resource.ResourceLifecycleManager) List(java.util.List) MediaType(io.gravitee.common.http.MediaType) ProxyResponse(io.gravitee.gateway.api.proxy.ProxyResponse) ExecutionContextFactory(io.gravitee.gateway.handlers.api.context.ExecutionContextFactory) Cors(io.gravitee.definition.model.Cors) TemplateVariableProvider(io.gravitee.gateway.api.expression.TemplateVariableProvider) PlanPolicyChainResolver(io.gravitee.gateway.handlers.api.policy.plan.PlanPolicyChainResolver) Api(io.gravitee.gateway.handlers.api.definition.Api) AbstractReactorHandler(io.gravitee.gateway.reactor.handler.AbstractReactorHandler) PolicyResult(io.gravitee.policy.api.PolicyResult) SecurityPolicyChainResolver(io.gravitee.gateway.security.core.SecurityPolicyChainResolver) ApiPolicyChainResolver(io.gravitee.gateway.handlers.api.policy.api.ApiPolicyChainResolver) Invoker(io.gravitee.gateway.api.Invoker) DefaultInvoker(io.gravitee.gateway.http.core.invoker.DefaultInvoker) DirectProxyConnection(io.gravitee.gateway.http.core.direct.DirectProxyConnection) ProxyConnection(io.gravitee.gateway.api.proxy.ProxyConnection) LoggableClientRequest(io.gravitee.gateway.handlers.api.logging.LoggableClientRequest) Request(io.gravitee.gateway.api.Request) AtomicReference(java.util.concurrent.atomic.AtomicReference) RequestPolicyChainProcessor(io.gravitee.gateway.policy.impl.RequestPolicyChainProcessor)

Aggregations

Request (io.gravitee.gateway.api.Request)4 Handler (io.gravitee.gateway.api.handler.Handler)4 ExecutionContext (io.gravitee.gateway.api.ExecutionContext)3 ProxyConnection (io.gravitee.gateway.api.proxy.ProxyConnection)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 HttpHeaders (io.gravitee.common.http.HttpHeaders)2 HttpStatusCode (io.gravitee.common.http.HttpStatusCode)2 Cors (io.gravitee.definition.model.Cors)2 Invoker (io.gravitee.gateway.api.Invoker)2 Response (io.gravitee.gateway.api.Response)2 Buffer (io.gravitee.gateway.api.buffer.Buffer)2 ProxyResponse (io.gravitee.gateway.api.proxy.ProxyResponse)2 CorsHandler (io.gravitee.gateway.handlers.api.cors.CorsHandler)2 CorsResponseHandler (io.gravitee.gateway.handlers.api.cors.CorsResponseHandler)2 LoggableClientRequest (io.gravitee.gateway.handlers.api.logging.LoggableClientRequest)2 LoggableClientResponse (io.gravitee.gateway.handlers.api.logging.LoggableClientResponse)2 DirectProxyConnection (io.gravitee.gateway.http.core.direct.DirectProxyConnection)2 Autowired (org.springframework.beans.factory.annotation.Autowired)2 JsonProperty (com.fasterxml.jackson.annotation.JsonProperty)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1