在上一篇文章中,我们实现了基于Java的aws lambda函数,并使用CloudFront进行了部署。 由于我们已经设置了lambda函数,因此我们将使用AWS API Gateway将其与http端点集成。
Amazon API Gateway是一项完全托管的服务,使开发人员可以轻松地创建,发布,维护,监控和保护各种规模的API。 在AWS管理控制台中单击几下,您可以创建一个API,充当应用程序从后端服务访问数据,业务逻辑或功能(例如在Amazon Elastic Compute Cloud上运行的工作负载)的“前门”。 (Amazon EC2),在AWS Lambda或任何Web应用程序上运行的代码
对于此示例,将API网关想象为一个HTTP连接器。 我们将更改原始功能以实现划分。
package com.gkatzioura.deployment.lambda;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.math.BigDecimal;
import java.util.Map;
import java.util.logging.Logger;
/**
* Created by gkatzioura on 9/10/2016.
*/
public class RequestFunctionHandler implements RequestHandler<Map<String,String>,String> {
private static final String NUMERATOR_KEY = "numerator";
private static final String DENOMINATOR_KEY = "denominator";
private static final Logger LOGGER = Logger.getLogger(RequestFunctionHandler.class.getName());
public String handleRequest(Map <String,String> values, Context context) {
LOGGER.info("Handling request");
if(!values.containsKey(NUMERATOR_KEY)||!values.containsKey(DENOMINATOR_KEY)) {
return "You need both numberator and denominator";
}
try {
BigDecimal numerator = new BigDecimal(values.get(NUMERATOR_KEY));
BigDecimal denominator= new BigDecimal(values.get(DENOMINATOR_KEY));
return numerator.divide(denominator).toString();
} catch (Exception e) {
return "Please provide valid values";
}
}
}
然后,我们将更改lambda代码并在s3上对其进行更新。
aws s3 cp build/distributions/JavaLambdaDeployment.zip s3://lambda-functions/JavaLambdaDeployment.zip
下一步是更新我们的CloudFormation模板,并将api网关转发请求添加到我们的lambda函数。
首先,我们必须声明我们的Rest API
"AGRA16PAA": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {"Name": "CalculationApi"}
}
然后,我们需要添加一个休息资源。 在DependsOn元素内,我们可以看到rest api的ID。 因此,cloudwatch将在创建其余api后创建资源。
"AGR2JDQ8": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {"Ref": "AGRA16PAA"},
"ParentId": {
"Fn::GetAtt": ["AGRA16PAA","RootResourceId"]
},
"PathPart": "divide"
},
"DependsOn": [
"AGRA16PAA"
]
}
另一个关键部分是添加权限,以便能够调用我们的lambda函数。
"LPI6K5": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"FunctionName": {"Fn::GetAtt": ["LF9MBL", "Arn"]},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {"Fn::Join": ["",
["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "AGRA16PAA"}, "/*"]
]}
}
}
最后一步是添加api网关方法,以便能够从api网关调用我们的lambda函数。 此外,我们将添加api网关部署说明。
"Deployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": { "Ref": "AGRA16PAA" },
"Description": "First Deployment",
"StageName": "StagingStage"
},
"DependsOn" : ["AGM25KFD"]
},
"AGM25KFD": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"AuthorizationType": "NONE",
"HttpMethod": "POST",
"ResourceId": {"Ref": "AGR2JDQ8"},
"RestApiId": {"Ref": "AGRA16PAA"},
"Integration": {
"Type": "AWS",
"IntegrationHttpMethod": "POST",
"IntegrationResponses": [{"StatusCode": 200}],
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{"Ref": "AWS::Region"},
":lambda:path/2015-03-31/functions/",
{"Fn::GetAtt": ["LF9MBL", "Arn"]},
"/invocations"
]
]
}
},
"MethodResponses": [{
"StatusCode": 200
}]
}
因此,我们最终获得了新的cloudwatch配置。
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"LF9MBL": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "lambda-functions",
"S3Key": "JavaLambdaDeployment.zip"
},
"FunctionName": "SimpleRequest",
"Handler": "com.gkatzioura.deployment.lambda.RequestFunctionHandler",
"MemorySize": 128,
"Role": "arn:aws:iam::274402012893:role/lambda_basic_execution",
"Runtime": "java8"
}
},
"Deployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": { "Ref": "AGRA16PAA" },
"Description": "First Deployment",
"StageName": "StagingStage"
},
"DependsOn" : ["AGM25KFD"]
},
"AGM25KFD": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"AuthorizationType": "NONE",
"HttpMethod": "POST",
"ResourceId": {"Ref": "AGR2JDQ8"},
"RestApiId": {"Ref": "AGRA16PAA"},
"Integration": {
"Type": "AWS",
"IntegrationHttpMethod": "POST",
"IntegrationResponses": [{"StatusCode": 200}],
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{"Ref": "AWS::Region"},
":lambda:path/2015-03-31/functions/",
{"Fn::GetAtt": ["LF9MBL","Arn"]},
"/invocations"
]
]
}
},
"MethodResponses": [{"StatusCode": 200}]
},
"DependsOn": ["LF9MBL","AGR2JDQ8","LPI6K5"]
},
"AGR2JDQ8": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {"Ref": "AGRA16PAA"},
"ParentId": {
"Fn::GetAtt": ["AGRA16PAA","RootResourceId"]
},
"PathPart": "divide"
},
"DependsOn": ["AGRA16PAA"]
},
"AGRA16PAA": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "CalculationApi"
}
},
"LPI6K5": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"FunctionName": {"Fn::GetAtt": ["LF9MBL", "Arn"]},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {"Fn::Join": ["",
["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "AGRA16PAA"}, "/*"]
]}
}
}
}
}
最后但并非最不重要的一点是,我们必须更新以前的cloudformation堆栈。
所以我们上传了我们最新的模板
aws s3 cp cloudformationjavalambda2.template s3://cloudformation-templates/cloudformationjavalambda2.template
我们要做的就是更新堆栈。
aws cloudformation update-stack --stack-name JavaLambdaStack --template-url https://s3.amazonaws.com/cloudformation-templates/cloudformationjavalambda2.template
我们的堆栈刚刚更新。
我们可以到达我们的api网关端点并尝试发布帖子。
curl -H "Content-Type: application/json" -X POST -d '{"numerator":1,"denominator":"2"}' https://{you api gateway endpoint}/StagingStage/divide
"0.5"
您可以在github上找到源代码。
翻译自: https://www.javacodegeeks.com/2016/10/java-aws-cloud-using-lambda-api-gateway-cloudformation.html