Skip to content

Commit e174707

Browse files
authored
Merge branch 'master' into 7104-netcore-31-lambda
2 parents be8c7c7 + c97e63b commit e174707

39 files changed

+4656
-2697
lines changed

packages/@aws-cdk/app-delivery/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"@types/nodeunit": "^0.0.30",
5757
"cdk-build-tools": "0.0.0",
5858
"cdk-integ-tools": "0.0.0",
59-
"fast-check": "^1.22.2",
59+
"fast-check": "^1.24.0",
6060
"nodeunit": "^0.11.3",
6161
"pkglint": "0.0.0"
6262
},

packages/@aws-cdk/aws-apigateway/README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -297,18 +297,17 @@ const errorResponseModel = api.addModel('ErrorResponseModel', {
297297
And reference all on your method definition.
298298

299299
```ts
300-
// If you want to define parameter mappings for the request, you need a validator
301-
const validator = api.addRequestValidator('DefaultValidator', {
302-
validateRequestBody: false,
303-
validateRequestParameters: true
304-
});
305300
resource.addMethod('GET', integration, {
306301
// We can mark the parameters as required
307302
requestParameters: {
308303
'method.request.querystring.who': true
309304
},
310-
// We need to set the validator for ensuring they are passed
311-
requestValidator: validator,
305+
// we can set request validator options like below
306+
requestValidatorOptions: {
307+
requestValidatorName: 'test-validator',
308+
validateRequestBody: true,
309+
validateRequestParameters: false
310+
}
312311
methodResponses: [
313312
{
314313
// Successful response from the integration
@@ -340,6 +339,9 @@ resource.addMethod('GET', integration, {
340339
});
341340
```
342341

342+
Specifying `requestValidatorOptions` automatically creates the RequestValidator construct with the given options.
343+
However, if you have your RequestValidator already initialized or imported, use the `requestValidator` option instead.
344+
343345
#### Default Integration and Method Options
344346

345347
The `defaultIntegration` and `defaultMethodOptions` properties can be used to

packages/@aws-cdk/aws-apigateway/lib/method.ts

+25-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ConnectionType, Integration } from './integration';
55
import { MockIntegration } from './integrations/mock';
66
import { MethodResponse } from './methodresponse';
77
import { IModel } from './model';
8-
import { IRequestValidator } from './requestvalidator';
8+
import { IRequestValidator, RequestValidatorOptions } from './requestvalidator';
99
import { IResource } from './resource';
1010
import { RestApi } from './restapi';
1111
import { validateHttpMethod } from './util';
@@ -73,6 +73,8 @@ export interface MethodOptions {
7373

7474
/**
7575
* The ID of the associated request validator.
76+
* Only one of `requestValidator` or `requestValidatorOptions` must be specified.
77+
* @default - No default validator
7678
*/
7779
readonly requestValidator?: IRequestValidator;
7880

@@ -83,6 +85,13 @@ export interface MethodOptions {
8385
* @default - no authorization scopes
8486
*/
8587
readonly authorizationScopes?: string[]
88+
89+
/**
90+
* Request validator options to create new validator
91+
* Only one of `requestValidator` or `requestValidatorOptions` must be specified.
92+
* @default - No default validator
93+
*/
94+
readonly requestValidatorOptions?: RequestValidatorOptions;
8695
}
8796

8897
export interface MethodProps {
@@ -160,7 +169,7 @@ export class Method extends Resource {
160169
integration: this.renderIntegration(props.integration),
161170
methodResponses: this.renderMethodResponses(options.methodResponses),
162171
requestModels: this.renderRequestModels(options.requestModels),
163-
requestValidatorId: options.requestValidator ? options.requestValidator.requestValidatorId : undefined,
172+
requestValidatorId: this.requestValidatorId(options),
164173
authorizationScopes: options.authorizationScopes ?? defaultMethodOptions.authorizationScopes,
165174
};
166175

@@ -302,6 +311,20 @@ export class Method extends Resource {
302311

303312
return models;
304313
}
314+
315+
private requestValidatorId(options: MethodOptions): string | undefined {
316+
if (options.requestValidator && options.requestValidatorOptions) {
317+
throw new Error(`Only one of 'requestValidator' or 'requestValidatorOptions' must be specified.`);
318+
}
319+
320+
if (options.requestValidatorOptions) {
321+
const validator = this.restApi.addRequestValidator('validator', options.requestValidatorOptions);
322+
return validator.requestValidatorId;
323+
}
324+
325+
// For backward compatibility
326+
return options.requestValidator?.requestValidatorId;
327+
}
305328
}
306329

307330
export enum AuthorizationType {

packages/@aws-cdk/aws-apigateway/test/test.method.ts

+78
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,84 @@ export = {
802802
AuthorizationScopes: ABSENT
803803
}));
804804

805+
test.done();
806+
},
807+
808+
'method has a request validator with provided properties'(test: Test) {
809+
// GIVEN
810+
const stack = new cdk.Stack();
811+
const api = new apigw.RestApi(stack, 'test-api', { deploy: false });
812+
813+
// WHEN
814+
new apigw.Method(stack, 'method-man', {
815+
httpMethod: 'GET',
816+
resource: api.root,
817+
options: {
818+
requestValidatorOptions: {
819+
requestValidatorName: 'test-validator',
820+
validateRequestBody: true,
821+
validateRequestParameters: false
822+
}
823+
}
824+
});
825+
826+
// THEN
827+
expect(stack).to(haveResource('AWS::ApiGateway::RequestValidator', {
828+
RestApiId: stack.resolve(api.restApiId),
829+
ValidateRequestBody: true,
830+
ValidateRequestParameters: false,
831+
Name: 'test-validator'
832+
}));
833+
834+
test.done();
835+
},
836+
837+
'method does not have a request validator'(test: Test) {
838+
// GIVEN
839+
const stack = new cdk.Stack();
840+
const api = new apigw.RestApi(stack, 'test-api', { deploy: false });
841+
842+
// WHEN
843+
new apigw.Method(stack, 'method-man', {
844+
httpMethod: 'GET',
845+
resource: api.root
846+
});
847+
848+
// THEN
849+
expect(stack).to(haveResource('AWS::ApiGateway::Method', {
850+
RequestValidatorId: ABSENT
851+
}));
852+
853+
test.done();
854+
},
855+
856+
'method does not support both request validator and request validator options'(test: Test) {
857+
// GIVEN
858+
const stack = new cdk.Stack();
859+
const api = new apigw.RestApi(stack, 'test-api', { deploy: false });
860+
const validator = api.addRequestValidator('test-validator1', {
861+
validateRequestBody: true,
862+
validateRequestParameters: false
863+
});
864+
865+
// WHEN
866+
const methodProps = {
867+
httpMethod: 'GET',
868+
resource: api.root,
869+
options: {
870+
requestValidatorOptions: {
871+
requestValidatorName: 'test-validator2',
872+
validateRequestBody: true,
873+
validateRequestParameters: false
874+
},
875+
requestValidator: validator
876+
}
877+
};
878+
879+
// THEN
880+
test.throws(() => new apigw.Method(stack, 'method', methodProps),
881+
/Only one of 'requestValidator' or 'requestValidatorOptions' must be specified./);
882+
805883
test.done();
806884
}
807885
};

