当两个函数位于同一账户、同一区域时,如何从另一个 AWS Java Lambda 函数调用 aws java lambda 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36483042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call an aws java lambda function from another AWS Java Lambda function when both are in same account, same region
提问by Sumit Arora
I have a java aws lambda function or handler as AHandler that does some stuff e.g. It has been subscribed to SNS events, It parses that SNS event and log relevant data to the database.
我有一个 java aws lambda 函数或处理程序作为 AHandler 做一些事情,例如它已订阅 SNS 事件,它解析该 SNS 事件并将相关数据记录到数据库中。
I have another java aws lambda BHandler, Objective of this BHandler to receive a request from AHandler and provide a response back to AHandler. Because BHandler's objective is to provide a response with some json data. and that would be used by the AHandler.
我有另一个 java aws lambda BHandler,这个 BHandler 的目标是接收来自 AHandler 的请求并将响应提供给 AHandler。因为 BHandler 的目标是提供一些 json 数据的响应。这将被 AHandler 使用。
May I see any clear example which tells how we can do such things ?
我可以看到任何明确的例子来说明我们如何做这些事情吗?
I saw this example call lambda function from a java classand Invoke lambda function from java
我看到这个例子call lambda function from a java classand Invoke lambda function from java
My question talks about that situation, when one aws java lambda function (or handler) calls to another aws java lambda function when both are in same region, same account,same vpc execution stuff, same rights.In that case aws java lambda function can directly call( or invoke) to another or still it has to provide aws key,region etc stuff (as in above links) ? A clear example/explanation would be very helpful.
我的问题是关于这种情况,当一个 aws java lambda 函数(或处理程序)调用另一个 aws java lambda 函数时,两者都在同一区域、同一帐户、相同的 vpc 执行内容、相同的权利。在这种情况下,aws java lambda 函数可以直接调用(或调用)另一个函数,或者它仍然必须提供 aws 密钥、区域等内容(如上面的链接所示)?一个明确的例子/解释会非常有帮助。
EDIT
编辑
The AHandler who is calling another Lambda function (BHandler) , exist on same account have given complete AWSLambdaFullAccesswith everything e.g.
正在调用另一个 Lambda 函数 (BHandler) 的 AHandler 存在于同一个帐户中,已经为所有内容提供了完整的AWSLambdaFullAccess,例如
“iam:PassRole", "lambda:*",
“iam:PassRole”, “lambda:*”,
Here is the code to call :
这是要调用的代码:
Note :Below code works when I call the same function with everything same from a normal java main function. But its not working like calling from on lambda function (like ALambdaHandler calling BLambdaHandler as a function call). Even its not returning any exception. Its just showing timeout, its got stuck at the code of: lambdaClient.invoke
注意:当我从普通的 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());
}
EDITI did everything as suggested by others and followed everything. At the end I reached to AWS support, and the problem was related to some VPC configurations stuff, and that got solved.If you have encountered similar stuff, then may be check security configs, VPC stuff.
编辑我按照其他人的建议做了一切并遵循了一切。最后我联系了AWS支持,问题与一些VPC配置的东西有关,并得到了解决。如果您遇到类似的东西,那么可能是检查安全配置,VPC的东西。
回答by Sandeep Sharma
We have achieved this by using com.amazonaws.services.lambda.model.InvokeRequest. Here is code sample.
我们通过使用 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);
}
}
回答by ?a?atay Gürtürk
- Make sure the role which your Lambda function executes with has
lambda:InvokeFunction
permission. - Then use AWS SDK to invoke the 2rd function. (Doc: http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/lambda/AWSLambdaClient.html#invoke(com.amazonaws.services.lambda.model.InvokeRequest))
- 确保您的 Lambda 函数执行的角色具有
lambda:InvokeFunction
权限。 - 然后使用 AWS SDK 调用第二个函数。(文档:http: //docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/lambda/AWSLambdaClient.html#invoke(com.amazonaws.services.lambda.model.InvokeRequest ))
Edit: For such a scenario, consider using Step Functions.
编辑:对于这种情况,请考虑使用Step Functions。
回答by Chandrashekhar Tupe
We had similar problem and tried to gather various implementations to achieve this. Turns out it had nothing to do with the code.
我们遇到了类似的问题,并试图收集各种实现来实现这一点。原来它与代码无关。
Few basic rules:
几个基本规则:
- Ensure proper policy and role for your lambda function, at minimum:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:::" }, { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "" ] } ] }
Have functions in same regions.
No VPC configurations needed. If your applications have VPC, make sure your lambda function has appropriate role policy (refer AWSLambdaVPCAccessExecutionRole)
Most important (primarily why it was failing for us), set right timeouts and heap sizes. Calling Lambda is going to wait until called one is finished. Simple math of 2x the called lambda values works. Also this was only with java lambda function calling another java lambda function. With node js lambda function calling another lambda function did not have this issue.
- 至少确保您的 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": [ "" ] } ] }
具有相同区域的功能。
无需 VPC 配置。如果您的应用程序具有 VPC,请确保您的 lambda 函数具有适当的角色策略(请参阅 AWSLambdaVPCAccessExecutionRole)
最重要的(主要是为什么它对我们来说失败了),设置正确的超时和堆大小。调用 Lambda 将等到被调用者完成。2 倍被调用的 lambda 值的简单数学运算有效。此外,这仅适用于调用另一个 java lambda 函数的 java lambda 函数。节点 js lambda 函数调用另一个 lambda 函数没有这个问题。
Following are some implementations that works for us:
以下是一些对我们有用的实现:
- Using service interface
- 使用服务接口
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);
}
- Using invoker
- 使用调用程序
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 should be created from builder.
AWSLambdaClient 应该从构建器创建。