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

io.quarkus.amazon.lambda.runtime.MockHttpEventServer Maven / Gradle / Ivy

package io.quarkus.amazon.lambda.runtime;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;

import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.RoutingContext;

public class MockHttpEventServer extends MockEventServer {

    private final ObjectWriter eventWriter;
    private final ObjectReader responseReader;

    public MockHttpEventServer() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        eventWriter = objectMapper.writerFor(APIGatewayV2HTTPEvent.class);
        responseReader = objectMapper.readerFor(APIGatewayV2HTTPResponse.class);
    }

    @Override
    protected void defaultHandlerSetup() {
        router.route().handler(this::handleHttpRequests);
    }

    public void handleHttpRequests(RoutingContext ctx) {
        String requestId = ctx.request().getHeader(AmazonLambdaApi.LAMBDA_RUNTIME_AWS_REQUEST_ID);
        if (requestId == null) {
            requestId = UUID.randomUUID().toString();
        }
        ctx.put(AmazonLambdaApi.LAMBDA_RUNTIME_AWS_REQUEST_ID, requestId);
        String traceId = ctx.request().getHeader(AmazonLambdaApi.LAMBDA_RUNTIME_AWS_REQUEST_ID);
        if (traceId == null) {
            traceId = UUID.randomUUID().toString();
        }
        ctx.put(AmazonLambdaApi.LAMBDA_TRACE_HEADER_KEY, traceId);
        Buffer body = ctx.getBody();

        APIGatewayV2HTTPEvent event = new APIGatewayV2HTTPEvent();
        event.setRequestContext(new APIGatewayV2HTTPEvent.RequestContext());
        event.getRequestContext().setHttp(new APIGatewayV2HTTPEvent.RequestContext.Http());
        event.getRequestContext().getHttp().setMethod(ctx.request().method().name());
        event.getRequestContext().getHttp().setSourceIp(ctx.request().connection().remoteAddress().hostAddress());
        event.setRawPath(ctx.request().path());
        event.setRawQueryString(ctx.request().query());
        for (String header : ctx.request().headers().names()) {
            if (header.equalsIgnoreCase("Expect")) {
                String expect = ctx.request().getHeader("Expect");
                if (expect != null && expect.equalsIgnoreCase(CONTINUE)) {
                    continue;
                }
            }
            if (event.getHeaders() == null)
                event.setHeaders(new HashMap<>());
            List values = ctx.request().headers().getAll(header);
            String value = String.join(",", values);
            event.getHeaders().put(header, value);
        }
        if (body != null) {
            String ct = ctx.request().getHeader("content-type");
            if (ct == null || isBinary(ct)) {
                String encoded = Base64.getEncoder().encodeToString(body.getBytes());
                event.setBody(encoded);
                event.setIsBase64Encoded(true);
            } else {
                event.setBody(new String(body.getBytes(), StandardCharsets.UTF_8));
            }
        }

        try {
            byte[] mEvent = eventWriter.writeValueAsBytes(event);
            ctx.put(APIGatewayV2HTTPEvent.class.getName(), mEvent);
            log.debugf("Putting message %s into the queue", requestId);
            queue.put(ctx);
        } catch (Exception e) {
            log.error("Publish failure", e);
            ctx.fail(500);
        }
    }

    @Override
    protected String getEventContentType(RoutingContext request) {
        if (request.get(APIGatewayV2HTTPEvent.class.getName()) != null)
            return "application/json";
        return super.getEventContentType(request);
    }

    @Override
    protected Buffer processEventBody(RoutingContext request) {
        byte[] buf = request.get(APIGatewayV2HTTPEvent.class.getName());
        if (buf != null) {
            return Buffer.buffer(buf);
        }
        return super.processEventBody(request);
    }

    @Override
    public void processResponse(RoutingContext ctx, RoutingContext pending, Buffer buffer) {
        if (pending.get(APIGatewayV2HTTPEvent.class.getName()) != null) {
            try {
                APIGatewayV2HTTPResponse res = responseReader.readValue(buffer.getBytes());
                HttpServerResponse response = pending.response();
                if (res.getHeaders() != null) {
                    for (Map.Entry header : res.getHeaders().entrySet()) {
                        if (canHaveCommaValue(header.getKey())) {
                            response.headers().add(header.getKey(), header.getValue());

                        } else {
                            for (String val : header.getValue().split(",")) {
                                response.headers().add(header.getKey(), val);
                            }
                        }
                    }
                }
                if (res.getCookies() != null) {
                    for (String cookie : res.getCookies()) {
                        response.headers().add("set-cookie", cookie);
                    }
                }
                response.setStatusCode(res.getStatusCode());
                String body = res.getBody();
                if (body != null) {
                    if (res.getIsBase64Encoded()) {
                        byte[] bytes = Base64.getDecoder().decode(body);
                        response.end(Buffer.buffer(bytes));
                    } else {
                        response.end(body);
                    }
                } else {
                    response.end();
                }

            } catch (IOException e) {
                log.error("Publish failure", e);
                pending.fail(500);
            }
        } else {
            super.processResponse(ctx, pending, buffer);
        }
    }

    private boolean isBinary(String contentType) {
        if (contentType != null) {
            String ct = contentType.toLowerCase(Locale.ROOT);
            return !(ct.startsWith("text") || ct.contains("json") || ct.contains("xml") || ct.contains("yaml"));
        }
        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy