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(ecs): add a new API for registering ECS targets #4212

Merged
merged 9 commits into from
Oct 4, 2019

Conversation

iamhopaul123
Copy link
Contributor

Add a new API for registering ECS targets, which is also the second part for #3922.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@iamhopaul123 iamhopaul123 added the pr/do-not-merge This PR should not be merged at this time. label Sep 23, 2019
@mergify
Copy link
Contributor

mergify bot commented Sep 23, 2019

Thanks so much for taking the time to contribute to the AWS CDK ❤️

We will shortly assign someone to review this pull request and help get it
merged. In the meantime, please take a minute to make sure you follow this
checklist
:

  • PR title type(scope): text
    • type: fix, feat, refactor go into CHANGELOG, chore is hidden
    • scope: name of module without aws- or cdk- prefix or postfix (e.g. s3 instead of aws-s3-deployment)
    • text: use all lower-case, do not end with a period, do not include issue refs
  • PR Description
    • Rationale: describe rationale of change and approach taken
    • Issues: indicate issues fixed via: fixes #xxx or closes #xxx
    • Breaking?: last paragraph: BREAKING CHANGE: <describe what changed + link for details>
  • Testing
    • Unit test added. Prefer to add a new test rather than modify existing tests
    • CLI or init templates change? Re-run/add CLI integration tests
  • Documentation
    • README: update module README to describe new features
    • API docs: public APIs must be documented. Copy from official AWS docs when possible
    • Design: for significant features, follow design process

1 similar comment
@mergify
Copy link
Contributor

mergify bot commented Sep 23, 2019

Thanks so much for taking the time to contribute to the AWS CDK ❤️

We will shortly assign someone to review this pull request and help get it
merged. In the meantime, please take a minute to make sure you follow this
checklist
:

  • PR title type(scope): text
    • type: fix, feat, refactor go into CHANGELOG, chore is hidden
    • scope: name of module without aws- or cdk- prefix or postfix (e.g. s3 instead of aws-s3-deployment)
    • text: use all lower-case, do not end with a period, do not include issue refs
  • PR Description
    • Rationale: describe rationale of change and approach taken
    • Issues: indicate issues fixed via: fixes #xxx or closes #xxx
    • Breaking?: last paragraph: BREAKING CHANGE: <describe what changed + link for details>
  • Testing
    • Unit test added. Prefer to add a new test rather than modify existing tests
    • CLI or init templates change? Re-run/add CLI integration tests
  • Documentation
    • README: update module README to describe new features
    • API docs: public APIs must be documented. Copy from official AWS docs when possible
    • Design: for significant features, follow design process

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

protocol: containerTarget.protocol
};
for (const targetGroupProp of containerTarget.targetGroups) {
if (targetGroupProp.listener instanceof elbv2.ApplicationListener) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for re-usability can we move out the logic for registering based on ApplicationListener and NetworkLister to independent methods, and refer to those methods here?

@mergify mergify bot dismissed piradeepk’s stale review September 24, 2019 17:53

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

/**
* Container targets of the container.
*/
readonly containerTargets: ContainerTargetProps[]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I like this name. It feels like introducing a new concept to users that I wonder whether it's worthwhile.

Also: ultimately, we just need a flat list of (container, port, targetGroupName, listener), so why introduce all this hierarchy here? Feels like a flat list of tuples would give a much more convenient API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I agree, since for each service for most of cases there will only be one or two targets to be registered. Using a flat list should be a better option.

/**
* Setting to create and attach target groups.
*/
readonly targetGroups: TargetGroupProps [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect a property named targetGroups to take ITargetGroup objects, not properties to create new target groups.

/**
* Properties for adding new targets to a listener.
*/
readonly addTargetGroupProps?: elbv2.AddApplicationTargetsProps | elbv2.AddNetworkTargetsProps,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No type unions please. If you want unions, create union-like classes instead.

Copy link
Contributor Author

@iamhopaul123 iamhopaul123 Sep 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot create an interface that extends these and also listeners below because they both have the properties with the same name but different types. Also, can you please explain the reason why type union is not recommended?

Copy link
Contributor

@rix0rrr rix0rrr Sep 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type unions do not translate well across jsii (to all languages that we target).

Union-like classes are abstract base classes that get constructed through some factory function:

abstract class MyGroupUnion {
 public static variantOne(): MyGroupUnion {
    // Return some subclass of MyGroupUnion
 }

 public static variantTwo(props: SomeProps) {
    // Return some subclass of MyGroupUnion
 }

 public abstract yieldSomeInterestingProperties(): SomeInterestingProperties;
}

/**
* Listener for the target group to attach to [disable-awslint:ref-via-interface].
*/
readonly listener: elbv2.ApplicationListener | elbv2.NetworkListener
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are the interfaces not good enough?

Can that be fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's because INetworkListener does not have the method addTargets, and arn is the only property the interface has.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Would it be possible to effectively implement addTargets() in the interfaces?

I guess not, huh?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still possible to implement addTargets() but it will be a little bit clumsy and reinvent the wheels. Yeah I think you are right.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

/**
* Create a config for adding target group to ALB listener.
*/
public static applicationListenerConfig(listener: elbv2.ApplicationListener, props?: elbv2.AddApplicationTargetsProps): ListenerConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the Config at the end of the method name here. Shorter is better, and the "config" part is already implied by the class name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

/**
* Properties for defining an ECS target.
*/
readonly containerTarget: LoadBalancerTargetOptions,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other interfaces are declared using a semicolon (;) at the end of fields, so please match the existing style.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think I would be in favor of inlining the LoadBalancerTargetOptions property into the parent struct here. The usability will be a lot better in non-JS languages.

/**
* ID for a target group to be created.
*/
readonly targetGroupId: string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer you called this newTargetGroupId to make it abundantly clear you will be creating a new TargetGroup for users, rather than picking an existing Target Group that they've already created.

* },
* )
*/
public registerContainerTargets(...targets: EcsTarget[]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that, if you're coming at this cold (and don't have all the state that you have in your head about this change), that the name service.registerContainerTargets is clear enough that it pertains to load balancing? (And not, for example, service discovery?)

