如何在另一个AWS Java Lambda函数中调用aws java lambda函数,两者都在同一个帐户中,同一个区域

我有一个java aws lambda函数或处理程序作为AHandler来做一些事情,例如它已经订阅了SNS事件,它解析了SNS事件并将相关数据记录到数据库中。

我有另一个java aws lambda BHandler,这个BHandler的目标是从AHandler接收请求并向AHandler提供响应。 因为BHandler的目标是提供一些json数据的响应。 这将由AHandler使用。

我是否可以看到任何明确的例子,告诉我们如何做这些事情?

我看到这个例子从java类 调用lambda函数和从java调用lambda函数

我的问题讨论了这种情况,当一个aws java lambda函数(或处理程序)调用另一个aws java lambda函数时,两者都在同一个区域,相同的帐户,相同的vpc执行东西,相同的权限。 在那种情况下,aws java lambda函数可以直接调用(或调用)到另一个或仍然必须提供aws键,区域等东西(如上面的链接)? 一个明确的例子/解释将非常有帮助。

编辑

正在调用另一个Lambda函数(BHandler)的AHandler,存在于同一个帐户上,已经给出了完整的AWSLambdaFullAccess ,例如

“iam:PassRole”,“lambda:*”,

这是要调用的代码:

注意:当我使用普通java main函数调用相同的函数时,下面的代码可以工作。 但它不像在lambda函数上调用一样(就像ALambdaHandler调用BLambdaHandler作为函数调用)。 即使它没有返回任何例外。 它只是显示超时,它被困在代码:lambdaClient.invoke

String awsAccessKeyId = PropertyManager.getSetting("awsAccessKeyId"); String awsSecretAccessKey = PropertyManager.getSetting("awsSecretAccessKey"); String regionName = PropertyManager.getSetting("regionName"); String geoIPFunctionName = PropertyManager.getSetting("FunctionName"); Region region; AWSCredentials credentials; AWSLambdaClient lambdaClient; credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey); lambdaClient = (credentials == null) ? new AWSLambdaClient() : new AWSLambdaClient(credentials); region = Region.getRegion(Regions.fromName(regionName)); lambdaClient.setRegion(region); String returnGeoIPDetails = null; try { InvokeRequest invokeRequest = new InvokeRequest(); invokeRequest.setFunctionName(FunctionName); invokeRequest.setPayload(ipInput); returnDetails = byteBufferToString( lambdaClient.invoke(invokeRequest).getPayload(), Charset.forName("UTF-8"),logger); } catch (Exception e) { logger.log(e.getMessage()); } 

编辑我按照其他人的建议做了一切,并遵循了一切。 最后我达到了AWS支持,问题与一些VPC配置相关,并且已经解决了。如果你遇到类似的东西,那么可能会检查安全配置,VPC的东西。

我们通过使用com.amazonaws.services.lambda.model.InvokeRequest实现了这一点。 这是代码示例。

 public class LambdaInvokerFromCode { public void runWithoutPayload(String functionName) { runWithPayload(functionName, null); } public void runWithPayload(String functionName, String payload) { AWSLambdaAsyncClient client = new AWSLambdaAsyncClient(); client.withRegion(Regions.US_EAST_1); InvokeRequest request = new InvokeRequest(); request.withFunctionName(functionName).withPayload(payload); InvokeResult invoke = client.invoke(request); System.out.println("Result invoking " + functionName + ": " + invoke); } public static void main(String[] args) { String KeyName ="41159569322017486.json"; String status = "success"; String body = "{\"bucketName\":\""+DBUtils.S3BUCKET_BULKORDER+"\",\"keyName\":\""+KeyName+"\", \"status\":\""+status+"\"}"; System.out.println(body); JSONObject inputjson = new JSONObject(body); String bucketName = inputjson.getString("bucketName"); String keyName = inputjson.getString("keyName"); String Status = inputjson.getString("status"); String destinationKeyName = keyName+"_"+status; LambdaInvokerFromCode obj = new LambdaInvokerFromCode(); obj.runWithPayload(DBUtils.FILE_RENAME_HANDLER_NAME,body); } } 

我们有类似的问题,并试图收集各种实现来实现这一目标。 原来它与代码无关。

几个基本规则:

  1. 确保lambda函数的正确策略和角色,至少: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs: : : " }, { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ " " ] } ] }
  2. 在同一地区有function。

  3. 无需VPC配置。 如果您的应用程序具有VPC,请确保您的lambda函数具有适当的角色策略(请参阅AWSLambdaVPCAccessExecutionRole)

  4. 最重要的(主要是为什么它失败了),设置正确的超时和堆大小。 调用Lambda将等到被叫一个完成。 2x被称为lambda值的简单数学运算。 这也只是使用java lambda函数调用另一个java lambda函数。 使用节点js lambda函数调用另一个lambda函数没有这个问题。

以下是一些适合我们的实现:

  1. 使用服务接口
 import com.amazonaws.regions.Regions; import com.amazonaws.services.lambda.AWSLambdaAsyncClientBuilder; import com.amazonaws.services.lambda.invoke.LambdaInvokerFactory; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; public class LambdaFunctionHandler implements RequestHandler { @Override public String handleRequest(Object input, Context context) { context.getLogger().log("Input: " + input); FineGrainedService fg = LambdaInvokerFactory.builder() .lambdaClient( AWSLambdaAsyncClientBuilder.standard() .withRegion(Regions.US_EAST_2) .build() ) .build(FineGrainedService.class); context.getLogger().log("Response back from FG" + fg.getClass()); String fgRespone = fg.callFineGrained("Call from Gateway"); context.getLogger().log("fgRespone: " + fgRespone); // TODO: implement your handler return "Hello from Gateway Lambda!"; } } import com.amazonaws.services.lambda.invoke.LambdaFunction; public interface FineGrainedService { @LambdaFunction(functionName="SimpleFineGrained") String callFineGrained(String input); } 
  1. 使用调用者
 import java.nio.ByteBuffer; import com.amazonaws.services.lambda.AWSLambdaClient; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; public class LambdaFunctionHandler implements RequestHandler { @Override public String handleRequest(Object input, Context context) { context.getLogger().log("Input: " + input); AWSLambdaClient lambdaClient = new AWSLambdaClient(); try { InvokeRequest invokeRequest = new InvokeRequest(); invokeRequest.setFunctionName("SimpleFineGrained"); invokeRequest.setPayload("From gateway"); context.getLogger().log("Before Invoke"); ByteBuffer payload = lambdaClient.invoke(invokeRequest).getPayload(); context.getLogger().log("After Inoke"); context.getLogger().log(payload.toString()); context.getLogger().log("After Payload logger"); } catch (Exception e) { // TODO: handle exception } // TODO: implement your handler return "Hello from Lambda!"; } } 

应该从构建器创建AWSLambdaClient。

  • 确保Lambda函数执行的角色具有lambda:InvokeFunction权限。
  • 然后使用AWS SDK调用第2个函数。 (Doc: http : //docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/lambda/AWSLambdaClient.html#invoke (com.amazonaws.services.lambda.model.InvokeRequest ) )

编辑:对于这种情况,请考虑使用步骤函数 。