Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add TimeoutInMillis Property to API Event Source #3310

Merged
merged 9 commits into from
Aug 18, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from unittest.case import skipIf

from integration.config.service_names import REST_API
from integration.helpers.base_test import BaseTest
from integration.helpers.resource import current_region_does_not_support


@skipIf(current_region_does_not_support([REST_API]), "REST API is not supported in this testing region")
class TestFunctionWithImplicitApiWithTimeout(BaseTest):
def test_function_with_implicit_api_with_timeout(self):
self.create_and_verify_stack("combination/function_with_implicit_api_with_timeout")
aaythapa marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[
{
"LogicalResourceId": "MyLambdaFunctionApiEventPermissionProd",
"ResourceType": "AWS::Lambda::Permission"
},
{
"LogicalResourceId": "MyLambdaFunctionRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "MyLambdaFunction",
"ResourceType": "AWS::Lambda::Function"
},
{
"LogicalResourceId": "MyOtherLambdaFunctionApiEventPermissionProd",
"ResourceType": "AWS::Lambda::Permission"
},
{
"LogicalResourceId": "MyOtherLambdaFunctionRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "MyOtherLambdaFunction",
"ResourceType": "AWS::Lambda::Function"
},
{
"LogicalResourceId": "ServerlessRestApiDeployment",
"ResourceType": "AWS::ApiGateway::Deployment"
},
{
"LogicalResourceId": "ServerlessRestApiProdStage",
"ResourceType": "AWS::ApiGateway::Stage"
},
{
"LogicalResourceId": "ServerlessRestApi",
"ResourceType": "AWS::ApiGateway::RestApi"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: A template to test timeout support for implicit APIs.

Resources:
MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs16.x
MemorySize: 128
Timeout: 3
InlineCode: |
exports.handler = async () => ‘Hello World!'
Events:
ApiEvent:
Type: Api
Properties:
Path: /sub
Method: get
TimeoutInMillis: 5000
MyOtherLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs16.x
MemorySize: 128
Timeout: 3
InlineCode: |
exports.handler = async () => ‘Hello World!'
Events:
ApiEvent:
Type: Api
Properties:
Path: /sub
Method: post
TimeoutInMillis: 8000
Metadata:
SamTransformTest: true
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ class ApiEventProperties(BaseModel):
RequestModel: Optional[RequestModel] = apieventproperties("RequestModel")
RequestParameters: Optional[RequestModelProperty] = apieventproperties("RequestParameters")
RestApiId: Optional[Union[str, Ref]] = apieventproperties("RestApiId")
TimeoutInMillis: Optional[SamIntrinsicable[int]] # TODO: add doc
aaythapa marked this conversation as resolved.
Show resolved Hide resolved


class ApiEvent(BaseModel):
Expand Down
18 changes: 18 additions & 0 deletions samtranslator/model/eventsources/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ class Api(PushEventSource):
"Auth": PropertyType(False, IS_DICT),
"RequestModel": PropertyType(False, IS_DICT),
"RequestParameters": PropertyType(False, IS_LIST),
"TimeoutInMillis": PropertyType(False, IS_INT),
}

Path: str
Expand All @@ -666,6 +667,7 @@ class Api(PushEventSource):
Auth: Optional[Dict[str, Any]]
RequestModel: Optional[Dict[str, Any]]
RequestParameters: Optional[List[Any]]
TimeoutInMillis: Optional[PassThrough]

def resources_to_link(self, resources: Dict[str, Any]) -> Dict[str, Any]:
"""
Expand Down Expand Up @@ -829,6 +831,8 @@ def _add_swagger_integration( # type: ignore[no-untyped-def] # noqa: PLR0912, P
self.add_auth_to_swagger(
self.Auth, api, api_id, self.relative_id, self.Method, self.Path, stage, editor, intrinsics_resolver
)
if self.TimeoutInMillis:
self.add_timeout_to_swagger(self.Path, self.Method, self.TimeoutInMillis, editor)
aaythapa marked this conversation as resolved.
Show resolved Hide resolved

if self.RequestModel:
sam_expect(self.RequestModel, self.relative_id, "RequestModel", is_sam_event=True).to_be_a_map()
Expand Down Expand Up @@ -1072,6 +1076,20 @@ def add_auth_to_swagger( # noqa: PLR0912, PLR0913
if resource_policy.get("CustomStatements"):
editor.add_custom_statements(resource_policy.get("CustomStatements")) # type: ignore[no-untyped-call]

@staticmethod
def add_timeout_to_swagger(path: str, method_name: str, timeout: int, editor: SwaggerEditor) -> None:
"""
Adds a timeout to this path/method.

:param path: string of path name
:param method_name: string of method name
:param timeout: int of timeout duration in milliseconds
:param editor: SwaggerEditor object

"""
for method_definition in editor.iter_on_method_definitions_for_path_at_method(path, method_name):
method_definition[editor._X_APIGW_INTEGRATION]["timeoutInMillis"] = timeout
aaythapa marked this conversation as resolved.
Show resolved Hide resolved


class AlexaSkill(PushEventSource):
resource_type = "AlexaSkill"
Expand Down
11 changes: 11 additions & 0 deletions samtranslator/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -248171,6 +248171,17 @@
],
"markdownDescription": "Identifier of a RestApi resource, which must contain an operation with the given path and method\\. Typically, this is set to reference an [AWS::Serverless::Api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html) resource defined in this template\\. \nIf you don't define this property, AWS SAM creates a default [AWS::Serverless::Api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html) resource using a generated `OpenApi` document\\. That resource contains a union of all paths and methods defined by `Api` events in the same template that do not specify a `RestApiId`\\. \nThis cannot reference an [AWS::Serverless::Api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html) resource defined in another template\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
"title": "RestApiId"
},
"TimeoutInMillis": {
"anyOf": [
{
"type": "object"
},
{
"type": "integer"
}
],
"title": "Timeoutinmillis"
}
},
"required": [
Expand Down
11 changes: 11 additions & 0 deletions schema_source/sam.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4896,6 +4896,17 @@
],
"markdownDescription": "Identifier of a RestApi resource, which must contain an operation with the given path and method\\. Typically, this is set to reference an [AWS::Serverless::Api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html) resource defined in this template\\. \nIf you don't define this property, AWS SAM creates a default [AWS::Serverless::Api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html) resource using a generated `OpenApi` document\\. That resource contains a union of all paths and methods defined by `Api` events in the same template that do not specify a `RestApiId`\\. \nThis cannot reference an [AWS::Serverless::Api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html) resource defined in another template\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
"title": "RestApiId"
},
"TimeoutInMillis": {
"anyOf": [
{
"type": "object"
},
{
"type": "integer"
}
],
"title": "Timeoutinmillis"
}
},
"required": [
Expand Down
41 changes: 41 additions & 0 deletions tests/translator/input/implicit_api_with_timeout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Resources:
RestApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/todo_list.zip
Handler: index.restapi
Runtime: nodejs12.x
gracelu0 marked this conversation as resolved.
Show resolved Hide resolved
Policies: AmazonDynamoDBFullAccess
Events:
AddItem:
Type: Api
Properties:
Path: /add
Method: post
TimeoutInMillis: 5000
CompleteItem:
Type: Api
Properties:
Path: /complete
Method: POST
TimeoutInMillis: 5000
GetList:
Type: Api
Properties:
Path: /getlist
Method: get
TimeoutInMillis: 10000

GetHtmlFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/todo_list.zip
Handler: index.gethtml
Runtime: nodejs12.x
Policies: AmazonDynamoDBReadOnlyAccess
Events:
GetHtml:
Type: Api
Properties:
Path: /{proxy+}
Method: any
aaythapa marked this conversation as resolved.
Show resolved Hide resolved
Loading