Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(type-safe-api): enable snapstart for java handlers by default and optimise java interceptors #597

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@

import org.jetbrains.annotations.NotNull;
import software.amazon.awscdk.services.lambda.Function;
import software.aws.pdk.type_safe_api.SnapStartFunction;
import software.constructs.Construct;

/**
* Lambda function construct which points to the {{vendorExtensions.x-handler.language}} implementation of {{operationIdCamelCase}}
*/
public class {{operationIdCamelCase}}Function extends Function {
public class {{operationIdCamelCase}}Function extends {{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}Function {
public {{operationIdCamelCase}}Function(@NotNull Construct scope, @NotNull String id, @NotNull {{operationIdCamelCase}}FunctionProps props) {
super(scope, id, props);
}
Expand Down Expand Up @@ -67,6 +68,7 @@ import software.amazon.awscdk.services.lambda.VersionOptions;
import software.amazon.awscdk.services.logs.RetentionDays;
import software.amazon.awscdk.services.sns.ITopic;
import software.amazon.awscdk.services.sqs.IQueue;
import software.aws.pdk.type_safe_api.SnapStartFunctionProps;
cogwirrel marked this conversation as resolved.
Show resolved Hide resolved

import java.io.BufferedReader;
import java.io.IOException;
Expand All @@ -77,7 +79,7 @@ import java.util.List;
import java.util.Map;

@lombok.Builder @lombok.Getter
public class {{operationIdCamelCase}}FunctionProps implements FunctionProps {
public class {{operationIdCamelCase}}FunctionProps implements {{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}FunctionProps {
private static String infraProjectAbsolutePath;

static {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ import java.util.List;
* The {{operationIdCamelCase}} class manages marshalling inputs and outputs.
*/
public class {{operationIdCamelCase}}Handler extends {{operationIdCamelCase}} {
/**
* Interceptors are initialised once during the lambda "init" phase
*/
private final List<Interceptor<{{operationIdCamelCase}}Input>> interceptors = DefaultInterceptors.all();

/**
* Return the interceptors for this handler.
* You can also use the @Interceptors annotation on the class to add interceptors
*/
@Override
public List<Interceptor<{{operationIdCamelCase}}Input>> getInterceptors() {
return DefaultInterceptors.all();
return this.interceptors;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,11 @@ public abstract class {{operationIdCamelCase}} implements RequestHandler<APIGate
*/
public abstract {{operationIdCamelCase}}Response handle(final {{operationIdCamelCase}}RequestInput request);

/**
* Interceptors that the handler class has been decorated with
*/
private List<Interceptor<{{operationIdCamelCase}}Input>> annotationInterceptors = Handlers.getAnnotationInterceptors({{operationIdCamelCase}}.class);

/**
* For more complex interceptors that require instantiation with parameters, you may override this method to
* return a list of instantiated interceptors. For simple interceptors with no need for constructor arguments,
Expand Down Expand Up @@ -1055,9 +1060,6 @@ public abstract class {{operationIdCamelCase}} implements RequestHandler<APIGate

List<Interceptor<{{operationIdCamelCase}}Input>> interceptors = new ArrayList<>();
interceptors.addAll(additionalInterceptors);

List<Interceptor<{{operationIdCamelCase}}Input>> annotationInterceptors = Handlers.getAnnotationInterceptors(this.getClass());

interceptors.addAll(annotationInterceptors);
interceptors.addAll(this.getInterceptors());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ import software.amazon.lambda.powertools.logging.LoggingUtils;
* See https://docs.powertools.aws.dev/lambda/java/latest/core/logging/
*/
public class LoggingInterceptor<Input> implements Interceptor<Input> {
private Logger logger = LogManager.getLogger(LoggingInterceptor.class);

/**
* Return the instance of the logger from the interceptor context
Expand Down Expand Up @@ -161,7 +162,6 @@ public class LoggingInterceptor<Input> implements Interceptor<Input> {
LoggingUtils.appendKey("operationId", operationId);

// Add the logger to the interceptor context
Logger logger = LogManager.getLogger(operationId);
input.getInterceptorContext().put("logger", logger);

Response response = input.getChain().next(input);
Expand Down Expand Up @@ -202,6 +202,13 @@ import software.amazon.lambda.powertools.tracing.TracingUtils;
*/
public class TracingInterceptor<Input> implements Interceptor<Input> {

{
// Create a segment during the lambda init phase to ensure xray emitter
// is warmed up prior to invocation phase
AWSXRay.beginSubsegment("Tracing Interceptor - Init");
AWSXRay.endSubsegment();
}

private final boolean captureResponse;

public TracingInterceptor(final boolean captureResponse) {
Expand Down Expand Up @@ -284,6 +291,7 @@ import software.amazon.lambda.powertools.metrics.MetricsUtils;
* See: https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics
*/
public class MetricsInterceptor<Input> implements Interceptor<Input> {
private MetricsLogger metrics = MetricsUtils.metricsLogger();

/**
* Return the instance of the metrics logger from the interceptor context
Expand All @@ -298,7 +306,6 @@ public class MetricsInterceptor<Input> implements Interceptor<Input> {

@Override
public Response handle(final ChainedRequestInput<Input> input) {
MetricsLogger metrics = MetricsUtils.metricsLogger();
metrics.putDimensions(DimensionSet.of("operationId", (String) input.getInterceptorContext().get("operationId")));

input.getInterceptorContext().put("metrics", metrics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from aws_cdk.aws_lambda import (
Function, Runtime, Tracing, Code
)
from aws_pdk.type_safe_api import SnapStartFunction
cogwirrel marked this conversation as resolved.
Show resolved Hide resolved
from os import path
from pathlib import Path

Expand All @@ -19,7 +20,7 @@ from pathlib import Path
{{#operation ~}}
{{#if vendorExtensions.x-handler}}

class {{operationIdCamelCase}}Function(Function):
class {{operationIdCamelCase}}Function({{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}Function):
"""
Lambda function construct which points to the {{vendorExtensions.x-handler.language}} implementation of {{operationIdCamelCase}}
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
}
###/TSAPI_WRITE_FILE###import { Construct } from "constructs";
import { Duration } from "aws-cdk-lib";
import { SnapStartFunction, SnapStartFunctionProps } from "@aws/pdk/type-safe-api";
import { Code, Function, Runtime, Tracing, FunctionProps } from "aws-cdk-lib/aws-lambda";
import * as path from "path";
{{#apiInfo ~}}
Expand All @@ -20,12 +21,12 @@ import * as path from "path";
/**
* Options for the {{operationIdCamelCase}}Function construct
*/
export interface {{operationIdCamelCase}}FunctionProps extends Omit<FunctionProps, 'code' | 'handler' | 'runtime'> {}
export interface {{operationIdCamelCase}}FunctionProps extends Omit<{{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}FunctionProps, 'code' | 'handler' | 'runtime'> {}

/**
* Lambda function construct which points to the {{vendorExtensions.x-handler.language}} implementation of {{operationIdCamelCase}}
*/
export class {{operationIdCamelCase}}Function extends Function {
export class {{operationIdCamelCase}}Function extends {{#startsWith vendorExtensions.x-handler.language 'java' ~}}SnapStart{{~/startsWith}}Function {
constructor(scope: Construct, id: string, props?: {{operationIdCamelCase}}FunctionProps) {
super(scope, id, {
{{#startsWith vendorExtensions.x-handler.language 'typescript' ~}}
Expand Down
3 changes: 3 additions & 0 deletions packages/type-safe-api/src/construct/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
export * from "./snap-start-java-function";
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
import { CfnFunction, Function, FunctionProps } from "aws-cdk-lib/aws-lambda";
import { Construct } from "constructs";

/**
* Options for the SnapStartFunction construct
*/
export interface SnapStartFunctionProps extends FunctionProps {
/**
* When true, disable snap start
* @default false
*/
readonly disableSnapStart?: boolean;
}

/**
* A lambda function which enables SnapStart on published versions by default
*/
export class SnapStartFunction extends Function {
constructor(scope: Construct, id: string, props: SnapStartFunctionProps) {
super(scope, id, props);

if (!props.disableSnapStart) {
(this.node.defaultChild as CfnFunction).addPropertyOverride("SnapStart", {
ApplyOn: "PublishedVersions",
});
}
}
}
1 change: 1 addition & 0 deletions packages/type-safe-api/src/construct/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./waf/types";
export * from "./authorizers";
export * from "./integrations";
export * from "./spec";
export * from "./functions";
8 changes: 7 additions & 1 deletion packages/type-safe-api/src/construct/integrations/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
IntegrationGrantProps,
IntegrationRenderProps,
} from "./integration";
import { SnapStartFunction } from "../functions/snap-start-java-function";
import { functionInvocationUri } from "../spec/utils";

/**
Expand All @@ -18,7 +19,12 @@ export class LambdaIntegration extends Integration {

constructor(lambdaFunction: IFunction) {
super();
this.lambdaFunction = lambdaFunction;
// Snap Start applies only to versions, so if the function is a SnapStartFunction, we'll reference the current version
if (lambdaFunction instanceof SnapStartFunction) {
this.lambdaFunction = lambdaFunction.currentVersion;
} else {
this.lambdaFunction = lambdaFunction;
}
}

/**
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading