Western Pacific Railroad and the beginnings of business software development, Java 7 features, Project Coin,
Project Amber, Java's serialization challenges and thoughts on future of Java serialization
To read a Java String with Jakarta JSON Processing (JSON-P) into a jakarta.json.JsonObject with Glassfish' implementation add the following dependency to your pom.xml:
import java.io.StringReader;
import org.junit.jupiter.api.Test;
import jakarta.json.Json;
public class JsonpWithGlassfishTest {
@Test
public void parseJSON() {
var expected = "glassfish";
var json = """
{"hello":"%s"}
""".formatted(expected);
try (var stringReader = new StringReader(json)){
var jsonObject = Json.createReader(stringReader).readObject();
var actual = jsonObject.getString("hello");
assertEquals(expected, actual);
}
}
}
To use the latest AWS Lambda deployment with HTTP API Gateway (or REST API Gateway):
import software.amazon.awscdk.services.apigatewayv2.alpha.HttpApi;
import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegration;
//...
void integrateWithHTTPApiGateway(IFunction function) {
var lambdaIntegration = HttpLambdaIntegration.Builder.create("HttpApiGatewayIntegration", function).build();
var httpApiGateway = HttpApi.Builder.create(this, "HttpApiGatewayIntegration")
.defaultIntegration(lambdaIntegration).build();
var url = httpApiGateway.getUrl();
CfnOutput.Builder.create(this, "HttpApiGatewayUrlOutput").value(url).build();
}
...configured with provisioned concurrency,
you need to create an alias function.addAlias("XYZ"); (this convenience method was introduced with CDK v2.23.0) in addition to the version and use the function instance for the integration:
import software.amazon.awscdk.Duration;
import software.amazon.awscdk.services.lambda.Architecture;
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.Version;
import software.constructs.Construct;
public class QuarkusLambda extends Construct {
static String lambdaHandler = "io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest";
static int memory = 1024; // ~0.5 vCPU
static int provisionedConcurrency = 1;
static int timeout = 10;
Function function;
public QuarkusLambda(Construct scope, String functionName) {
super(scope, "QuarkusLambda");
this.function = createFunction(functionName, lambdaHandler, memory, timeout);
Version.Builder.create(this, "ProvisionedConcurrencyVersion")
.lambda(function)
.provisionedConcurrentExecutions(provisionedConcurrency)
.build();
function.addAlias("recent");
integrateWithHTTPApiGateway(function);
}
Function createFunction(String functionName, String functionHandler, int memory, int timeout) {
return Function.Builder.create(this, functionName)
.runtime(Runtime.JAVA_11)
.architecture(Architecture.ARM_64)
.code(Code.fromAsset("../lambda/target/function.zip"))
.handler(functionHandler)
.memorySize(memory)
.functionName(functionName)
.timeout(Duration.seconds(timeout))
.build();
}
}
To fix the following AWS Lambda deployment error error:
Resource handler returned message: "Specified ReservedConcurrentExecutions for function decreases account's UnreservedConcurrentExecution below its minimum value of [50]. (Service: Lambda, Status Code: 400, Request ID: (...)
remove the reservedConcurrentExecutions from the lambda configuration:
With Lambda function URLs you can directly
expose an AWS Lambda, without REST / HTTP API Gateway or Application Load Balancer.
An AWS Lambda function:
import software.amazon.awscdk.services.lambda.IFunction;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.constructs.Construct;
public class QuarkusLambda extends Construct{
static Map<String, String> configuration = Map.of("message", "hello, quarkus as AWS Lambda");
static String lambdaHandler = "io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest";
static int memory = 1024; //~0.5 vCPU
static int maxConcurrency = 2;
static int timeout = 10;
IFunction function;
public QuarkusLambda(Construct scope,String functionName) {
super(scope, "QuarkusLambda");
this.function = createFunction(functionName, lambdaHandler, configuration, memory, maxConcurrency, timeout);
}
IFunction createFunction(String functionName,String functionHandler, Map<String,String> configuration, int memory, int maximumConcurrentExecution, int timeout) {
return Function.Builder.create(this, functionName)
.runtime(Runtime.JAVA_11)
.architecture(Architecture.ARM_64)
.code(Code.fromAsset("../lambda/target/function.zip"))
.handler(functionHandler)
.memorySize(memory)
.functionName(functionName)
.environment(configuration)
.timeout(Duration.seconds(timeout))
.reservedConcurrentExecutions(maximumConcurrentExecution)
.build();
}
public IFunction getFunction(){
return this.function;
}
}
Can be directly exposed via a generated URL with:
var quarkuLambda = new QuarkusLambda(this, "airhacks_lambda_gretings_boundary_FUrl");
var function = quarkuLambda.getFunction();
var functionUrl = function
.addFunctionUrl(FunctionUrlOptions.builder()
.authType(FunctionUrlAuthType.NONE)
.build());
CfnOutput.Builder.create(this, "FunctionURLOutput").value(functionUrl.getUrl()).build();
In this 6 minute screencast I refactored a Lambda from HTTP API Gateway to use Function URL directly: