Skip to content

Commit 18a6b0c

Browse files
authored
feat(elbv2): use addAction() on an imported application listener (#19293)
This PR adds the ability to call `addAction()` on an imported `IApplicationListener`. Fixes #10902 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e8142e9 commit 18a6b0c

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener.ts

+45
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,21 @@ export interface IApplicationListener extends IResource, ec2.IConnectable {
508508
* Don't call this directly. It is called by ApplicationTargetGroup.
509509
*/
510510
registerConnectable(connectable: ec2.IConnectable, portRange: ec2.Port): void;
511+
512+
/**
513+
* Perform the given action on incoming requests
514+
*
515+
* This allows full control of the default action of the load balancer,
516+
* including Action chaining, fixed responses and redirect responses. See
517+
* the `ListenerAction` class for all options.
518+
*
519+
* It's possible to add routing conditions to the Action added in this way.
520+
*
521+
* It is not possible to add a default action to an imported IApplicationListener.
522+
* In order to add actions to an imported IApplicationListener a `priority`
523+
* must be provided.
524+
*/
525+
addAction(id: string, props: AddApplicationActionProps): void;
511526
}
512527

513528
/**
@@ -627,6 +642,36 @@ abstract class ExternalApplicationListener extends Resource implements IApplicat
627642
// eslint-disable-next-line max-len
628643
throw new Error('Can only call addTargets() when using a constructed ApplicationListener; construct a new TargetGroup and use addTargetGroup.');
629644
}
645+
646+
/**
647+
* Perform the given action on incoming requests
648+
*
649+
* This allows full control of the default action of the load balancer,
650+
* including Action chaining, fixed responses and redirect responses. See
651+
* the `ListenerAction` class for all options.
652+
*
653+
* It's possible to add routing conditions to the Action added in this way.
654+
*
655+
* It is not possible to add a default action to an imported IApplicationListener.
656+
* In order to add actions to an imported IApplicationListener a `priority`
657+
* must be provided.
658+
*/
659+
public addAction(id: string, props: AddApplicationActionProps): void {
660+
checkAddRuleProps(props);
661+
662+
if (props.priority !== undefined) {
663+
// New rule
664+
//
665+
// TargetGroup.registerListener is called inside ApplicationListenerRule.
666+
new ApplicationListenerRule(this, id + 'Rule', {
667+
listener: this,
668+
priority: props.priority,
669+
...props,
670+
});
671+
} else {
672+
throw new Error('priority must be set for actions added to an imported listener');
673+
}
674+
}
630675
}
631676

632677
/**

packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts

+79
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,85 @@ describe('tests', () => {
707707
});
708708
});
709709

710+
test('Can add actions to an imported listener', () => {
711+
// GIVEN
712+
const stack = new cdk.Stack();
713+
const stack2 = new cdk.Stack();
714+
const vpc = new ec2.Vpc(stack, 'VPC');
715+
const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', {
716+
vpc,
717+
});
718+
const listener = lb.addListener('Listener', {
719+
port: 80,
720+
});
721+
722+
// WHEN
723+
listener.addAction('Default', {
724+
action: elbv2.ListenerAction.fixedResponse(404, {
725+
contentType: 'text/plain',
726+
messageBody: 'Not Found',
727+
}),
728+
});
729+
730+
const importedListener = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack2, 'listener', {
731+
listenerArn: 'listener-arn',
732+
defaultPort: 443,
733+
securityGroup: ec2.SecurityGroup.fromSecurityGroupId(stack2, 'SG', 'security-group-id', {
734+
allowAllOutbound: false,
735+
}),
736+
});
737+
importedListener.addAction('Hello', {
738+
action: elbv2.ListenerAction.fixedResponse(503),
739+
conditions: [elbv2.ListenerCondition.pathPatterns(['/hello'])],
740+
priority: 10,
741+
});
742+
743+
// THEN
744+
Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::Listener', {
745+
DefaultActions: [
746+
{
747+
FixedResponseConfig: {
748+
ContentType: 'text/plain',
749+
MessageBody: 'Not Found',
750+
StatusCode: '404',
751+
},
752+
Type: 'fixed-response',
753+
},
754+
],
755+
});
756+
757+
Template.fromStack(stack2).hasResourceProperties('AWS::ElasticLoadBalancingV2::ListenerRule', {
758+
ListenerArn: 'listener-arn',
759+
Priority: 10,
760+
Actions: [
761+
{
762+
FixedResponseConfig: {
763+
StatusCode: '503',
764+
},
765+
Type: 'fixed-response',
766+
},
767+
],
768+
});
769+
});
770+
771+
test('actions added to an imported listener must have a priority', () => {
772+
// GIVEN
773+
const stack = new cdk.Stack();
774+
775+
const importedListener = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack, 'listener', {
776+
listenerArn: 'listener-arn',
777+
defaultPort: 443,
778+
securityGroup: ec2.SecurityGroup.fromSecurityGroupId(stack, 'SG', 'security-group-id', {
779+
allowAllOutbound: false,
780+
}),
781+
});
782+
expect(() => {
783+
importedListener.addAction('Hello', {
784+
action: elbv2.ListenerAction.fixedResponse(503),
785+
});
786+
}).toThrow(/priority must be set for actions added to an imported listener/);
787+
});
788+
710789
testDeprecated('Can add redirect responses', () => {
711790
// GIVEN
712791
const stack = new cdk.Stack();

0 commit comments

Comments
 (0)