Created
February 26, 2020 13:31
-
-
Save jamsesso/b52743886a9e23227ea933775ca5965f to your computer and use it in GitHub Desktop.
Thin lambda dev server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.amazonaws.services.lambda.runtime.Context; | |
import io.javalin.Javalin; | |
import io.javalin.http.HandlerType; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.util.Map; | |
import java.util.regex.Pattern; | |
import java.util.stream.Collectors; | |
public class ApiGatewayServer implements AutoCloseable { | |
private static final Logger LOG = LoggerFactory.getLogger(ApiGatewayServer.class); | |
private final LambdaApplication app; | |
private final int port; | |
private Javalin javalin; | |
public ApiGatewayServer(LambdaApplication app, int port) { | |
this.app = app; | |
this.port = port; | |
} | |
public void start() { | |
javalin = Javalin.create().start("0.0.0.0", port); | |
for (Class<? extends LambdaFunction> function : app.getFunctions()) { | |
Lambda metadata = function.getAnnotation(Lambda.class); | |
HandlerType method = HandlerType.valueOf(metadata.method().toUpperCase()); | |
String path = convertToJavalinPath(metadata.path()); | |
LOG.info("{} /{} ({})", method, metadata.path(), function.getCanonicalName()); | |
javalin.addHandler(method, path, ctx -> { | |
// Build the request objects. | |
Context context = new FakeContext(function); | |
RequestIdentity identity = new RequestIdentity(); | |
identity.setSourceIp(ctx.ip()); | |
identity.setUserAgent(ctx.userAgent()); | |
RequestContext requestContext = new RequestContext(); | |
requestContext.setAccountId("0123456789"); | |
requestContext.setRequestId(context.getAwsRequestId()); | |
requestContext.setStage("local"); | |
requestContext.setIdentity(identity); | |
Request request = new Request(); | |
request.setBase64Encoded(false); | |
request.setBody(ctx.body()); | |
request.setHeaders(ctx.headerMap()); | |
request.setHttpMethod(method.name()); | |
request.setPath(ctx.path()); | |
request.setPathParameters(ctx.pathParamMap()); | |
request.setQueryStringParameters(ctx.queryParamMap().entrySet().stream() | |
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get(0)))); | |
request.setRequestContext(requestContext); | |
// Invoke the handler class. | |
LambdaLauncher launcher = new LambdaLauncher(function, app.module()); | |
Response response = launcher.handleRequest(request, context); | |
// Write the result to the Javalin context. | |
for(Map.Entry<String, String> header : response.getHeaders().entrySet()) { | |
ctx.header(header.getKey(), header.getValue()); | |
} | |
ctx.status(response.getStatusCode()); | |
ctx.result(response.getBody()); | |
}); | |
} | |
// This method does not return. | |
while (!Thread.currentThread().isInterrupted()); | |
} | |
@Override | |
public void close() { | |
if (javalin != null) { | |
javalin.stop(); | |
} | |
} | |
private static String convertToJavalinPath(String apiGatewayPath) { | |
Pattern pattern = Pattern.compile("\\{(?<VARIABLE>[^{}]+)}"); | |
return pattern.matcher(apiGatewayPath).replaceAll(":$1"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Retention(RetentionPolicy.RUNTIME) | |
@Target({ElementType.TYPE}) | |
public @interface Lambda { | |
String path(); | |
String method(); | |
String name() default ""; | |
String description() default ""; | |
int memoryMb() default 128; | |
int timeoutSec() default 60; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.amazonaws.services.lambda.runtime.Context; | |
import com.amazonaws.services.lambda.runtime.RequestHandler; | |
public interface LambdaFunction extends RequestHandler<Request, Response> { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment