Skip to content

Commit

Permalink
Switch to version 3.x of the AWS SDK for JavaScript (#195)
Browse files Browse the repository at this point in the history
* WIP

* Fixed test cases

* Removed unused deps
  • Loading branch information
dsarlo authored Dec 2, 2023
1 parent 343087d commit 27e92b6
Show file tree
Hide file tree
Showing 7 changed files with 959 additions and 465 deletions.
37 changes: 16 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,45 +34,40 @@
},
"homepage": "https://github.com/mj1618/serverless-offline-sns#readme",
"dependencies": {
"aws-sdk": "^2.1476.0",
"@aws-sdk/client-sns": "^3.465.0",
"@aws-sdk/client-sqs": "^3.465.0",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"lodash": "^4.17.21",
"node-fetch": "^3.3.2",
"serverless": "^3.35.2",
"serverless": "^3.38.0",
"shelljs": "^0.8.5",
"uuid": "^9.0.1",
"xml": "^1.0.1"
},
"devDependencies": {
"@types/chai": "^4.3.9",
"@types/cors": "^2.8.15",
"@types/express": "^4.17.20",
"@types/mocha": "^10.0.3",
"@types/node": "^20.8.7",
"@types/node-fetch": "^2.6.7",
"@types/serverless": "^3.12.17",
"@types/shelljs": "^0.8.14",
"@types/sinon": "^10.0.20",
"@types/uuid": "^9.0.6",
"@types/xml": "^1.0.10",
"@types/chai": "^4.3.11",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/mocha": "^10.0.6",
"@types/node": "^20.10.2",
"@types/node-fetch": "^2.6.9",
"@types/serverless": "^3.12.18",
"@types/shelljs": "^0.8.15",
"@types/uuid": "^9.0.7",
"@types/xml": "^1.0.11",
"all-contributors-cli": "^6.26.1",
"aws-sdk-mock": "^5.8.0",
"aws-sdk-client-mock": "^3.0.0",
"chai": "^4.3.10",
"handlebars": "4.7.8",
"istanbul": "^0.4.5",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"prettier": "3.0.3",
"sinon": "^16.1.1",
"source-map-support": "^0.5.21",
"ts-loader": "^9.5.0",
"prettier": "3.1.0",
"ts-mocha": "^10.0.0",
"ts-node": "^10.9.1",
"tslint": "^5.20.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^5.2.2"
"typescript": "^5.3.2"
},
"nyc": {
"extension": [
Expand Down
6 changes: 0 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import bodyParser from "body-parser";
import { ISNSAdapter } from "./types.js";
import { SNSServer } from "./sns-server.js";
import _ from "lodash";
import AWS from "aws-sdk";
import { resolve } from "path";
import { topicNameFromArn } from "./helpers.js";
import { spawn } from "child_process";
Expand Down Expand Up @@ -113,11 +112,6 @@ class ServerlessOfflineSns {
this.region = "us-east-1";
}
this.autoSubscribe = this.config.autoSubscribe === undefined ? true : this.config.autoSubscribe;
// Congure SNS client to be able to find us.
AWS.config.sns = {
endpoint: "http://127.0.0.1:" + this.localPort,
region: this.region,
};
}

public async start() {
Expand Down
103 changes: 51 additions & 52 deletions src/sns-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import AWS from "aws-sdk";
import {
ListSubscriptionsResponse, ListTopicsResponse, MessageAttributeMap
} from "aws-sdk/clients/sns.d.js";
import { ListSubscriptionsResponse, ListTopicsResponse, MessageAttributeValue, SNSClient, ListTopicsCommand, ListSubscriptionsCommand, UnsubscribeCommand, CreateTopicCommand, SubscribeCommand, PublishCommand } from "@aws-sdk/client-sns";
import _ from "lodash";
import fetch from "node-fetch";
import { createMessageId, createSnsLambdaEvent } from "./helpers.js";
import { IDebug, ISNSAdapter } from "./types.js";

export class SNSAdapter implements ISNSAdapter {
private sns: AWS.SNS;
private sns: SNSClient;
private pluginDebug: IDebug;
private port: number;
private server: any;
Expand Down Expand Up @@ -44,26 +41,23 @@ export class SNSAdapter implements ISNSAdapter {
this.endpoint = snsEndpoint || `http://127.0.0.1:${localPort}`;
this.debug("using endpoint: " + this.endpoint);
this.accountId = accountId;
if (!AWS.config.credentials) {
AWS.config.update({
this.sns = new SNSClient({
credentials: {
accessKeyId: "AKID",
secretAccessKey: "SECRET",
region,
});
}
this.sns = new AWS.SNS({
},
endpoint: this.endpoint,
region,
});
}

public async listTopics(): Promise<ListTopicsResponse> {
this.debug("listing topics");
const req = this.sns.listTopics({});
this.debug(JSON.stringify(req.httpRequest));
const req = new ListTopicsCommand({});
this.debug(JSON.stringify(req.input));

return await new Promise((res) => {
this.sns.listTopics({}, (err, topics) => {
this.sns.send(req, (err, topics) => {
if (err) {
this.debug(err, err.stack);
} else {
Expand All @@ -76,11 +70,11 @@ export class SNSAdapter implements ISNSAdapter {

public async listSubscriptions(): Promise<ListSubscriptionsResponse> {
this.debug("listing subs");
const req = this.sns.listSubscriptions({});
this.debug(JSON.stringify(req.httpRequest));
const req = new ListSubscriptionsCommand({});
this.debug(JSON.stringify(req.input));

return await new Promise((res) => {
this.sns.listSubscriptions({}, (err, subs) => {
this.sns.send(req, (err, subs) => {
if (err) {
this.debug(err, err.stack);
} else {
Expand All @@ -93,11 +87,10 @@ export class SNSAdapter implements ISNSAdapter {

public async unsubscribe(arn) {
this.debug("unsubscribing: " + arn);
const unsubscribeReq = new UnsubscribeCommand({ SubscriptionArn: arn });
await new Promise((res) => {
this.sns.unsubscribe(
{
SubscriptionArn: arn,
},
this.sns.send(
unsubscribeReq,
(err, data) => {
if (err) {
this.debug(err, err.stack);
Expand All @@ -111,8 +104,9 @@ export class SNSAdapter implements ISNSAdapter {
}

public async createTopic(topicName) {
const createTopicReq = new CreateTopicCommand({ Name: topicName });
return new Promise((res) =>
this.sns.createTopic({ Name: topicName }, (err, data) => {
this.sns.send(createTopicReq, (err, data) => {
if (err) {
this.debug(err, err.stack);
} else {
Expand Down Expand Up @@ -197,8 +191,9 @@ export class SNSAdapter implements ISNSAdapter {
);
}

const subscribeRequest = new SubscribeCommand(params);
await new Promise((res) => {
this.sns.subscribe(params, (err, data) => {
this.sns.send(subscribeRequest, (err, data) => {
if (err) {
this.debug(err, err.stack);
} else {
Expand Down Expand Up @@ -230,8 +225,9 @@ export class SNSAdapter implements ISNSAdapter {
);
}

const subscribeRequest = new SubscribeCommand(params);
await new Promise((res) => {
this.sns.subscribe(params, (err, data) => {
this.sns.send(subscribeRequest, (err, data) => {
if (err) {
this.debug(err, err.stack);
} else {
Expand All @@ -253,21 +249,22 @@ export class SNSAdapter implements ISNSAdapter {
topicArn: string,
message: string,
type: string = "",
messageAttributes: MessageAttributeMap = {},
messageAttributes: Record<string, MessageAttributeValue> = {},
subject: string = "",
messageGroupId?: string
) {
topicArn = this.convertPseudoParams(topicArn);
const publishReq = new PublishCommand({
Message: message,
Subject: subject,
MessageStructure: type,
TopicArn: topicArn,
MessageAttributes: messageAttributes,
...(messageGroupId && { MessageGroupId: messageGroupId }),
});
return await new Promise((resolve, reject) =>
this.sns.publish(
{
Message: message,
Subject: subject,
MessageStructure: type,
TopicArn: topicArn,
MessageAttributes: messageAttributes,
...(messageGroupId && { MessageGroupId: messageGroupId }),
},
this.sns.send(
publishReq,
(err, result) => {
resolve(result);
}
Expand All @@ -279,19 +276,20 @@ export class SNSAdapter implements ISNSAdapter {
targetArn: string,
message: string,
type: string = "",
messageAttributes: MessageAttributeMap = {},
messageAttributes: Record<string, MessageAttributeValue> = {},
messageGroupId?: string
) {
targetArn = this.convertPseudoParams(targetArn);
const publishReq = new PublishCommand({
Message: message,
MessageStructure: type,
TargetArn: targetArn,
MessageAttributes: messageAttributes,
...(messageGroupId && { MessageGroupId: messageGroupId }),
});
return await new Promise((resolve, reject) =>
this.sns.publish(
{
Message: message,
MessageStructure: type,
TargetArn: targetArn,
MessageAttributes: messageAttributes,
...(messageGroupId && { MessageGroupId: messageGroupId }),
},
this.sns.send(
publishReq,
(err, result) => {
resolve(result);
}
Expand All @@ -303,18 +301,19 @@ export class SNSAdapter implements ISNSAdapter {
phoneNumber: string,
message: string,
type: string = "",
messageAttributes: MessageAttributeMap = {},
messageAttributes: Record<string, MessageAttributeValue> = {},
messageGroupId?: string
) {
const publishReq = new PublishCommand({
Message: message,
MessageStructure: type,
PhoneNumber: phoneNumber,
MessageAttributes: messageAttributes,
...(messageGroupId && { MessageGroupId: messageGroupId }),
});
return await new Promise((resolve, reject) =>
this.sns.publish(
{
Message: message,
MessageStructure: type,
PhoneNumber: phoneNumber,
MessageAttributes: messageAttributes,
...(messageGroupId && { MessageGroupId: messageGroupId }),
},
this.sns.send(
publishReq,
(err, result) => {
resolve(result);
}
Expand Down
53 changes: 27 additions & 26 deletions src/sns-server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import AWS from "aws-sdk";
import { TopicsList, Subscription } from "aws-sdk/clients/sns.js";
import fetch from "node-fetch";
import { URL } from "url";
Expand All @@ -18,6 +17,7 @@ import {
topicArnFromName,
formatMessageAttributes,
} from "./helpers.js";
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";

export class SNSServer implements ISNSServer {
private topics: TopicsList;
Expand Down Expand Up @@ -257,9 +257,9 @@ export class SNSServer implements ISNSServer {
if (_.intersection(v as unknown[], attrs).length > 0) {
this.debug(
"filterPolicy Passed: " +
v +
" matched message attrs: " +
JSON.stringify(attrs)
v +
" matched message attrs: " +
JSON.stringify(attrs)
);
shouldSend = true;
} else {
Expand All @@ -270,9 +270,9 @@ export class SNSServer implements ISNSServer {
if (!shouldSend) {
this.debug(
"filterPolicy Failed: " +
JSON.stringify(policies) +
" did not match message attrs: " +
JSON.stringify(messageAttrs)
JSON.stringify(policies) +
" did not match message attrs: " +
JSON.stringify(messageAttrs)
);
}

Expand All @@ -296,34 +296,35 @@ export class SNSServer implements ISNSServer {
private publishSqs(event, sub, messageAttributes, messageGroupId) {
const subEndpointUrl = new URL(sub.Endpoint);
const sqsEndpoint = `${subEndpointUrl.protocol}//${subEndpointUrl.host}/`;
const sqs = new AWS.SQS({ endpoint: sqsEndpoint, region: this.region });
const sqs = new SQSClient({ endpoint: sqsEndpoint, region: this.region });

if (sub["Attributes"]["RawMessageDelivery"] === "true") {
const sendMsgReq = new SendMessageCommand({
QueueUrl: sub.Endpoint,
MessageBody: event,
MessageAttributes: formatMessageAttributes(messageAttributes),
...(messageGroupId && { MessageGroupId: messageGroupId }),
});
return new Promise<void>((resolve, reject) => {
sqs
.sendMessage({
QueueUrl: sub.Endpoint,
MessageBody: event,
MessageAttributes: formatMessageAttributes(messageAttributes),
...(messageGroupId && { MessageGroupId: messageGroupId }),
}).promise().then(() => {
resolve();
});
.send(sendMsgReq).then(() => {
resolve();
});
});
} else {
const records = JSON.parse(event).Records ?? [];
const messagePromises = records.map((record) => {
const sendMsgReq = new SendMessageCommand({
QueueUrl: sub.Endpoint,
MessageBody: JSON.stringify(record.Sns),
MessageAttributes: formatMessageAttributes(messageAttributes),
...(messageGroupId && { MessageGroupId: messageGroupId }),
});
return new Promise<void>((resolve, reject) => {
sqs
.sendMessage({
QueueUrl: sub.Endpoint,
MessageBody: JSON.stringify(record.Sns),
MessageAttributes: formatMessageAttributes(messageAttributes),
...(messageGroupId && { MessageGroupId: messageGroupId }),
})
.promise().then(() => {
resolve();
});
.send(sendMsgReq).then(() => {
resolve();
});
});
});
return new Promise<void>((resolve, reject) => {
Expand Down Expand Up @@ -430,7 +431,7 @@ export class SNSServer implements ISNSServer {
if (msg instanceof Object) {
try {
msg = JSON.stringify(msg);
} catch (ex) {}
} catch (ex) { }
}
this.pluginDebug(msg, "server");
}
Expand Down
1 change: 0 additions & 1 deletion src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export interface ISNSAdapter {
subscribeQueue(queueUrl: string, arn: string, snsConfig: any): Promise<void>;
publish(
topicArn: string,
type: string,
message: string
): Promise<PublishResponse>;
}
Expand Down
Loading

0 comments on commit 27e92b6

Please sign in to comment.