Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
feat(user registration) : create event rule and attach it to SNS targ…
Browse files Browse the repository at this point in the history
…et + eventSchema (#110)

* user registration event rule and attach it to SNS target

* tie DLQ name to eventName

* user-registration event schema

* update user events dlq
  • Loading branch information
sri-kirsh authored Mar 6, 2023
1 parent 50154a3 commit 2b49ca4
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class CollectionApiEvents extends Resource {
});

this.snsTopicDlq = new sqs.SqsQueue(this, 'sns-topic-dql', {
name: `${config.prefix}-SNS-Topic-Event-Rule-DLQ`,
name: `${config.prefix}-SNS-${eventConfig.name}-Event-Rule-DLQ`,
tags: config.tags,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class ShareableListEvents extends Resource {
});

this.snsTopicDlq = new sqs.SqsQueue(this, 'sns-topic-dql', {
name: `${config.prefix}-SNS-Topic-Event-Rule-DLQ`,
name: `${config.prefix}-SNS-${eventConfig.shareableList.name}-Topic-DLQ`,
tags: config.tags,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class ShareableListItemEvents extends Resource {
});

this.snsTopicDlq = new sqs.SqsQueue(this, 'sns-topic-dql', {
name: `${config.prefix}-SNS-Topic-Event-Rule-DLQ`,
name: `${config.prefix}-SNS-${eventConfig.shareableListItem.name}-Topic-DLQ`,
tags: config.tags,
});

Expand Down
2 changes: 1 addition & 1 deletion .aws/src/event-rules/user-api-events/userApiEventRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class UserApiEvents extends Resource {
});

this.snsTopicDlq = new sqs.SqsQueue(this, 'sns-topic-dql', {
name: `${config.prefix}-SNS-Topic-Event-Rule-DLQ`,
name: `${config.prefix}-${eventConfig.name}-Topic-Rule-DLQ`,
tags: config.tags,
});

Expand Down
8 changes: 8 additions & 0 deletions .aws/src/event-rules/user-registration/eventConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { config as globalConfig } from '../../config';

export const eventConfig = {
name: 'UserRegistration',
source: 'web-repo',
detailType: ['User Registration'],
bus: globalConfig.sharedEventBusName,
};
116 changes: 116 additions & 0 deletions .aws/src/event-rules/user-registration/userRegistrationEventRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { Construct } from 'constructs';
import { Resource } from 'cdktf';
import {
PocketEventBridgeProps,
PocketEventBridgeRuleWithMultipleTargets,
ApplicationEventBus,
PocketPagerDuty,
} from '@pocket-tools/terraform-modules';
import { config } from '../../config';
import { iam, sns, sqs } from '@cdktf/provider-aws';
import { eventConfig } from './eventConfig';
import { createDeadLetterQueueAlarm } from '../utils';
import * as NullProviders from '@cdktf/provider-null';

export class UserRegistrationEventRule extends Resource {
public readonly snsTopic: sns.SnsTopic;
public readonly snsTopicDlq: sqs.SqsQueue;

constructor(
scope: Construct,
private name: string,
private pagerDuty: PocketPagerDuty
) {
super(scope, name);

this.snsTopic = new sns.SnsTopic(this, 'user-registration-topic', {
name: `${config.prefix}-UserRegistrationTopic`,
lifecycle: {
preventDestroy: true,
},
});

this.snsTopicDlq = new sqs.SqsQueue(this, 'sns-topic-dql', {
name: `${config.prefix}-SNS-${eventConfig.name}-Topic--DLQ`,
tags: config.tags,
});

const userRegistrationEvent = this.createUserRegistrationEventRules();
this.createPolicyForEventBridgeToSns();

//todo: set DLQ alert after the chores ticket

//place-holder resource used to make sure we are not
//removing the event-rule or the SNS by mistake
//if the resources are removed, this would act as an additional check
//to prevent resource deletion in-addition to preventDestroy
//e.g removing any of the dependsOn resource and running npm build would
//throw error
new NullProviders.Resource(this, 'null-resource', {
dependsOn: [userRegistrationEvent.getEventBridge().rule, this.snsTopic],
});
}

/**
* Rolls out event bridge rule and attaches them to sns target
* for user-registration-events
* @private
*/
private createUserRegistrationEventRules() {
const userRegistrationEventRuleProps: PocketEventBridgeProps = {
eventRule: {
name: `${config.prefix}-${eventConfig.name}-Rule`,
eventPattern: {
source: [eventConfig.source],
'detail-type': eventConfig.detailType,
},
eventBusName: eventConfig.bus,
preventDestroy: true,
},
targets: [
{
arn: this.snsTopic.arn,
deadLetterArn: this.snsTopicDlq.arn,
targetId: `${config.prefix}-User-Registration-Event-SNS-Target`,
terraformResource: this.snsTopic,
},
],
};
return new PocketEventBridgeRuleWithMultipleTargets(
this,
`${config.prefix}-User-Registration-EventBridge-Rule`,
userRegistrationEventRuleProps
);
}

private createPolicyForEventBridgeToSns() {
const eventBridgeSnsPolicy = new iam.DataAwsIamPolicyDocument(
this,
`${config.prefix}-EventBridge-SNS-Policy`,
{
statement: [
{
effect: 'Allow',
actions: ['sns:Publish'],
resources: [this.snsTopic.arn],
principals: [
{
identifiers: ['events.amazonaws.com'],
type: 'Service',
},
],
},
],
}
).json;

return new sns.SnsTopicPolicy(
this,
'user-registration-events-sns-topic-policy',
{
arn: this.snsTopic.arn,
policy: eventBridgeSnsPolicy,
}
);
}
}
71 changes: 71 additions & 0 deletions .aws/src/events-schema/userRegistrationEventSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* user registration event is emitted in web repo when
* user initiates a password recovery
*/
import { Resource } from 'cdktf';
import { Construct } from 'constructs';
import { eventbridgeschemas } from '@cdktf/provider-aws';
import { SCHEMA_REGISTRY, SCHEMA_TYPE } from './types';
import { SchemasSchemaConfig } from '@cdktf/provider-aws/lib/eventbridgeschemas/schemas-schema';

export class UserRegistrationEventSchema extends Resource {
public readonly userRegistrationEvent: string = 'User-Registration-Event';

constructor(scope: Construct, private name: string) {
super(scope, name);
this.createUserRegistrationEventSchema();
}

private createUserRegistrationEventSchema() {
const schemaProps: SchemasSchemaConfig = {
name: this.userRegistrationEvent,
description: `emitted when pocket user is registered (e.g signup)`,
type: SCHEMA_TYPE,
registryName: SCHEMA_REGISTRY,
content: JSON.stringify(this.getUserRegistrationPayload()),
};
const schema = new eventbridgeschemas.SchemasSchema(
this,
`${this.userRegistrationEvent}-Schema`,
schemaProps
);

return schema;
}

/***
* Schema scaffold from the aws console
*/
private getUserRegistrationPayload() {
return {
openapi: '3.0.0',
info: {
version: '1.0.0',
title: 'Event',
},
paths: {},
components: {
schemas: {
Event: {
type: 'object',
required: ['encodedUserId', 'locale', 'userId', 'email'],
properties: {
email: {
type: 'string',
},
encodedUserId: {
type: 'string',
},
locale: {
type: 'string',
},
userId: {
type: 'string',
},
},
},
},
},
};
}
}
24 changes: 15 additions & 9 deletions .aws/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { UserMergeEventSchema } from './events-schema/userMergeEvent';
import { PremiumPurchaseEvent } from './events-schema/premiumPurchaseEvent';
import { ForgotPasswordRequestEvent } from './events-schema/ForgotPasswordRequestEvent';
import { PremiumPurchase } from './event-rules/premium-purchase';
import { UserRegistrationEventRule } from './event-rules/user-registration/userRegistrationEventRule';
import { UserRegistrationEventSchema } from './events-schema/userRegistrationEventSchema';

class PocketEventBus extends TerraformStack {
constructor(scope: Construct, name: string) {
Expand Down Expand Up @@ -84,15 +86,8 @@ class PocketEventBus extends TerraformStack {
//'Premium Purchase' event, currently emitted by web-repo
new PremiumPurchase(this, 'premium-purchase', pagerDuty);

//Schema
new UserEventsSchema(this, 'user-api-events-schema');
new QueueCheckDeleteSchema(this, 'queue-delete-schema');
new UserMergeEventSchema(this, 'user-merge-event-shema');
new PremiumPurchaseEvent(this, 'premium-purchase-event-schema');
new ForgotPasswordRequestEvent(
this,
'forgot-password-request-event-schema'
);
//'User Registration' event, currently emitted by web-repo
new UserRegistrationEventRule(this, 'user-registration', pagerDuty);

new CollectionApiEvents(
this,
Expand All @@ -117,6 +112,17 @@ class PocketEventBus extends TerraformStack {
sharedPocketEventBus,
pagerDuty
);

//Schema
new UserEventsSchema(this, 'user-api-events-schema');
new QueueCheckDeleteSchema(this, 'queue-delete-schema');
new UserMergeEventSchema(this, 'user-merge-event-shema');
new PremiumPurchaseEvent(this, 'premium-purchase-event-schema');
new ForgotPasswordRequestEvent(
this,
'forgot-password-request-event-schema'
);
new UserRegistrationEventSchema(this, `user-registration-event-schema`);
}

/**
Expand Down

0 comments on commit 2b49ca4

Please sign in to comment.