packages/@aws-cdk/aws-applicationautoscaling/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"@types/nodeunit": "^0.0.30",
6767
"cdk-build-tools": "0.0.0",
6868
"cfn2ts": "0.0.0",
69-
"fast-check": "^1.22.2",
69+
"fast-check": "^1.24.0",
7070
"nodeunit": "^0.11.3",
7171
"pkglint": "0.0.0"
7272
},

packages/@aws-cdk/aws-autoscaling-common/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"@types/nodeunit": "^0.0.30",
6363
"cdk-build-tools": "0.0.0",
6464
"cdk-integ-tools": "0.0.0",
65-
"fast-check": "^1.22.2",
65+
"fast-check": "^1.24.0",
6666
"nodeunit": "^0.11.3",
6767
"pkglint": "0.0.0"
6868
},

packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js

+29-17
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,24 @@ const requestCertificate = async function(requestId, domainName, subjectAlternat
9999

100100
console.log('Waiting for ACM to provide DNS records for validation...');
101101

102-
let record;
103-
for (let attempt = 0; attempt < maxAttempts && !record; attempt++) {
102+
let records;
103+
for (let attempt = 0; attempt < maxAttempts && !records; attempt++) {
104104
const { Certificate } = await acm.describeCertificate({
105105
CertificateArn: reqCertResponse.CertificateArn
106106
}).promise();
107107
const options = Certificate.DomainValidationOptions || [];
108-
109108
if (options.length > 0 && options[0].ResourceRecord) {
110-
record = options[0].ResourceRecord;
109+
// some alternative names will produce the same validation record
110+
// as the main domain (eg. example.com + *.example.com)
111+
// filtering duplicates to avoid errors with adding the same record
112+
// to the route53 zone twice
113+
const unique = options
114+
.map((val) => val.ResourceRecord)
115+
.reduce((acc, cur) => {
116+
acc[cur.Name] = cur;
117+
return acc;
118+
}, {});
119+
records = Object.keys(unique).sort().map(key => unique[key]);
111120
} else {
112121
// Exponential backoff with jitter based on 200ms base
113122
// component of backoff fixed to ensure minimum total wait time on
@@ -116,25 +125,28 @@ const requestCertificate = async function(requestId, domainName, subjectAlternat
116125
await sleep(random() * base * 50 + base * 150);
117126
}
118127
}
119-
if (!record) {
128+
if (!records) {
120129
throw new Error(`Response from describeCertificate did not contain DomainValidationOptions after ${maxAttempts} attempts.`)
121130
}
122131

123-
console.log(`Upserting DNS record into zone ${hostedZoneId}: ${record.Name} ${record.Type} ${record.Value}`);
132+
console.log(`Upserting ${records.length} DNS records into zone ${hostedZoneId}:`);
124133

125134
const changeBatch = await route53.changeResourceRecordSets({
126135
ChangeBatch: {
127-
Changes: [{
128-
Action: 'UPSERT',
129-
ResourceRecordSet: {
130-
Name: record.Name,
131-
Type: record.Type,
132-
TTL: 60,
133-
ResourceRecords: [{
134-
Value: record.Value
135-
}]
136-
}
137-
}]
136+
Changes: records.map((record) => {
137+
console.log(`${record.Name} ${record.Type} ${record.Value}`)
138+
return {
139+
Action: 'UPSERT',
140+
ResourceRecordSet: {
141+
Name: record.Name,
142+
Type: record.Type,
143+
TTL: 60,
144+
ResourceRecords: [{
145+
Value: record.Value
146+
}]
147+
}
148+
};
149+
}),
138150
},
139151
HostedZoneId: hostedZoneId
140152
}).promise();

0 commit comments

Comments
 (0)