UNPKG

lifion-kinesis

Version:

Lifion client for Amazon Kinesis Data streams

138 lines (124 loc) 4.74 kB
/** * A module with statics to handle DynamoDB tables. * * @module table * @private */ 'use strict'; const equal = require('fast-deep-equal'); /** * Checks if the specified table exists and would wait until the table is deleted or activated * if the table is in the middle of an update. * * @param {Object} params - The params. * @param {Object} params.client - An instance of the DynamoDB client. * @param {Object} params.logger - A logger instance. * @param {string} params.tableName - The name of the table to check. * @returns {Promise<string>} If the table exists, the ARN of the table, `null` otherwise. * @private */ async function checkIfTableExists({ client, logger, tableName }) { try { const params = { TableName: tableName }; const { Table } = await client.describeTable(params); const { TableArn, TableStatus } = Table; if (TableStatus === 'DELETING') { logger.debug('Waiting for the table to complete deletion…'); await client.waitFor('tableNotExists', params); logger.debug('The table is now gone.'); return null; } if (TableStatus && TableStatus !== 'ACTIVE') { logger.debug('Waiting for the table to be active…'); await client.waitFor('tableExists', params); logger.debug('The table is now active.'); } return TableArn; } catch (err) { if (err.code !== 'ResourceNotFoundException') { logger.error(err); throw err; } return null; } } /** * Ensures that the table is tagged as expected by reading the tags then updating them if needed. * * @param {Object} params - The params. * @param {Object} params.client - An instance of the DynamoDB client. * @param {Object} params.logger - A logger instance. * @param {string} params.tableArn - The ARN of the table to check the tags for. * @param {Object} params.tags - The tags that should be present in the table. * @returns {Promise<void>} * @memberof module:table */ async function confirmTableTags({ client, logger, tableArn, tags }) { const params = { ResourceArn: tableArn }; let { Tags } = await client.listTagsOfResource(params); const existingTags = Tags.reduce((obj, { Key, Value }) => ({ ...obj, [Key]: Value }), {}); const mergedTags = { ...existingTags, ...tags }; if (!equal(existingTags, mergedTags)) { Tags = Object.entries(mergedTags).map(([Key, Value]) => ({ Key, Value })); await client.tagResource({ ...params, Tags }); logger.debug('The table tags have been updated.'); } else { logger.debug('The table is already tagged as required.'); } } /** * Creates a table and waits until its activation. * * @param {Object} params - The params. * @param {Object} params.client - An instance of the DynamoDB client. * @param {Object} params.logger - A logger instance. * @param {Object} [params.provisionedThroughput] - The provisioned throughput for the new table. * @param {Object} params.provisionedThroughput.readCapacityUnits - The number of RCUs. * @param {Object} params.provisionedThroughput.writeCapacityUnits - The number of WCUs. * @param {string} params.tableName - The name of the table to create. * @returns {Promise<string>} The ARN of the new table. * @memberof module:table */ async function ensureTableExists(params) { const { client, logger, provisionedThroughput, tableName } = params; logger.debug(`Verifying the "${tableName}" table exists and it's active…`); const tableArn = await checkIfTableExists(params); if (!tableArn) { logger.debug('Trying to create the table…'); let billingMode = { BillingMode: 'PAY_PER_REQUEST' }; if (provisionedThroughput) { const { readCapacityUnits, writeCapacityUnits } = provisionedThroughput; billingMode = { ProvisionedThroughput: { ReadCapacityUnits: readCapacityUnits, WriteCapacityUnits: writeCapacityUnits } }; } await client.createTable({ ...billingMode, AttributeDefinitions: [ { AttributeName: 'consumerGroup', AttributeType: 'S' }, { AttributeName: 'streamName', AttributeType: 'S' } ], KeySchema: [ { AttributeName: 'consumerGroup', KeyType: 'HASH' }, { AttributeName: 'streamName', KeyType: 'RANGE' } ], SSESpecification: { Enabled: true }, TableName: tableName }); logger.debug('Waiting for the new table to be active…'); const { Table } = await client.waitFor('tableExists', { TableName: tableName }); logger.debug('The new table is now active.'); return Table.TableArn; } logger.debug("The table exists and it's active."); return tableArn; } module.exports = { confirmTableTags, ensureTableExists };