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

refactor: convert "import" to "from" methods #2456

Merged
merged 13 commits into from
May 6, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ function createSelfUpdatingStack(pipelineStack: cdk.Stack): SelfUpdatingPipeline
});

// simple source
const bucket = s3.Bucket.import( pipeline, 'PatternBucket', { bucketArn: 'arn:aws:s3:::totally-fake-bucket' });
const bucket = s3.Bucket.fromBucketArn( pipeline, 'PatternBucket', 'arn:aws:s3:::totally-fake-bucket');
const sourceOutput = new codepipeline.Artifact('SourceOutput');
const sourceAction = new cpactions.S3SourceAction({
actionName: 'S3Source',
Expand Down
4 changes: 1 addition & 3 deletions packages/@aws-cdk/assets/lib/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@ export class Asset extends cdk.Construct {
const s3Filename = cdk.Fn.select(1, cdk.Fn.split(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.stringValue)).toString();
this.s3ObjectKey = `${this.s3Prefix}${s3Filename}`;

this.bucket = s3.Bucket.import(this, 'AssetBucket', {
bucketName: this.s3BucketName
});
this.bucket = s3.Bucket.fromBucketName(this, 'AssetBucket', this.s3BucketName);

// form the s3 URL of the object key
this.s3Url = this.bucket.urlForObject(this.s3ObjectKey);
Expand Down
23 changes: 14 additions & 9 deletions packages/@aws-cdk/aws-apigateway/lib/restapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Method, MethodOptions } from './method';
import { IRestApiResource, ResourceBase, ResourceOptions } from './resource';
import { Stage, StageOptions } from './stage';

export interface RestApiImportProps {
export interface RestApiAttributes {
/**
* The REST API ID of an existing REST API resource.
*/
Expand All @@ -34,7 +34,7 @@ export interface IRestApi extends IResource {
* Exports a REST API resource from this stack.
* @returns REST API props that can be imported to another stack.
*/
export(): RestApiImportProps;
export(): RestApiAttributes;
}

export interface RestApiProps extends ResourceOptions {
Expand Down Expand Up @@ -165,20 +165,25 @@ export interface RestApiProps extends ResourceOptions {
* public endpoint.
*/
export class RestApi extends Resource implements IRestApi {

public static fromRestApiId(scope: Construct, id: string, restApiId: string): IRestApi {
return RestApi.fromRestApiAttributes(scope, id, { restApiId });
}

/**
* Imports an existing REST API resource.
* @param scope Parent construct
* @param id Construct ID
* @param props Imported rest API properties
* @param attrs Imported rest API properties
*/
public static import(scope: Construct, id: string, props: RestApiImportProps): IRestApi {
public static fromRestApiAttributes(scope: Construct, id: string, attrs: RestApiAttributes): IRestApi {
class Import extends Construct implements IRestApi {
public restApiId = props.restApiId;
public restApiId = attrs.restApiId;
public get restApiRootResourceId() {
if (!props.restApiRootResourceId) { throw new Error(`Imported REST API does not have "restApiRootResourceId"`); }
return props.restApiRootResourceId;
if (!attrs.restApiRootResourceId) { throw new Error(`Imported REST API does not have "restApiRootResourceId"`); }
return attrs.restApiRootResourceId;
}
public export() { return props; }
public export() { return attrs; }
}

return new Import(scope, id);
Expand Down Expand Up @@ -252,7 +257,7 @@ export class RestApi extends Resource implements IRestApi {
* Exports a REST API resource from this stack.
* @returns REST API props that can be imported to another stack.
*/
public export(): RestApiImportProps {
public export(): RestApiAttributes {
return {
restApiId: new CfnOutput(this, 'RestApiId', { value: this.restApiId }).makeImportValue().toString()
};
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-apigateway/test/test.restapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ export = {
const stack = new cdk.Stack();

// WHEN
const imported = apigateway.RestApi.import(stack, 'imported-api', {
const imported = apigateway.RestApi.fromRestApiAttributes(stack, 'imported-api', {
restApiId: 'api-rxt4498f'
});

Expand Down Expand Up @@ -493,7 +493,7 @@ export = {
'"cloneFrom" can be used to clone an existing API'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const cloneFrom = apigateway.RestApi.import(stack, 'RestApi', {
const cloneFrom = apigateway.RestApi.fromRestApiAttributes(stack, 'RestApi', {
restApiId: 'foobar'
});

Expand Down
221 changes: 119 additions & 102 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,111 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps {
readonly role?: iam.IRole;
}

abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGroup {

public abstract autoScalingGroupName: string;
protected albTargetGroup?: elbv2.ApplicationTargetGroup;

/**
* Send a message to either an SQS queue or SNS topic when instances launch or terminate
*/
public onLifecycleTransition(id: string, props: BasicLifecycleHookProps): LifecycleHook {
return new LifecycleHook(this, `LifecycleHook${id}`, {
autoScalingGroup: this,
...props
});
}

/**
* Scale out or in based on time
*/
public scaleOnSchedule(id: string, props: BasicScheduledActionProps): ScheduledAction {
return new ScheduledAction(this, `ScheduledAction${id}`, {
autoScalingGroup: this,
...props,
});
}

/**
* Scale out or in to achieve a target CPU utilization
*/
public scaleOnCpuUtilization(id: string, props: CpuUtilizationScalingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ASGAverageCPUUtilization,
targetValue: props.targetUtilizationPercent,
...props
});
}

/**
* Scale out or in to achieve a target network ingress rate
*/
public scaleOnIncomingBytes(id: string, props: NetworkUtilizationScalingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ASGAverageNetworkIn,
targetValue: props.targetBytesPerSecond,
...props
});
}

/**
* Scale out or in to achieve a target network egress rate
*/
public scaleOnOutgoingBytes(id: string, props: NetworkUtilizationScalingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ASGAverageNetworkOut,
targetValue: props.targetBytesPerSecond,
...props
});
}

/**
* Scale out or in to achieve a target request handling rate
*
* The AutoScalingGroup must have been attached to an Application Load Balancer
* in order to be able to call this.
*/
public scaleOnRequestCount(id: string, props: RequestCountScalingProps): TargetTrackingScalingPolicy {
if (this.albTargetGroup === undefined) {
throw new Error('Attach the AutoScalingGroup to an Application Load Balancer before calling scaleOnRequestCount()');
}

const resourceLabel = `${this.albTargetGroup.firstLoadBalancerFullName}/${this.albTargetGroup.targetGroupFullName}`;

const policy = new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ALBRequestCountPerTarget,
targetValue: props.targetRequestsPerSecond,
resourceLabel,
...props
});

policy.node.addDependency(this.albTargetGroup.loadBalancerAttached);
return policy;
}

/**
* Scale out or in in order to keep a metric around a target value
*/
public scaleToTrackMetric(id: string, props: MetricTargetTrackingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
customMetric: props.metric,
...props
});
}

/**
* Scale out or in, in response to a metric
*/
public scaleOnMetric(id: string, props: BasicStepScalingPolicyProps): StepScalingPolicy {
return new StepScalingPolicy(this, id, { ...props, autoScalingGroup: this });
}
}

/**
* A Fleet represents a managed set of EC2 instances
*
Expand All @@ -187,8 +292,20 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps {
*
* The ASG spans all availability zones.
*/
export class AutoScalingGroup extends Resource implements IAutoScalingGroup, elb.ILoadBalancerTarget, ec2.IConnectable,
elbv2.IApplicationLoadBalancerTarget, elbv2.INetworkLoadBalancerTarget {
export class AutoScalingGroup extends AutoScalingGroupBase implements
elb.ILoadBalancerTarget,
ec2.IConnectable,
elbv2.IApplicationLoadBalancerTarget,
elbv2.INetworkLoadBalancerTarget {

public static fromAutoScalingGroupName(scope: Construct, id: string, autoScalingGroupName: string): IAutoScalingGroup {
class Import extends AutoScalingGroupBase {
public autoScalingGroupName = autoScalingGroupName;
}

return new Import(scope, id);
}

/**
* The type of OS instances of this fleet are running.
*/
Expand All @@ -215,7 +332,6 @@ export class AutoScalingGroup extends Resource implements IAutoScalingGroup, elb
private readonly securityGroups: ec2.ISecurityGroup[] = [];
private readonly loadBalancerNames: string[] = [];
private readonly targetGroupArns: string[] = [];
private albTargetGroup?: elbv2.ApplicationTargetGroup;

constructor(scope: Construct, id: string, props: AutoScalingGroupProps) {
super(scope, id);
Expand Down Expand Up @@ -345,112 +461,13 @@ export class AutoScalingGroup extends Resource implements IAutoScalingGroup, elb
scriptLines.forEach(scriptLine => this.userDataLines.push(scriptLine));
}

/**
* Scale out or in based on time
*/
public scaleOnSchedule(id: string, props: BasicScheduledActionProps): ScheduledAction {
return new ScheduledAction(this, `ScheduledAction${id}`, {
autoScalingGroup: this,
...props,
});
}

/**
* Scale out or in to achieve a target CPU utilization
*/
public scaleOnCpuUtilization(id: string, props: CpuUtilizationScalingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ASGAverageCPUUtilization,
targetValue: props.targetUtilizationPercent,
...props
});
}

/**
* Scale out or in to achieve a target network ingress rate
*/
public scaleOnIncomingBytes(id: string, props: NetworkUtilizationScalingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ASGAverageNetworkIn,
targetValue: props.targetBytesPerSecond,
...props
});
}

/**
* Scale out or in to achieve a target network egress rate
*/
public scaleOnOutgoingBytes(id: string, props: NetworkUtilizationScalingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ASGAverageNetworkOut,
targetValue: props.targetBytesPerSecond,
...props
});
}

/**
* Scale out or in to achieve a target request handling rate
*
* The AutoScalingGroup must have been attached to an Application Load Balancer
* in order to be able to call this.
*/
public scaleOnRequestCount(id: string, props: RequestCountScalingProps): TargetTrackingScalingPolicy {
if (this.albTargetGroup === undefined) {
throw new Error('Attach the AutoScalingGroup to an Application Load Balancer before calling scaleOnRequestCount()');
}

const resourceLabel = `${this.albTargetGroup.firstLoadBalancerFullName}/${this.albTargetGroup.targetGroupFullName}`;

const policy = new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
predefinedMetric: PredefinedMetric.ALBRequestCountPerTarget,
targetValue: props.targetRequestsPerSecond,
resourceLabel,
...props
});

policy.node.addDependency(this.albTargetGroup.loadBalancerAttached);
return policy;
}

/**
* Scale out or in in order to keep a metric around a target value
*/
public scaleToTrackMetric(id: string, props: MetricTargetTrackingProps): TargetTrackingScalingPolicy {
return new TargetTrackingScalingPolicy(this, `ScalingPolicy${id}`, {
autoScalingGroup: this,
customMetric: props.metric,
...props
});
}

/**
* Scale out or in, in response to a metric
*/
public scaleOnMetric(id: string, props: BasicStepScalingPolicyProps): StepScalingPolicy {
return new StepScalingPolicy(this, id, { ...props, autoScalingGroup: this });
}

/**
* Adds a statement to the IAM role assumed by instances of this fleet.
*/
public addToRolePolicy(statement: iam.PolicyStatement) {
this.role.addToPolicy(statement);
}

/**
* Send a message to either an SQS queue or SNS topic when instances launch or terminate
*/
public onLifecycleTransition(id: string, props: BasicLifecycleHookProps): LifecycleHook {
return new LifecycleHook(this, `LifecycleHook${id}`, {
autoScalingGroup: this,
...props
});
}

/**
* Apply CloudFormation update policies for the AutoScalingGroup
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ export = {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);
const importedRole = iam.Role.import(stack, 'ImportedRole', { roleArn: 'arn:aws:iam::123456789012:role/HelloDude' });
const importedRole = iam.Role.fromRoleArn(stack, 'ImportedRole', 'arn:aws:iam::123456789012:role/HelloDude');

// WHEN
const asg = new autoscaling.AutoScalingGroup(stack, 'MyASG', {
Expand Down Expand Up @@ -534,9 +534,7 @@ function mockVpc(stack: cdk.Stack) {
}

function mockSecurityGroup(stack: cdk.Stack) {
return ec2.SecurityGroup.import(stack, 'MySG', {
securityGroupId: 'most-secure',
});
return ec2.SecurityGroup.fromSecurityGroupId(stack, 'MySG', 'most-secure');
}

function getTestStack(): cdk.Stack {
Expand Down
Loading