Skip to content

Commit c916e66

Browse files
authored
Release 1.64.0 (to main) #3093
Release 1.64.0 (to main)
2 parents 1e29fc8 + c9244ae commit c916e66

File tree

55 files changed

+7161
-282
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+7161
-282
lines changed

.cfnlintrc.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ ignore_templates:
121121
- tests/translator/output/**/globals_for_function.json # RuntimeManagementConfig
122122
- tests/translator/output/**/function_with_runtime_config.json # RuntimeManagementConfig
123123
- tests/translator/output/**/managed_policies_minimal.json # Intentionally has non-existent managed policy name
124+
- tests/translator/output/**/function_with_mq.json # Property "EventSourceArn" can Fn::GetAtt to a resource of types [AWS::DynamoDB::GlobalTable, AWS::DynamoDB::Table, AWS::Kinesis::Stream, AWS::Kinesis::StreamConsumer, AWS::SQS::Queue]
124125
ignore_checks:
125126
- E2531 # Deprecated runtime; not relevant for transform tests
126127
- W2531 # EOL runtime; not relevant for transform tests

DEVELOPMENT_GUIDE.md

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Integration tests are covered in detail in the [INTEGRATION_TESTS.md file](INTEG
168168
For new properties of SAM resources, use [`Property`](https://github.com/aws/serverless-application-model/blob/c5830b63857f52e540fec13b29f029458edc539a/samtranslator/model/__init__.py#L36-L45) or [`PassThroughProperty`](https://github.com/aws/serverless-application-model/blob/dd79f535500158baa8e367f081d6a12113497e45/samtranslator/model/__init__.py#L48-L56) instead of [`PropertyType`](https://github.com/aws/serverless-application-model/blob/c39c2807bbf327255de8abed8b8150b18c60f053/samtranslator/model/__init__.py#L13-L33). This avoids [sneaky bugs](https://github.com/aws/serverless-application-model/pull/2495#discussion_r976715242) and ensures valid templates do not cause transform failures.
169169

170170
For new properties of CloudFormation resources, use [`GeneratedProperty`](https://github.com/aws/serverless-application-model/blob/79452f69bc1fcf918b8625c2f9005c74ab874801/samtranslator/model/__init__.py#L74-L82). It performs no runtime validation, reducing the risk of valid values causing transform failures.
171+
7. **Write all new code under [`samtranslator/internal`](https://github.com/aws/serverless-application-model/tree/develop/samtranslator/internal) if possible.** This ensures we don't increase our "public" library interface and cause unnecessary breakages to consumers. While Python doesn't have private access modifiers, we assume anything [by convention private](https://peps.python.org/pep-0008/#descriptive-naming-styles) or under `internal` to be internal code, not bound by typical expectations of backward compatibility.
171172

172173
Code conventions
173174
----------------

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ test-fast:
1212
pytest -x --cov samtranslator --cov-report term-missing --cov-fail-under 95 -n auto tests/
1313

1414
test-cov-report:
15-
pytest --cov samtranslator --cov-report term-missing --cov-report html --cov-fail-under 95 tests/
15+
pytest --cov samtranslator --cov-report term-missing --cov-report html --cov-fail-under 95 -n auto tests/
16+
open htmlcov/index.html &> /dev/null || true
1617

1718
integ-test:
1819
pytest --no-cov integration/

integration/combination/test_connectors.py

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def tearDown(self):
2626

2727
@parameterized.expand(
2828
[
29+
("combination/connector_appsync_to_lambda",),
2930
("combination/connector_appsync_to_table",),
3031
("combination/connector_function_to_function",),
3132
("combination/connector_restapi_to_function",),

integration/combination/test_function_with_mq.py

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ def companion_stack_outputs(self, get_companion_stack_outputs):
2626
]
2727
)
2828
def test_function_with_mq(self, file_name, mq_broker, mq_secret, subnet_key):
29+
# Temporarily skip this test and we should either re-enable this once the AZ issue is fixed
30+
# or once we figure out a way to trigger integ test only when transform output changes.
31+
if subnet_key == "PreCreatedSubnetOne":
32+
pytest.skip("Skipping this test to temporarily bypass AvailabilityZone issue.")
2933
companion_stack_outputs = self.companion_stack_outputs
3034
parameters = self.get_parameters(companion_stack_outputs, subnet_key)
3135
secret_name = mq_secret + "-" + generate_suffix()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[
2+
{
3+
"LogicalResourceId": "HelloLambda",
4+
"ResourceType": "AWS::Lambda::Function"
5+
},
6+
{
7+
"LogicalResourceId": "HelloLambdaRole",
8+
"ResourceType": "AWS::IAM::Role"
9+
},
10+
{
11+
"LogicalResourceId": "AppSyncApi",
12+
"ResourceType": "AWS::AppSync::GraphQLApi"
13+
},
14+
{
15+
"LogicalResourceId": "ApiKey",
16+
"ResourceType": "AWS::AppSync::ApiKey"
17+
},
18+
{
19+
"LogicalResourceId": "ApiSchema",
20+
"ResourceType": "AWS::AppSync::GraphQLSchema"
21+
},
22+
{
23+
"LogicalResourceId": "AppSyncLambdaDataSource",
24+
"ResourceType": "AWS::AppSync::DataSource"
25+
},
26+
{
27+
"LogicalResourceId": "TriggerFunction",
28+
"ResourceType": "AWS::Lambda::Function"
29+
},
30+
{
31+
"LogicalResourceId": "TriggerFunctionRole",
32+
"ResourceType": "AWS::IAM::Role"
33+
},
34+
{
35+
"LogicalResourceId": "AppSyncApiLambdaInvocationRole",
36+
"ResourceType": "AWS::IAM::Role"
37+
},
38+
{
39+
"LogicalResourceId": "DataSourceToLambdaConnectorPolicy",
40+
"ResourceType": "AWS::IAM::ManagedPolicy"
41+
},
42+
{
43+
"LogicalResourceId": "AppSyncSayHelloResolver",
44+
"ResourceType": "AWS::AppSync::Resolver"
45+
}
46+
]

integration/resources/expected/combination/connector_appsync_to_table.json

+8
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,13 @@
3434
{
3535
"LogicalResourceId": "DataSourceToTableConnectorPolicy",
3636
"ResourceType": "AWS::IAM::ManagedPolicy"
37+
},
38+
{
39+
"LogicalResourceId": "SaveNoteResolver",
40+
"ResourceType": "AWS::AppSync::Resolver"
41+
},
42+
{
43+
"LogicalResourceId": "GetNoteResolver",
44+
"ResourceType": "AWS::AppSync::Resolver"
3745
}
3846
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
Resources:
2+
AppSyncApiLambdaInvocationRole:
3+
Type: AWS::IAM::Role
4+
Properties:
5+
AssumeRolePolicyDocument:
6+
Version: '2012-10-17'
7+
Statement:
8+
- Effect: Allow
9+
Principal:
10+
Service: appsync.amazonaws.com
11+
Action:
12+
- sts:AssumeRole
13+
14+
HelloLambda:
15+
Type: AWS::Serverless::Function
16+
Properties:
17+
InlineCode: |
18+
exports.handler = async (_) => {
19+
return "Hello World"
20+
}
21+
Handler: index.handler
22+
Runtime: nodejs14.x
23+
24+
AppSyncApi:
25+
Type: AWS::AppSync::GraphQLApi
26+
Properties:
27+
AuthenticationType: API_KEY
28+
Name: AppSyncApi
29+
30+
ApiSchema:
31+
Type: AWS::AppSync::GraphQLSchema
32+
Properties:
33+
ApiId: !GetAtt AppSyncApi.ApiId
34+
Definition: |
35+
type Query {
36+
sayHello: String!
37+
}
38+
schema {
39+
query: Query
40+
}
41+
42+
AppSyncLambdaDataSource:
43+
Type: AWS::AppSync::DataSource
44+
Properties:
45+
ApiId: !GetAtt AppSyncApi.ApiId
46+
Name: AppSyncLambdaDataSource
47+
Type: AWS_LAMBDA
48+
ServiceRoleArn: !GetAtt AppSyncApiLambdaInvocationRole.Arn
49+
LambdaConfig:
50+
LambdaFunctionArn: !GetAtt HelloLambda.Arn
51+
52+
AppSyncSayHelloResolver:
53+
DependsOn: ApiSchema
54+
Type: AWS::AppSync::Resolver
55+
Properties:
56+
ApiId: !GetAtt AppSyncApi.ApiId
57+
TypeName: Query
58+
FieldName: sayHello
59+
DataSourceName: !GetAtt AppSyncLambdaDataSource.Name
60+
RequestMappingTemplate: |
61+
{
62+
"version" : "2017-02-28",
63+
"operation": "Invoke",
64+
"payload": $util.toJson($context.args)
65+
}
66+
ResponseMappingTemplate: |
67+
$util.toJson($context.result)
68+
69+
DataSourceToLambdaConnector:
70+
Type: AWS::Serverless::Connector
71+
Properties:
72+
Source:
73+
Id: AppSyncLambdaDataSource
74+
Destination:
75+
Id: HelloLambda
76+
Permissions:
77+
- Write
78+
79+
ApiKey:
80+
Type: AWS::AppSync::ApiKey
81+
Properties:
82+
ApiId: !GetAtt AppSyncApi.ApiId
83+
84+
TriggerFunction:
85+
Type: AWS::Serverless::Function
86+
Properties:
87+
Environment:
88+
Variables:
89+
API_KEY: !GetAtt ApiKey.ApiKey
90+
GRAPHQL_URL: !GetAtt AppSyncApi.GraphQLUrl
91+
Runtime: nodejs14.x
92+
Handler: index.handler
93+
InlineCode: |
94+
const https = require("https");
95+
96+
exports.handler = async (_) => {
97+
const queries = {
98+
sayHello: /* GraphQL */ `
99+
query {
100+
sayHello
101+
}
102+
`,
103+
};
104+
105+
106+
const fetch = async (url, options) =>
107+
new Promise((resolve, reject) => {
108+
const req = https.request(url, options, (res) => {
109+
const body = [];
110+
res.on("data", (chunk) => body.push(chunk));
111+
res.on("end", () => {
112+
const resString = Buffer.concat(body).toString();
113+
resolve(resString);
114+
});
115+
});
116+
117+
req.on("error", (err) => {
118+
reject(err);
119+
});
120+
121+
req.on("timeout", () => {
122+
req.destroy();
123+
reject(new Error("Request time out"));
124+
});
125+
126+
req.write(options.body);
127+
req.end();
128+
});
129+
130+
131+
const makeRequest = async (queryName) => {
132+
const options = {
133+
method: "POST",
134+
headers: {
135+
"x-api-key": process.env.API_KEY,
136+
},
137+
body: JSON.stringify({ query: queries[queryName] }),
138+
timeout: 10000, // ms
139+
};
140+
141+
const response = await fetch(process.env.GRAPHQL_URL, options);
142+
const body = JSON.parse(response);
143+
const data = body.data?.[queryName];
144+
145+
if (body.errors !== undefined) {
146+
throw JSON.stringify(body.errors);
147+
}
148+
149+
if (data !== "Hello World") {
150+
throw new Error(`${queryName} error: '${data}' must be 'Hello World'`);
151+
}
152+
153+
return body.data;
154+
};
155+
156+
157+
return await makeRequest("sayHello");
158+
};
159+
160+
161+
Metadata:
162+
SamTransformTest: true

0 commit comments

Comments
 (0)