1
import software.amazon.awscdk.services.lambda.Function;

Function helloLambda = new Function(helloStack, "hellocdkworld123", FunctionProps.builder()
              .functionName("HelloLambda")
              .code(Code.fromAsset("target/cdkhello-0.1.jar")) // <- x ?
              .runtime(Runtime.JAVA_8)
              .handler("com.myorg.functions.HelloLambda::sayHello") <- y?
              .build());

There is also a possibility to reference it by S3 bucket. But when I run cdk bootstrap I get a generated bucket with generated name of the jar file. How should I be able to reference that before hand from code? Of course now I could write the exact bucket + file but then purpose of defining it from code is lost right?

4

1 回答 1

1

首先,假设您在调用 Lambda 时要执行的方法是sayHello,从com.myorg.functions.HelloLambda类中,那么您的解决方案的那部分是正确的。更困难的部分实际上是使用其中的 Lambda 代码访问 JAR。

注意:我已经用我认为更好的方法来更新我的原始答案。为了避免混淆并使这个答案过于冗长,我删除了原始答案,尽管其中大部分与这个答案很常见。我相信这个答案有助于改进这个答案。

将依赖资源的 JAR 的路径传递给 CDK

TL;博士

  • 为您的 Lambda JAR 的完整路径创建一个新属性。
  • 将依赖和执行相关的目标关联到package构建阶段。
  • 更新cdk.json以指向package阶段。
  • 通过系统属性将完整路径传递给您的 CDK 代码。
  • 使用 System 属性传递给Code.asset(...).

准备

我已将 Lambda 和 CDK 基础设施代码分离到单独的 Maven 模块中。目的是一旦 Lambda 代码被编译,打包成一个 uber JAR(它的代码加上它所有的依赖项的代码),基础设施模块可以将它作为一个依赖项引用,将 Lambda JAR 的完整路径传递给App/Stack 类,它可以将其用作资产。

为您的 Lambda JAR 的完整路径创建一个新属性。

在 的属性部分中pom.xml,创建一个新属性以引用您的 Lambda JAR。像这样的东西:

<properties>
    ...
    <lambda.jar>${GROUP_ID:ARTIFACT_ID:jar}</lambda.jar>
    ...
</properties>

使用依赖项插件使用 Lambda 依赖项的 JAR 的完整路径填充属性。

<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>properties</goal>
                    </goals>
                    <phase>package</phase>
                </execution>
            </executions>
        </plugin>
        ...
    <plugins>
</build>

这将properties目标与process-resources阶段相关联。每当构建的该阶段发生时,您之前创建的属性将使用本地存储库中 JAR 的完整路径填充。

将依赖和执行相关的目标关联到构建的单个阶段。

当您创建一个新的 CDK Java 项目时,它会输出一个名为 的文件cdk.json,该文件默认指向 Mavenexec:java目标。为了lambda.jar正确填充新属性,您需要将exec:java目标与上述相同阶段相关联。

<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.6.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <phase>package</phase>
                </execution>
            </executions>
            <configuration>
                <mainClass>com.myorg.TestingApp</mainClass>
            </configuration>
        </plugin>
        ...
    </plugins>
</build>

为了让您的代码能够访问您生成的 JAR 文件,您需要为您的 App 类创建一个系统属性(我无法让环境变量工作)。你pom.xml从这样的事情开始:

通过系统属性将完整路径传递给您的 CDK 代码。

在配置部分(在 之后mainClass),为您的资产目录添加一个系统属性,如下所示:

<systemProperties>
    <systemProperty>
        <key>lambda.jar</key>
        <value>${lambda.jar}</value>
    </systemProperty>
</systemProperties>

更新cdk.json以指向您使用的公共阶段。

cdk.json的 CDK 项目应更改为指向process-resources阶段。完成后,它将如下所示:

{
  "app": "mvn package"
}

这将导致两个目标连续运行,并且在执行时,您的 Lambda JAR 的路径将作为系统属性传递。

从您的 App/Stack 代码访问该属性。

最后,现在系统属性已创建,您可以通过调用从代码中访问它System.getProperty("lambda.jar")。像这样的东西:

final Code code = Code.fromAsset(System.getProperty("lambda.jar"));

然后,您可以在定义 Lambda 函数时在任何需要的地方使用代码参考。

于 2019-11-25T23:53:25.373 回答