Skip to content

Commit

Permalink
- Added a client-options to be able to control the requestTimeout per…
Browse files Browse the repository at this point in the history
… service.
  • Loading branch information
etiennenoel committed May 14, 2024
1 parent 174e4ed commit 17b3fa1
Show file tree
Hide file tree
Showing 19 changed files with 2,501 additions and 3,073 deletions.
5,323 changes: 2,342 additions & 2,981 deletions packages/aws/package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions packages/aws/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-cloudformation": "^3.441.0",
"@aws-sdk/client-cloudfront": "^3.441.0",
"@aws-sdk/client-dynamodb": "^3.441.0",
"@aws-sdk/client-eventbridge": "^3.441.0",
"@aws-sdk/client-s3": "^3.441.0",
"@aws-sdk/client-secrets-manager": "^3.441.0",
"@aws-sdk/client-ses": "^3.441.0",
"@aws-sdk/client-sqs": "^3.441.0",
"@aws-sdk/client-ssm": "^3.441.0",
"@aws-sdk/s3-request-presigner": "^3.441.0",
"@aws-sdk/client-cloudformation": "^3.569.0",
"@aws-sdk/client-cloudfront": "^3.569.0",
"@aws-sdk/client-dynamodb": "^3.569.0",
"@aws-sdk/client-eventbridge": "^3.569.0",
"@aws-sdk/client-s3": "^3.569.0",
"@aws-sdk/client-secrets-manager": "^3.569.0",
"@aws-sdk/client-ses": "^3.569.0",
"@aws-sdk/client-sqs": "^3.569.0",
"@aws-sdk/client-ssm": "^3.569.0",
"@aws-sdk/s3-request-presigner": "^3.569.0",
"@awslabs-community-fork/dynamodb-data-mapper": "^0.7.13",
"@awslabs-community-fork/dynamodb-data-marshaller": "^0.7.13",
"@awslabs-community-fork/dynamodb-expressions": "^0.7.13",
Expand Down
76 changes: 43 additions & 33 deletions packages/aws/src/clients/cloudformation.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {CloudformationClientInterface} from "../interfaces/cloudformation-client
import {v4 as uuid} from "uuid";
import {CloudformationDeploymentStatusEnum} from "../enums/cloudformation-deployment-status.enum";
import {NotFoundHttpError} from "@pristine-ts/networking";
import {ClientOptionsInterface} from "../interfaces/client-options.interface";