For myself, I would be wondering what I'm registering into?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is hard to find a name that can be really clear enough to figure out what exactly this method does by seeing the name alone. However, I agree the naming can be improved to make it more explicit.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

rix0rrr
rix0rrr previously approved these changes Oct 1, 2019
@mergify mergify bot dismissed rix0rrr’s stale review October 1, 2019 16:26

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Comment on lines +380 to +405
* @example
*
* service.registerLoadBalancerTargets(
* {
* containerTarget: {
* containerName: 'web',
* containerPort: 80,
* },
* targetGroupId: 'ECS',
* listener: ecs.ListenerConfig.applicationListener(listener, {
* protocol: elbv2.ApplicationProtocol.HTTPS
* }),
* },
* )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add this to the README, not sure if it makes sense to add it here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a precedent for having examples in jsdoc strings versus in README?

/**
* ID for a target group to be created.
*/
readonly newTargetGroupId: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this to targetGroupId (new is relative)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, I just made him change it from targetGroupId -> newTargetGroupId.

The thing is, I'm not sure that targetGroupId conveys accurately enough that it will be created, rather than one that already exists that happens to have that ID.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, just find newTargetGroup to be ambiguous.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@piradeepk piradeepk added the @aws-cdk/aws-ecs Related to Amazon Elastic Container label Oct 2, 2019
SoManyHs
SoManyHs previously approved these changes Oct 3, 2019
Copy link
Contributor

@SoManyHs SoManyHs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very small nits, otherwise LGTM!

Comment on lines +380 to +405
* @example
*
* service.registerLoadBalancerTargets(
* {
* containerTarget: {
* containerName: 'web',
* containerPort: 80,
* },
* targetGroupId: 'ECS',
* listener: ecs.ListenerConfig.applicationListener(listener, {
* protocol: elbv2.ApplicationProtocol.HTTPS
* }),
* },
* )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a precedent for having examples in jsdoc strings versus in README?

@@ -664,6 +664,321 @@ export = {

test.done();
}
},

'allows add load balancers to a service': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rephrase to "allows registering multiple target groups"

},

'allows add load balancers to a service': {
'when application load balancers': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "with" application load balancers

},
},

'when network load balancers': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"with"

@iamhopaul123
Copy link
Contributor Author

@SoManyHs

Do we have a precedent for having examples in jsdoc strings versus in README?

I included the example in README as well. And for jsdoc strings, I referred to this. I think it can help when users first use this method and when they hover to the method they can see the example to know how to use the method, which makes it more convenient.

@mergify mergify bot dismissed SoManyHs’s stale review October 4, 2019 00:11

Pull request has been modified.

SoManyHs
SoManyHs previously approved these changes Oct 4, 2019
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@rix0rrr
Copy link
Contributor

rix0rrr commented Oct 4, 2019

Examples could/should be in both.

rix0rrr
rix0rrr previously approved these changes Oct 4, 2019
@rix0rrr
Copy link
Contributor

rix0rrr commented Oct 4, 2019

Remove the label when you are ready to merge.

@iamhopaul123 iamhopaul123 removed the pr/do-not-merge This PR should not be merged at this time. label Oct 4, 2019
@mergify mergify bot dismissed stale reviews from rix0rrr and SoManyHs October 4, 2019 16:27

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Copy link
Contributor

@piradeepk piradeepk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ship it!

@mergify
Copy link
Contributor

mergify bot commented Oct 4, 2019

Thank you for contributing! Your pull request is now being automatically merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-ecs Related to Amazon Elastic Container
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants