-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into sagemaker-l2
- Loading branch information
Showing
5 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
packages/@aws-cdk/aws-apigateway/lib/rate-limited-api-key.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { Construct, Resource } from '@aws-cdk/core'; | ||
import { ApiKey, ApiKeyProps, IApiKey } from './api-key'; | ||
import { QuotaSettings, ThrottleSettings, UsagePlan, UsagePlanPerApiStage } from './usage-plan'; | ||
|
||
/** | ||
* RateLimitedApiKey properties. | ||
*/ | ||
export interface RateLimitedApiKeyProps extends ApiKeyProps { | ||
/** | ||
* API Stages to be associated with the RateLimitedApiKey. | ||
* @default none | ||
*/ | ||
readonly apiStages?: UsagePlanPerApiStage[]; | ||
|
||
/** | ||
* Number of requests clients can make in a given time period. | ||
* @default none | ||
*/ | ||
readonly quota?: QuotaSettings; | ||
|
||
/** | ||
* Overall throttle settings for the API. | ||
* @default none | ||
*/ | ||
readonly throttle?: ThrottleSettings; | ||
} | ||
|
||
/** | ||
* An API Gateway ApiKey, for which a rate limiting configuration can be specified. | ||
* | ||
* @resource AWS::ApiGateway::ApiKey | ||
*/ | ||
export class RateLimitedApiKey extends Resource implements IApiKey { | ||
public readonly keyId: string; | ||
|
||
constructor(scope: Construct, id: string, props: RateLimitedApiKeyProps = { }) { | ||
super(scope, id, { | ||
physicalName: props.apiKeyName, | ||
}); | ||
|
||
const resource = new ApiKey(this, 'Resource', props); | ||
|
||
if (props.apiStages || props.quota || props.throttle) { | ||
new UsagePlan(this, 'UsagePlanResource', { | ||
apiKey: resource, | ||
apiStages: props.apiStages, | ||
quota: props.quota, | ||
throttle: props.throttle | ||
}); | ||
} | ||
|
||
this.keyId = resource.keyId; | ||
} | ||
} |
108 changes: 108 additions & 0 deletions
108
packages/@aws-cdk/aws-apigateway/test/test.rate-limited-api-key.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { expect, haveResource, ResourcePart } from '@aws-cdk/assert'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import { Test } from "nodeunit"; | ||
import * as apigateway from '../lib'; | ||
|
||
const API_KEY_RESOURCE_TYPE = 'AWS::ApiGateway::ApiKey'; | ||
const USAGE_PLAN_RESOURCE_TYPE = 'AWS::ApiGateway::UsagePlan'; | ||
const USAGE_PLAN_KEY_RESOURCE_TYPE = 'AWS::ApiGateway::UsagePlanKey'; | ||
|
||
export = { | ||
'default setup'(test: Test) { | ||
// GIVEN | ||
const stack = new cdk.Stack(); | ||
const api = new apigateway.RestApi(stack, 'my-api', { cloudWatchRole: false, deploy: false }); | ||
api.root.addMethod('GET'); // Need at least one method on the api | ||
|
||
// WHEN | ||
new apigateway.RateLimitedApiKey(stack, 'my-api-key'); | ||
|
||
// THEN | ||
// should have an api key with no props defined. | ||
expect(stack).to(haveResource(API_KEY_RESOURCE_TYPE, undefined, ResourcePart.CompleteDefinition)); | ||
// should not have a usage plan. | ||
expect(stack).notTo(haveResource(USAGE_PLAN_RESOURCE_TYPE)); | ||
// should not have a usage plan key. | ||
expect(stack).notTo(haveResource(USAGE_PLAN_KEY_RESOURCE_TYPE)); | ||
|
||
test.done(); | ||
}, | ||
|
||
'only api key is created when rate limiting properties are not provided'(test: Test) { | ||
// GIVEN | ||
const stack = new cdk.Stack(); | ||
const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: true, deployOptions: { stageName: 'test' } }); | ||
api.root.addMethod('GET'); // api must have atleast one method. | ||
|
||
// WHEN | ||
new apigateway.RateLimitedApiKey(stack, 'test-api-key', { | ||
customerId: 'test-customer', | ||
resources: [api] | ||
}); | ||
|
||
// THEN | ||
expect(stack).to(haveResource('AWS::ApiGateway::ApiKey', { | ||
CustomerId: 'test-customer', | ||
StageKeys: [ | ||
{ | ||
RestApiId: { Ref: "testapiD6451F70" }, | ||
StageName: { Ref: "testapiDeploymentStagetest5869DF71" } | ||
} | ||
] | ||
})); | ||
// should not have a usage plan. | ||
expect(stack).notTo(haveResource(USAGE_PLAN_RESOURCE_TYPE)); | ||
// should not have a usage plan key. | ||
expect(stack).notTo(haveResource(USAGE_PLAN_KEY_RESOURCE_TYPE)); | ||
|
||
test.done(); | ||
}, | ||
|
||
'api key and usage plan are created and linked when rate limiting properties are provided'(test: Test) { | ||
// GIVEN | ||
const stack = new cdk.Stack(); | ||
const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: true, deployOptions: { stageName: 'test' } }); | ||
api.root.addMethod('GET'); // api must have atleast one method. | ||
|
||
// WHEN | ||
new apigateway.RateLimitedApiKey(stack, 'test-api-key', { | ||
customerId: 'test-customer', | ||
resources: [api], | ||
quota: { | ||
limit: 10000, | ||
period: apigateway.Period.MONTH | ||
} | ||
}); | ||
|
||
// THEN | ||
// should have an api key | ||
expect(stack).to(haveResource('AWS::ApiGateway::ApiKey', { | ||
CustomerId: 'test-customer', | ||
StageKeys: [ | ||
{ | ||
RestApiId: { Ref: "testapiD6451F70" }, | ||
StageName: { Ref: "testapiDeploymentStagetest5869DF71" } | ||
} | ||
] | ||
})); | ||
// should have a usage plan with specified quota. | ||
expect(stack).to(haveResource(USAGE_PLAN_RESOURCE_TYPE, { | ||
Quota: { | ||
Limit: 10000, | ||
Period: 'MONTH' | ||
} | ||
}, ResourcePart.Properties)); | ||
// should have a usage plan key linking the api key and usage plan | ||
expect(stack).to(haveResource(USAGE_PLAN_KEY_RESOURCE_TYPE, { | ||
KeyId: { | ||
Ref: 'testapikey998028B6' | ||
}, | ||
KeyType: 'API_KEY', | ||
UsagePlanId: { | ||
Ref: 'testapikeyUsagePlanResource66DB63D6' | ||
} | ||
}, ResourcePart.Properties)); | ||
|
||
test.done(); | ||
} | ||
}; |