Skip to content

Commit

Permalink
fix(sns): allow tokens to be used in UrlSubscription (#2938)
Browse files Browse the repository at this point in the history
  • Loading branch information
spg authored and rix0rrr committed Jul 4, 2019
1 parent bcc5862 commit 5ce4141
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
28 changes: 25 additions & 3 deletions packages/@aws-cdk/aws-sns-subscriptions/lib/url.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sns = require('@aws-cdk/aws-sns');
import { Token } from '@aws-cdk/core';
import { SubscriptionProps } from './subscription';

/**
Expand All @@ -13,6 +14,13 @@ export interface UrlSubscriptionProps extends SubscriptionProps {
* @default false
*/
readonly rawMessageDelivery?: boolean;

/**
* The subscription's protocol.
*
* @default - Protocol is derived from url
*/
readonly protocol?: sns.SubscriptionProtocol;
}

/**
Expand All @@ -23,17 +31,31 @@ export interface UrlSubscriptionProps extends SubscriptionProps {
* @see https://docs.aws.amazon.com/sns/latest/dg/sns-http-https-endpoint-as-subscriber.html
*/
export class UrlSubscription implements sns.ITopicSubscription {
private readonly protocol: sns.SubscriptionProtocol;
private readonly unresolvedUrl: boolean;

constructor(private readonly url: string, private readonly props: UrlSubscriptionProps = {}) {
if (!url.startsWith('http://') && !url.startsWith('https://')) {
this.unresolvedUrl = Token.isUnresolved(url);
if (!this.unresolvedUrl && !url.startsWith('http://') && !url.startsWith('https://')) {
throw new Error('URL must start with either http:// or https://');
}

if (this.unresolvedUrl && props.protocol === undefined) {
throw new Error('Must provide protocol if url is unresolved');
}

if (this.unresolvedUrl) {
this.protocol = props.protocol!;
} else {
this.protocol = this.url.startsWith('https:') ? sns.SubscriptionProtocol.HTTPS : sns.SubscriptionProtocol.HTTP;
}
}

public bind(_topic: sns.ITopic): sns.TopicSubscriptionConfig {
return {
subscriberId: this.url,
subscriberId: this.unresolvedUrl ? 'UnresolvedUrl' : this.url,
endpoint: this.url,
protocol: this.url.startsWith('https:') ? sns.SubscriptionProtocol.HTTPS : sns.SubscriptionProtocol.HTTP,
protocol: this.protocol,
rawMessageDelivery: this.props.rawMessageDelivery,
filterPolicy: this.props.filterPolicy,
};
Expand Down
40 changes: 39 additions & 1 deletion packages/@aws-cdk/aws-sns-subscriptions/test/subs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import '@aws-cdk/assert/jest';
import lambda = require('@aws-cdk/aws-lambda');
import sns = require('@aws-cdk/aws-sns');
import sqs = require('@aws-cdk/aws-sqs');
import { Stack } from '@aws-cdk/core';
import { SecretValue, Stack } from '@aws-cdk/core';
import subs = require('../lib');

// tslint:disable:object-literal-key-quotes
Expand Down Expand Up @@ -71,6 +71,44 @@ test('url subscription (with raw delivery)', () => {
});
});

test('url subscription (unresolved url with protocol)', () => {
const secret = SecretValue.secretsManager('my-secret');
const url = secret.toString();
topic.addSubscription(new subs.UrlSubscription(url, {protocol: sns.SubscriptionProtocol.HTTPS}));

expect(stack).toMatchTemplate({
"Resources": {
"MyTopic86869434": {
"Type": "AWS::SNS::Topic",
"Properties": {
"DisplayName": "displayName",
"TopicName": "topicName"
}
},
"MyTopicUnresolvedUrlBA127FB3": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": "{{resolve:secretsmanager:my-secret:SecretString:::}}",
"Protocol": "https",
"TopicArn": { "Ref": "MyTopic86869434" },
}
}
}
});
});

test('url subscription (unknown protocol)', () => {
expect(() => topic.addSubscription(new subs.UrlSubscription('some-protocol://foobar.com/')))
.toThrowError(/URL must start with either http:\/\/ or https:\/\//);
});

test('url subscription (unresolved url without protocol)', () => {
const secret = SecretValue.secretsManager('my-secret');
const url = secret.toString();
expect(() => topic.addSubscription(new subs.UrlSubscription(url)))
.toThrowError(/Must provide protocol if url is unresolved/);
});

test('queue subscription', () => {
const queue = new sqs.Queue(stack, 'MyQueue');

Expand Down

0 comments on commit 5ce4141

Please sign in to comment.