/**
* The client to use to interact with AWS Cloudformation. It is a wrapper around the CloudformationClient of @aws-sdk/client-cloudformation.
Expand Down Expand Up @@ -88,15 +89,18 @@ export class CloudformationClient implements CloudformationClientInterface {

/**
* Gets the description and all its details from a Cloudformation stack.
* @param stackName The stack name to get the.
* @param stackName The stack name to retrieve the description of.
* @param options
*/
async getStackDescription(stackName: string): Promise<Stack | undefined> {
async getStackDescription(stackName: string, options?: Partial<ClientOptionsInterface>): Promise<Stack | undefined> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Getting stack information", {stackName}, AwsModuleKeyname);
const command = new DescribeStacksCommand({
StackName: stackName,
})
try {
const response: DescribeStacksCommandOutput = await this.getClient().send(command);
const response: DescribeStacksCommandOutput = await this.getClient().send(command, {
requestTimeout: options?.requestTimeout,
});
if (!response.Stacks || response.Stacks.length < 1) {
return undefined;
}
Expand All @@ -118,11 +122,11 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Gets the description and all its details from all the CloudFormation stacks.
*/
async listStacks(): Promise<Stack[]> {
async listStacks(options?: Partial<ClientOptionsInterface>): Promise<Stack[]> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Getting list of stacks", {}, AwsModuleKeyname);
const command = new DescribeStacksCommand({})
try {
const response: DescribeStacksCommandOutput = await this.getClient().send(command);
const response: DescribeStacksCommandOutput = await this.getClient().send(command, options);
return response.Stacks ?? [];
} catch (e) {
this.logHandler.error("Error getting stack description from cloudformation", {error: e}, AwsModuleKeyname);
Expand All @@ -133,12 +137,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Creates a new stack in Cloudformation.
* @param input The input to create the new stack.
* @param options
*/
async createStack(input: CreateStackCommandInput): Promise<CreateStackCommandOutput> {
async createStack(input: CreateStackCommandInput, options?: Partial<ClientOptionsInterface>): Promise<CreateStackCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Creating new stack", {input}, AwsModuleKeyname);
const command = new CreateStackCommand(input)
try {
return await this.getClient().send(command);
return await this.getClient().send(command, options);
} catch (e) {
this.logHandler.error("Error creating stack in cloudformation", {error: e, input}, AwsModuleKeyname);
throw e;
Expand All @@ -148,12 +153,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Updates a stack in Cloudformation.
* @param input The input to update the new stack.
* @param options
*/
async updateStack(input: UpdateStackCommandInput): Promise<UpdateStackCommandOutput> {
async updateStack(input: UpdateStackCommandInput, options?: Partial<ClientOptionsInterface>): Promise<UpdateStackCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Updating stack", {input}, AwsModuleKeyname);
const command = new UpdateStackCommand(input)
try {
return await this.getClient().send(command);
return await this.getClient().send(command, options);
} catch (e) {
if (e.message == "No updates are to be performed.") {
return {
Expand All @@ -170,12 +176,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Deletes a stack in Cloudformation.
* @param input The input to delete the new stack.
* @param options
*/
async deleteStack(input: DeleteStackCommandInput): Promise<DeleteStackCommandOutput> {
async deleteStack(input: DeleteStackCommandInput, options?: Partial<ClientOptionsInterface>): Promise<DeleteStackCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Deleting stack", {input}, AwsModuleKeyname);
const command = new DeleteStackCommand(input)
try {
return await this.getClient().send(command);
return await this.getClient().send(command, options);
} catch (e) {
this.logHandler.error("Error deleting stack in cloudformation", {error: e, input}, AwsModuleKeyname);
throw e;
Expand All @@ -185,12 +192,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Creates a Change Set.
* @param input The input to create a change set.
* @param options
*/
async createChangeSet(input: CreateChangeSetCommandInput): Promise<CreateChangeSetCommandOutput> {
async createChangeSet(input: CreateChangeSetCommandInput, options?: Partial<ClientOptionsInterface>): Promise<CreateChangeSetCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Create Change Set", {input}, AwsModuleKeyname);
const command = new CreateChangeSetCommand(input)
try {
const response = await this.getClient().send(command);
const response = await this.getClient().send(command, options);

this.logHandler.debug("CLOUDFORMATION CLIENT - Create Change set Response", {input, response}, AwsModuleKeyname)

Expand All @@ -204,12 +212,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Deletes a Change Set.
* @param input The input to delete a change set.
* @param options
*/
async deleteChangeSet(input: DeleteChangeSetCommandInput): Promise<DeleteChangeSetCommandOutput> {
async deleteChangeSet(input: DeleteChangeSetCommandInput, options?: Partial<ClientOptionsInterface>): Promise<DeleteChangeSetCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Delete Change Set", {input}, AwsModuleKeyname);
const command = new DeleteChangeSetCommand(input)
try {
const response = await this.getClient().send(command);
const response = await this.getClient().send(command, options);

this.logHandler.debug("CLOUDFORMATION CLIENT - Delete Change set Response", {input, response}, AwsModuleKeyname)

Expand All @@ -223,14 +232,14 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Describes a Change Set.
* @param input The input to describe a change set.
* @param retryNumber
* @param options
*/
async describeChangeSet(input: DescribeChangeSetCommandInput): Promise<DescribeChangeSetCommandOutput> {
async describeChangeSet(input: DescribeChangeSetCommandInput, options?: Partial<ClientOptionsInterface>): Promise<DescribeChangeSetCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Describe Change Set", {input}, AwsModuleKeyname);
const command = new DescribeChangeSetCommand(input)
try {

const response = await this.getClient().send(command);
const response = await this.getClient().send(command, options);

this.logHandler.debug("CLOUDFORMATION CLIENT - Describe Change set Response", {input, response}, AwsModuleKeyname)

Expand All @@ -244,13 +253,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Executes a Change Set.
* @param input The input to execute a change set.
* @param retryNumber
* @param options
*/
async executeChangeSet(input: ExecuteChangeSetCommandInput): Promise<ExecuteChangeSetCommandOutput> {
async executeChangeSet(input: ExecuteChangeSetCommandInput, options?: Partial<ClientOptionsInterface>): Promise<ExecuteChangeSetCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - Execute Change Set", {input}, AwsModuleKeyname);
const command = new ExecuteChangeSetCommand(input)
try {
const response = await this.getClient().send(command);
const response = await this.getClient().send(command, options);

this.logHandler.debug("CLOUDFORMATION CLIENT - Execute Change set Response", {input, response}, AwsModuleKeyname)

Expand All @@ -264,12 +273,13 @@ export class CloudformationClient implements CloudformationClientInterface {
/**
* Lists a Change Set.
* @param input The input to list a change set.
* @param options
*/
async listChangeSets(input: ListChangeSetsCommandInput): Promise<ListChangeSetsCommandOutput> {
async listChangeSets(input: ListChangeSetsCommandInput, options?: Partial<ClientOptionsInterface>): Promise<ListChangeSetsCommandOutput> {
this.logHandler.debug("CLOUDFORMATION CLIENT - List Change Sets", {input}, AwsModuleKeyname);
const command = new ListChangeSetsCommand(input)
try {
const response = await this.getClient().send(command);
const response = await this.getClient().send(command, options);

this.logHandler.debug("CLOUDFORMATION CLIENT - List Change set Response", {input, response}, AwsModuleKeyname)

Expand All @@ -289,7 +299,7 @@ export class CloudformationClient implements CloudformationClientInterface {
* @param capabilities
* @param statusCallback
*/
async deployStack(stackName: string, cloudformationTemplateS3Url: string, stackParameters: { [key in string]: string }, capabilities: Capability[], statusCallback?: (status: CloudformationDeploymentStatusEnum, changeSetName?: string) => void): Promise<CloudformationDeploymentStatusEnum> {
async deployStack(stackName: string, cloudformationTemplateS3Url: string, stackParameters: { [key in string]: string }, capabilities: Capability[], statusCallback?: (status: CloudformationDeploymentStatusEnum, changeSetName?: string) => void, options?: Partial<ClientOptionsInterface>): Promise<CloudformationDeploymentStatusEnum> {
const parameters: Parameter[] = [];

for (const key in stackParameters) {
Expand All @@ -307,7 +317,7 @@ export class CloudformationClient implements CloudformationClientInterface {
// Check if the stack exists or not first.
let changeSetType: ChangeSetType = ChangeSetType.UPDATE;

const stack = await this.getStackDescription(stackName);
const stack = await this.getStackDescription(stackName, options);

if (stack === undefined) {
changeSetType = ChangeSetType.CREATE;
Expand All @@ -322,12 +332,12 @@ export class CloudformationClient implements CloudformationClientInterface {
ChangeSetName: changeSetName,
ChangeSetType: changeSetType,
OnStackFailure: OnStackFailure.ROLLBACK,
}
}, options
);

this.logHandler.debug("After calling createChangeSet", {stack, response, changeSetName, stackName}, AwsModuleKeyname)

const status = await this.monitorChangeSet(stackName, changeSetName);
const status = await this.monitorChangeSet(stackName, changeSetName, undefined, options);

switch (status) {
case CloudformationDeploymentStatusEnum.Failed:
Expand All @@ -343,17 +353,17 @@ export class CloudformationClient implements CloudformationClientInterface {
await this.executeChangeSet({
StackName: stackName,
ChangeSetName: changeSetName,
})
}, options)

return this.monitorStack(stackName, statusCallback);
return this.monitorStack(stackName, statusCallback, options);
}

private async monitorChangeSet(stackName: string, changeSetName: string, statusCallback?: (status: CloudformationDeploymentStatusEnum, changeSetName: string) => void): Promise<CloudformationDeploymentStatusEnum> {
private async monitorChangeSet(stackName: string, changeSetName: string, statusCallback?: (status: CloudformationDeploymentStatusEnum, changeSetName: string) => void, options?: Partial<ClientOptionsInterface>): Promise<CloudformationDeploymentStatusEnum> {
while (true) {
const response = await this.describeChangeSet({
StackName: stackName,
ChangeSetName: changeSetName,
});
}, options);

this.logHandler.debug("Describe ChangeSet result.", {response}, AwsModuleKeyname)

Expand Down Expand Up @@ -390,9 +400,9 @@ export class CloudformationClient implements CloudformationClientInterface {
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
private async monitorStack(stackName: string, statusCallback?: (status: CloudformationDeploymentStatusEnum) => void): Promise<CloudformationDeploymentStatusEnum> {
private async monitorStack(stackName: string, statusCallback?: (status: CloudformationDeploymentStatusEnum) => void, options?: Partial<ClientOptionsInterface>): Promise<CloudformationDeploymentStatusEnum> {
while (true) {
const response = await this.getStackDescription(stackName);
const response = await this.getStackDescription(stackName, options);

this.logHandler.debug("Stack Description result.", {response}, AwsModuleKeyname)

Expand Down
11 changes: 7 additions & 4 deletions packages/aws/src/clients/cloudfront.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import {CloudfrontClientInterface} from "../interfaces/cloudfront-client.interface";
import {DescribeStacksCommand, DescribeStacksCommandOutput} from "@aws-sdk/client-cloudformation";
import { v4 as uuidv4 } from 'uuid';
import {ClientOptionsInterface} from "../interfaces/client-options.interface";

/**
* The client to use to interact with AWS Cloudformation. It is a wrapper around the Cloudfront of @aws-sdk/client-cloudfront.
Expand Down Expand Up @@ -58,8 +59,9 @@ export class CloudfrontClient implements CloudfrontClientInterface {
*
* @param distributionId
* @param paths
* @param options
*/
async invalidate(distributionId: string, paths: string[]): Promise<CreateInvalidationResult> {
async invalidate(distributionId: string, paths: string[], options?: Partial<ClientOptionsInterface>): Promise<CreateInvalidationResult> {
this.logHandler.debug("CloudFront CLIENT - Invalidating", {distributionId, paths}, AwsModuleKeyname);
const command = new CreateInvalidationCommand({
DistributionId: distributionId,
Expand All @@ -72,7 +74,7 @@ export class CloudfrontClient implements CloudfrontClientInterface {
}
})
try {
const response: CreateInvalidationResult = await this.getClient().send(command);
const response: CreateInvalidationResult = await this.getClient().send(command, options);

if(response === undefined) {
throw new Error("Unknown error invalidating the CloudFront distribution");
Expand All @@ -90,16 +92,17 @@ export class CloudfrontClient implements CloudfrontClientInterface {
*
* @param distributionId
* @param invalidationId
* @param options
*/
async getInvalidation(distributionId: string, invalidationId: string): Promise<GetInvalidationResult> {
async getInvalidation(distributionId: string, invalidationId: string, options?: Partial<ClientOptionsInterface>): Promise<GetInvalidationResult> {
this.logHandler.debug("CloudFront CLIENT - Get Invalidating", {distributionId, invalidationId}, AwsModuleKeyname);
const command = new GetInvalidationCommand({
DistributionId: distributionId,
Id: invalidationId,
})

try {
const response: GetInvalidationResult = await this.getClient().send(command);
const response: GetInvalidationResult = await this.getClient().send(command, options);

if(response === undefined) {
throw new Error("Unknown error invalidating the CloudFront distribution");
Expand Down
6 changes: 4 additions & 2 deletions packages/aws/src/clients/event-bridge.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {EventBridgeSendMessageError} from "../errors/event-bridge-send-message.e
import {EventBridgeClientInterface} from "../interfaces/event-bridge-client.interface";
import {moduleScoped, tag} from "@pristine-ts/common";
import {AwsModuleKeyname} from "../aws.module.keyname";
import {ClientOptionsInterface} from "../interfaces/client-options.interface";

/**
* The client to use to interact with AWS Event Bridge. It is a wrapper around the AwsEventBridgeClient of @aws-sdk/client-eventbridge.
Expand Down Expand Up @@ -43,9 +44,10 @@ export class EventBridgeClient implements EventBridgeClientInterface {
* Sends an event to event bridge.
* @param eventBridgeMessages The messages to send to event bridge.
* @param eventBusName The event bus name where to send the messages.
* @param options
* @param endpoint The endpoint for event bridge.
*/
async send(eventBridgeMessages: EventBridgeMessageModel | EventBridgeMessageModel[], eventBusName: string, endpoint?: string): Promise<void> {
async send(eventBridgeMessages: EventBridgeMessageModel | EventBridgeMessageModel[], eventBusName: string, endpoint?: string, options?: Partial<ClientOptionsInterface>): Promise<void> {
try {
const client = this.getClient(endpoint);

Expand Down Expand Up @@ -79,7 +81,7 @@ export class EventBridgeClient implements EventBridgeClientInterface {
}]
}

const response = await client.send(putEventsCommand);
const response = await client.send(putEventsCommand, options);

this.logHandler.debug("Message successfully sent to the EventBridge", {
eventBridgeMessages,
Expand Down
Loading

0 comments on commit 17b3fa1

Please sign in to comment.