从用Java编写的lambda函数调用lambda函数

时间:2017-05-16 07:20:31

标签: java amazon-web-services aws-lambda

有没有什么好的文档如何从用java编写的lambda函数调用lambda函数? 从lambda函数调用lambda函数或从普通的java应用程序调用是否有区别?

我发现的唯一的东西是普通的AWS Java SDK文档。 http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/index.html

如果有人可以帮助我,我会很高兴。

2 个答案:

答案 0 :(得分:1)

是的,你可以正常地从lambdas调用lambdas,就像你的代码在某个主机上执行一样。

您还有一个额外的步骤可以确保执行对另一个lambda的调用的lambda具有执行其他lambda函数的权限(该权限称为"lambda:InvokeFunction")。

其余步骤与使用AWS SDK的常规java相同,您实例化AWSLambdaClient对象,设置凭据和设置(区域等),然后创建InvokeRequest对象这是用适当的有效载荷调用的子lambda。

Here's some sample java code which does exactly this,但它也是标准sdk文档的一部分。

并且还要记住,您仍将受到第一个lambda的原始超时限制,否则将停止执行。

以下是您应该能够使用的相关代码片段,我已经根据凭据更改了第二个lamdba的调用方式 - 您可以将用于调用第一个lambda的凭据隐式传递给第二个一个,这可能更简单,更易于维护 - 您只需要确保第一个lambda调用获取凭据,其余的将继承它们。

    Region region;
    AWSLambdaClient lambdaClient;

    lambdaClient = new AWSLambdaClient(new DefaultAWSCredentialsProviderChain());
    region = Region.getRegion(Regions.fromName(regionName));
    lambdaClient.setRegion(region);

    InvokeRequest invokeRequest = new InvokeRequest();
    invokeRequest.setFunctionName(FunctionName);
    invokeRequest.setPayload(ipInput);


    returnDetails = byteBufferToString(
            lambdaClient.invoke(invokeRequest).getPayload(),
            Charset.forName("UTF-8"),logger);

编辑:我还应该指出,根据您的体系结构,可能有更清晰的选项,比如使用SQS,或者取决于嵌套lambda的简单程度,将它们直接内嵌在彼此中以避免额外的调用。

答案 1 :(得分:0)

许多已使用的API函数已弃用,AWS文档是......我共享一个新实现的示例。 Lambda函数" updateS3Chart"调用另一个Lambda函数" AsyncUpdate"异步:

public class LambdaInvoker {
static final Logger logger = LogManager.getLogger(LambdaInvoker.class);
static final String LambdaFunctionName = "AsyncUpdate"; 

private class AsyncLambdaHandler implements AsyncHandler<InvokeRequest, InvokeResult>
{
    public void onSuccess(InvokeRequest req, InvokeResult res) {
        logger.debug("\nLambda function returned:");
        ByteBuffer response_payload = res.getPayload();
        logger.debug(new String(response_payload.array()));
    }
    public void onError(Exception e) {
        logger.debug(e.getMessage());
    }
}

public void updateS3Chart(UpdateS3ChartRequest updateS3ChartRequest) {
    Gson gson = new Gson();

    try {
        //issue: aws region is not set to debug-time. solution for eclipse:
        //environment variable is set by lambda container or eclipse ide environment variables
        //use instead for eclipse debugging: project -> Run as -> Run Configurations -> Environment -> Add variable: "AWS_REGION": "eu-central-1"
        AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); //Default async client using the DefaultAWSCredentialsProviderChain and DefaultAwsRegionProviderChain chain
        InvokeRequest req = new InvokeRequest()
            .withFunctionName(LambdaFunctionName)
            .withPayload(gson.toJson(updateS3ChartRequest));

        Future<InvokeResult> future_res = lambda.invokeAsync(req, new AsyncLambdaHandler());

        logger.debug("Waiting for async callback");
        while (!future_res.isDone() && !future_res.isCancelled()) {
            // perform some other tasks...
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                logger.debug("Thread.sleep() was interrupted!");
            }
            System.out.print(".");
        }

    } catch (Exception e) {
        logger.fatal("Execute async lambda function: " + LambdaFunctionName + " failed: " + e.getMessage());
    }

}
}

您必须在IDE中将AWS区域设置为系统属性以进行调试(请参阅Eclipse源代码中的注释)。 UpdateS3ChartRequest是带有属性set / get的简单POJO。