UNPKG

@cumulus/aws-client

Version:
178 lines 6.98 kB
"use strict"; /** * @module DynamoDb */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.deleteAndWaitForDynamoDbTableNotExists = exports.createAndWaitForDynamoDbTable = exports.parallelScan = exports.scan = exports.get = void 0; const p_map_1 = __importDefault(require("p-map")); const p_retry_1 = __importDefault(require("p-retry")); const range_1 = __importDefault(require("lodash/range")); const client_dynamodb_1 = require("@aws-sdk/client-dynamodb"); const errors_1 = require("@cumulus/errors"); const services_1 = require("./services"); const utils_1 = require("./utils"); /** * Call DynamoDb client get * * See [DocumentClient.get()](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html) * for descriptions of `params` and the return data. * * @param {Object} params * @param {string} params.tableName - Table name to read * @param {GetCommandInput.Key} params.item - Key identifying object to get * @param {DynamoDBDocument} params.client - Instance of a DynamoDb DocumentClient * @param {Object} params.getParams - Additional parameters for DocumentClient.get() * @returns {Promise<Object>} * @throws {RecordDoesNotExist} if a record cannot be found */ const get = async (params) => { const { client, getParams = {}, item, tableName, } = params; const getResponse = await client.get({ ...getParams, TableName: tableName, Key: item, }); if (getResponse.Item) return getResponse.Item; throw new errors_1.RecordDoesNotExist(`No record found for ${JSON.stringify(item)} in ${tableName}`); }; exports.get = get; /** * Call DynamoDb client scan * * See [DocumentClient.scan()](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html) * for descriptions of `params` and the return data. * * @param {Object} params * @returns {Promise<Object>} */ exports.scan = (0, utils_1.improveStackTrace)(async (params) => { const { client, fields, limit, query, select, startKey, tableName, } = params; const scanParams = { TableName: tableName, }; if (query) { if (query.filter && query.values) { scanParams.FilterExpression = query.filter; scanParams.ExpressionAttributeValues = query.values; } if (query.names) { scanParams.ExpressionAttributeNames = query.names; } } if (fields) { scanParams.ProjectionExpression = fields; } if (limit) { scanParams.Limit = limit; } if (select) { scanParams.Select = select; } if (startKey) { scanParams.ExclusiveStartKey = startKey; } const response = await client.scan(scanParams); // recursively go through all the records if (response.LastEvaluatedKey) { const more = await (0, exports.scan)({ tableName, client, query, fields, limit, select, startKey: response.LastEvaluatedKey, }); if (more.Items) { response.Items = (response.Items || []).concat(more.Items); } if (typeof response.Count === 'number' && typeof more.Count === 'number') { response.Count += more.Count; } } return response; }); /** * Do a parallel scan of DynamoDB table using a document client. * * See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan. * See [DocumentClient.scan()](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html). * * @param {Object} params * @param {number} params.totalSegments * Total number of segments to divide table into for parallel scanning * @param {ScanInput} params.scanParams * Params for the DynamoDB client scan operation * See https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html * @param {function} params.processItemsFunc - Function used to process returned items by scan * @param {DynamoDBDocument} [params.dynamoDbClient] - Instance of Dynamo DB document client * @param {pRetry.Options} [params.retryOptions] - Retry options for scan operations * @returns {Promise} */ const parallelScan = async (params) => { const { totalSegments, scanParams, processItemsFunc, dynamoDbClient, retryOptions, } = params; return await (0, p_map_1.default)((0, range_1.default)(totalSegments), async (_, segmentIndex) => { let exclusiveStartKey; const segmentScanParams = { ...scanParams, TotalSegments: totalSegments, Segment: segmentIndex, }; /* eslint-disable no-await-in-loop */ do { const { Items = [], LastEvaluatedKey, } = await (0, p_retry_1.default)(() => dynamoDbClient.scan(segmentScanParams), retryOptions); exclusiveStartKey = LastEvaluatedKey; segmentScanParams.ExclusiveStartKey = exclusiveStartKey; await processItemsFunc(Items); } while (exclusiveStartKey); /* eslint-enable no-await-in-loop */ return Promise.resolve(); }, { stopOnError: false, }); }; exports.parallelScan = parallelScan; /** * Create a DynamoDB table and then wait for the table to exist * * @param {Object} params - the same params that you would pass to AWS.createTable * See https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/classes/dynamodb.html#createtable * @returns {Promise<Object>} the output of the createTable call * * @static */ async function createAndWaitForDynamoDbTable(params) { const dynamoDbClient = (0, services_1.dynamodb)(); const createTableResult = await dynamoDbClient.createTable(params); await (0, client_dynamodb_1.waitUntilTableExists)({ client: dynamoDbClient, minDelay: 1, maxWaitTime: 3, }, { TableName: params.TableName }); return createTableResult; } exports.createAndWaitForDynamoDbTable = createAndWaitForDynamoDbTable; /** * Delete a DynamoDB table and then wait for the table to not exist * * @param {Object} params - the same params that you would pass to AWS.deleteTable * See https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/classes/dynamodb.html#deletetable * @returns {Promise} * * @static */ async function deleteAndWaitForDynamoDbTableNotExists(params) { const dynamoDbClient = (0, services_1.dynamodb)(); await dynamoDbClient.deleteTable(params); await (0, client_dynamodb_1.waitUntilTableNotExists)({ client: dynamoDbClient, minDelay: 1, maxWaitTime: 3, }, { TableName: params.TableName }); } exports.deleteAndWaitForDynamoDbTableNotExists = deleteAndWaitForDynamoDbTableNotExists; //# sourceMappingURL=DynamoDb.js.map