Skip to content

Migrate to AWS SDK V3 - Part 1 #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .github/workflows/integrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,24 @@ jobs:
run: |
npm update --no-save
npm update --save-dev --no-save
- name: Unit tests
- name: Unit tests (AWS SDK v2)
# Some tests depend on TTY support, which is missing in GA runner
# Workaround taken from https://github.com/actions/runner/issues/241#issuecomment-577360161
run: script -e -c "npm test -- -b"
- name: Packaging tests
env:
SLS_AWS_SDK_V3: '0'
- name: Unit tests (AWS SDK v3)
run: script -e -c "npm test -- -b"
env:
SLS_AWS_SDK_V3: '1'
- name: Packaging tests (AWS SDK v2)
run: npm run integration-test-run-package
env:
SLS_AWS_SDK_V3: '0'
- name: Packaging tests (AWS SDK v3)
run: npm run integration-test-run-package
env:
SLS_AWS_SDK_V3: '1'

windowsNode16:
name: '[Windows] Node 16: Unit tests'
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,24 @@ jobs:
then
npx dump-release-notes-from-cc-changelog $NEW_VERSION
fi
- name: Unit tests
- name: Unit tests (AWS SDK v2)
# Some tests depend on TTY support, which is missing in GA runner
# Workaround taken from https://github.com/actions/runner/issues/241#issuecomment-577360161
run: script -e -c "npm test -- -b"
- name: Packaging tests
env:
SLS_AWS_SDK_V3: '0'
- name: Unit tests (AWS SDK v3)
run: script -e -c "npm test -- -b"
env:
SLS_AWS_SDK_V3: '1'
- name: Packaging tests (AWS SDK v2)
run: npm run integration-test-run-package
env:
SLS_AWS_SDK_V3: '0'
- name: Packaging tests (AWS SDK v3)
run: npm run integration-test-run-package
env:
SLS_AWS_SDK_V3: '1'

windowsNode16:
name: '[Windows] Node 16: Unit tests'
Expand Down
101 changes: 101 additions & 0 deletions lib/aws/client-factory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use strict';

const { APIGatewayClient } = require('@aws-sdk/client-api-gateway');
const { ApiGatewayV2Client } = require('@aws-sdk/client-apigatewayv2');
const { CloudFormationClient } = require('@aws-sdk/client-cloudformation');
const { CloudWatchClient } = require('@aws-sdk/client-cloudwatch');
const { CloudWatchLogsClient } = require('@aws-sdk/client-cloudwatch-logs');
const { CognitoIdentityProviderClient } = require('@aws-sdk/client-cognito-identity-provider');
const { ECRClient } = require('@aws-sdk/client-ecr');
const { EventBridgeClient } = require('@aws-sdk/client-eventbridge');
const { IAMClient } = require('@aws-sdk/client-iam');
const { LambdaClient } = require('@aws-sdk/client-lambda');
const { S3Client } = require('@aws-sdk/client-s3');
const { SSMClient } = require('@aws-sdk/client-ssm');
const { STSClient } = require('@aws-sdk/client-sts');

// Map service names to their client classes
const CLIENT_MAP = {
APIGateway: APIGatewayClient,
ApiGatewayV2: ApiGatewayV2Client,
CloudFormation: CloudFormationClient,
CloudWatch: CloudWatchClient,
CloudWatchLogs: CloudWatchLogsClient,
CognitoIdentityProvider: CognitoIdentityProviderClient,
ECR: ECRClient,
EventBridge: EventBridgeClient,
IAM: IAMClient,
Lambda: LambdaClient,
S3: S3Client,
SSM: SSMClient,
STS: STSClient,
};

class AWSClientFactory {
constructor(baseConfig = {}) {
this.baseConfig = baseConfig;
this.clients = new Map();
}

/**
* Get a configured AWS service client
* @param {string} serviceName - Name of the AWS service (e.g., 'S3', 'CloudFormation')
* @param {Object} overrideConfig - Configuration to override base config
* @returns {Object} AWS SDK v3 client instance
*/
getClient(serviceName, overrideConfig = {}) {
const ClientClass = CLIENT_MAP[serviceName];
if (!ClientClass) {
throw new Error(`Unknown AWS service: ${serviceName}`);
}

// Create a cache key based on service and config
const configKey = JSON.stringify({ serviceName, ...this.baseConfig, ...overrideConfig });

if (!this.clients.has(configKey)) {
const clientConfig = { ...this.baseConfig, ...overrideConfig };
this.clients.set(configKey, new ClientClass(clientConfig));
}

return this.clients.get(configKey);
}

/**
* Send a command to an AWS service
* @param {string} serviceName - Name of the AWS service
* @param {Object} command - AWS SDK v3 command instance
* @param {Object} clientConfig - Optional client configuration override
* @returns {Promise} Result of the AWS API call
*/
async send(serviceName, command, clientConfig = {}) {
const client = this.getClient(serviceName, clientConfig);
return client.send(command);
}

/**
* Clear the client cache
*/
clearCache() {
this.clients.clear();
}

/**
* Update the base configuration for all future clients
* @param {Object} newConfig - New base configuration
*/
updateBaseConfig(newConfig) {
this.baseConfig = { ...this.baseConfig, ...newConfig };
// Clear cache to force recreation with new config
this.clearCache();
}

/**
* Get list of supported AWS services
* @returns {Array} Array of supported service names
*/
getSupportedServices() {
return Object.keys(CLIENT_MAP);
}
}

module.exports = AWSClientFactory;
Loading