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

从用Java编写的lambda函数调用lambda函数,java,amazon-web-services,aws-lambda,Java,Amazon Web Services,Aws Lambda,有没有关于如何从java编写的lambda函数调用lambda函数的好文档? 从lambda函数调用lambda函数与从普通java应用程序调用lambda函数之间有区别吗 我唯一找到的是普通的AWS Java SDK文档。 如果有人能帮助我,我会很高兴。是的,您可以正常地从lambdas调用lambdas,就像您的代码在某个主机上执行一样 您将有一个额外的步骤来确保执行对另一个lambda的调用的lambda具有执行其他lambda函数的权限(该权限被调用) 其余步骤与使用AWS SDK的常

有没有关于如何从java编写的lambda函数调用lambda函数的好文档? 从lambda函数调用lambda函数与从普通java应用程序调用lambda函数之间有区别吗

我唯一找到的是普通的AWS Java SDK文档。


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

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

您将有一个额外的步骤来确保执行对另一个lambda的调用的lambda具有执行其他lambda函数的权限(该权限被调用)

其余步骤与使用AWS SDK的常规java相同,实例化一个对象,设置凭证和设置(区域等),然后创建一个
InvokeRequest
对象,该对象是要使用适当负载调用的子lambda

,但它也是标准sdk文档的一部分


还要记住,对于第一个lambda,您仍然需要遵守原始超时,否则执行将停止

以下是您应该能够使用的相关代码片段,我已经更改了第二个lamdba在凭据方面的调用方式-您可以将用于调用第一个lambda的凭据隐式传递到第二个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的简单程度,将它们直接内联到彼此内部以避免额外调用。

许多使用的API函数都不推荐使用,AWS docu。。。我分享一个新实现的示例。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());
    }

}
}
公共类LambdaInvoker{
静态最终记录器Logger=LogManager.getLogger(LambdaInvoker.class);
静态最终字符串lambdFunctionName=“AsyncUpdate”;
私有类AsyncLambdaHandler实现AsyncHandler
{
成功时公共无效(InvokeRequest请求、InvokeResult请求){
debug(“\nLambda函数返回:”);
ByteBuffer response_payload=res.getPayload();
debug(新字符串(response_payload.array());
}
公共无效申报人(例外e){
debug(例如getMessage());
}
}
public void updateS3Chart(UpdateS3ChartRequest UpdateS3ChartRequest){
Gson Gson=新的Gson();
试一试{
//问题:aws区域未设置为调试时间。eclipse的解决方案:
//环境变量由lambda容器或eclipseide环境变量设置
//改为用于eclipse调试:项目->运行方式->运行配置->环境->添加变量:“AWS\U区域”:“eu-central-1”
AWSLambdaAsync lambda=AWSLambdaAsyncClientBuilder.defaultClient();//使用DefaultAWSCredentialsProviderChain和DefaultAwsRegionProviderChain的默认异步客户端
InvokeRequest req=新InvokeRequest()
.withFunctionName(lambdFunctionName)
.withPayload(gson.toJson(updateS3ChartRequest));
Future_res=lambda.invokeAsync(req,new asynchlambdahandler());
debug(“等待异步回调”);
而(!future_res.isDone()&&!future_res.isCancelled()){
//执行一些其他任务。。。
试一试{
睡眠(1000);
}
捕捉(中断异常e){
debug(“Thread.sleep()被中断!”);
}
系统输出打印(“.”);
}
}捕获(例外e){
致命(“执行异步lambda函数:+lambdfunctionname+”失败:+e.getMessage());
}
}
}

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

lambda是功能接口的简写,如果您有一个实例,您可以像调用普通方法一样调用它。如果你在谈论其他事情,那么把你的实际问题贴出来。确保传递
InvocationType='Event'
以确保子调用是正确的asynchronous@AlastairMcCormack-这可能取决于他的用例,但我假设他想调用另一个lambda函数,然后在第一个函数中返回结果进行进一步处理,这意味着他应该将默认的lambda调用类型调用保留为
RequestResponse
,以便它是同步的-真的。我假设如果OP想要调用更多的同步代码,那么他们会将其放在同一个Lambda方法中。我想我们不知道:)实际上我只是想把数据传递给第二个lambda函数,所以我认为异步是正确的方法。谢谢大家迄今为止的帮助!“还请记住,对于第一个lambda,您仍将受到原始超时的约束,否则将停止执行”我认为子lambda和父lambda之间没有任何依赖关系。在父对象完成后,子对象将继续愉快地运行(当然,前提是您启动子对象异步,并在父对象完成之前为调用留出时间)。我想你可能只是在谈论一个同步调用,但我只是想澄清一下,你可以创建一个完全独立的子lambda。