Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

aws-core-utils

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aws-core-utils - npm Package Compare versions

Comparing version 2.0.1 to 2.1.0

183

kinesis-utils.js
'use strict';
let AWS = require("aws-sdk");
let kinesis = null; // simple, single module-scope cache for an AWS.Kinesis instance
// Module-scope cache of AWS.Kinesis instances by region key
let kinesisByRegionKey = new WeakMap();
// Module-scope cache of the Kinesis options used to construct the AWS.Kinesis instances by region key
let kinesisOptionsByRegionKey = new WeakMap();
// A map of region key objects by region, which is only needed, because WeakMaps can ONLY have object keys
const regionKeysByRegion = new Map();
const regions = require('./regions');
const Strings = require('core-functions/strings');
const stringify = Strings.stringify;
const deepEqual = require('deep-equal');
const strict = {strict:true};
/**
* Utilities for working with AWS.Kinesis and a simple, module-scope cache for a single AWS.Kinesis instance for Lambda.
* Utilities for working with AWS.Kinesis and a module-scope cache of AWS.Kinesis instances by region for Lambda.
* @module aws-core-utils/kinesis-utils

@@ -14,2 +27,6 @@ * @author Byron du Preez

module.exports = {
setKinesis: setKinesis,
getKinesis: getKinesis,
getKinesisOptionsUsed: getKinesisOptionsUsed,
deleteKinesis: deleteKinesis,
configureKinesis: configureKinesis

@@ -19,43 +36,145 @@ };

/**
* Configures the given context, if it does not already have a context.kinesis, with the cached kinesis instance (if
* any and if its region & maxRetries matches the current region and given maxRetries); otherwise with a new AWS.Kinesis
* instance, which will be cached if there is no existing cached instance.
* Creates and caches a new AWS Kinesis instance with the given Kinesis constructor options for either the region
* specified in the given options (if any and region specified) or for the current region (if not) UNLESS a previously
* cached Kinesis instance exists and the given options EITHER match the options used to construct it OR are undefined,
* empty or only region, in which case no new instance will be created and the cached instance will be returned instead.
* If the given options do not match existing options and are not empty and not only region, then logs a warning that
* the previously cached Kinesis instance is being replaced and returns the new AWS Kinesis instance.
*
* Logging should be configured before calling this function (see {@linkcode logging-utils#configureLogging}
*
* @param {Object} context - the context to configure
* @param {number} maxRetries - the maximum number of retries to configure on the AWS.Kinesis instance
* @returns {Object} the given context
* @param {Object|undefined} [kinesisOptions] - the optional Kinesis constructor options to use
* @param {string|undefined} [kinesisOptions.region] - an optional region to use instead of the current region
* @param {Object|undefined} [context] - the context, which is just used for logging
* @returns {Object} an cached or new AWS Kinesis instance created and cached for the specified or current region
*/
function configureKinesis(context, maxRetries) {
const region = regions.getRegion();
function setKinesis(kinesisOptions, context) {
// If no options were specified, then use an empty object
const options = kinesisOptions ? kinesisOptions : {};
const contextKinesisIncompatible = context.kinesis && context.kinesis.config &&
(context.kinesis.config.region !== region || context.kinesis.config.maxRetries !== maxRetries);
if (contextKinesisIncompatible) {
if (context.warnEnabled) context.warn(`Existing context.kinesis with region (${context.kinesis.config.region}) & maxRetries (${context.kinesis.config.maxRetries}) is incompatible with region (${region}) & maxRetries (${maxRetries}) and will be replaced!`);
// If no region was specified in the given kinesis options, then set it to the current region
let region = options.region;
if (!region) {
const currentRegion = regions.getRegion();
options.region = currentRegion;
region = currentRegion;
}
const regionKey = getRegionKey(region);
if (!context.kinesis || contextKinesisIncompatible) {
if (kinesis && kinesis.config) {
if (kinesis.config.region === region && kinesis.config.maxRetries === maxRetries) {
// Use cached kinesis instance
if (context.debugEnabled) context.debug(`Using cached kinesis instance with region (${kinesis.config.region}) & maxRetries (${kinesis.config.maxRetries})`);
context.kinesis = kinesis;
} else {
// Cached kinesis instance has the wrong region and/or maxRetries, so create a new one
if (context.debugEnabled) context.debug(`Cached kinesis has incompatible region (${kinesis.config.region}) & maxRetries (${kinesis.config.maxRetries}), so creating a new context.kinesis with region (${region}) & maxRetries (${maxRetries})`);
context.kinesis = new AWS.Kinesis({region: region, maxRetries: maxRetries});
}
// Check if there is already a Kinesis instance cached for this region
let kinesis = kinesisByRegionKey.get(regionKey);
if (kinesis) {
const logInfo = context && context.info ? context.info : console.log;
// If caller specified no options, then accept the cached instance for the current region (regardless of its options)
if (!kinesisOptions || Object.getOwnPropertyNames(kinesisOptions).length === 0) {
logInfo(`Reusing cached Kinesis instance for region (${region}) with ANY options, since no options were specified`);
return kinesis;
}
// If caller ONLY specified a region, then accept the cached instance for the region (regardless of its options)
if (Object.getOwnPropertyNames(options).length === 1) {
logInfo(`Reusing cached Kinesis instance for region (${region}) with ANY options, since only region was specified`);
return kinesis;
}
// If the given options match the options used to construct the cached instance, then returns the cached instance
const optionsUsed = kinesisOptionsByRegionKey.get(regionKey);
// context.debug(`options = ${JSON.stringify(options)}`);
// context.debug(`optionsUsed = ${JSON.stringify(optionsUsed)}`);
// context.debug(`optionsUsed == options = ${optionsUsed == options}`);
// context.debug(`optionsUsed === options = ${optionsUsed === options}`);
// context.debug(`deepEqual(optionsUsed, options) = ${deepEqual(optionsUsed, options)}`);
if (deepEqual(optionsUsed, options, strict)) {
// Use the cached instance if its config is identical to the modified options
logInfo(`Reusing cached Kinesis instance for region (${region}) with identical options`);
return kinesis;
} else {
// No cached kinesis yet, so create one and cache it
kinesis = new AWS.Kinesis({region: region, maxRetries: maxRetries});
if (context.debugEnabled) context.debug(`Cached a new kinesis instance with region (${kinesis.config.region}) & maxRetries (${kinesis.config.maxRetries})`);
context.kinesis = kinesis;
const logWarn = context && context.warn ? context.warn : console.warn;
logWarn(`Replacing cached Kinesis instance (${stringify(optionsUsed)}) for region (${region}) with new instance (${stringify(options)})`);
}
} else {
if (context.debugEnabled) context.debug(`Using compatible, existing context.kinesis instance with region (${context.kinesis.config.region}) & maxRetries (${context.kinesis.config.maxRetries})`);
}
// Create a new kinesis instance with the modified options
kinesis = new AWS.Kinesis(options);
// Cache the new instance and the options used to create it
kinesisByRegionKey.set(regionKey, kinesis);
kinesisOptionsByRegionKey.set(regionKey, options);
return kinesis;
}
/**
* Deletes the Kinesis instance cached for the given region (if any) and returns true if successfully deleted or false
* if it did not exist.
* @param {string} region - the AWS region to use as a key
* @returns {boolean} true if existed and deleted; false otherwise
*/
function deleteKinesis(region) {
const regionKey = getRegionKey(region);
kinesisOptionsByRegionKey.delete(regionKey);
return kinesisByRegionKey.delete(regionKey);
}
/**
* Gets the Kinesis instance cached for the given region (if specified and if previously cached); otherwise for the
* current region (if previously cached); otherwise returns undefined.
* @param {string} [region] - the optional AWS region to use - defaults to current AWS region if not specified
* @returns {Object|undefined} the Kinesis instance cached for the given or current region (if any); otherwise returns undefined
*/
function getKinesis(region) {
const regionKey = getRegionKey(region ? region : regions.getRegion());
return kinesisByRegionKey.get(regionKey);
}
/**
* Gets the kinesis options used to construct the Kinesis instance cached for the given region (if specified and if
* previously cached); otherwise for the current region (if previously cached); otherwise returns undefined.
* @param {string} [region] - the optional AWS region to use - defaults to current AWS region if not specified
* @returns {Object|undefined} the kinesis options used to construct the Kinesis instance cached for the given or
* current region (if any); otherwise returns undefined
*/
function getKinesisOptionsUsed(region) {
const regionKey = getRegionKey(region ? region : regions.getRegion());
return kinesisOptionsByRegionKey.get(regionKey);
}
function getRegionKey(region) {
let regionKey = regionKeysByRegion.get(region);
if (!regionKey) {
regionKey = {region: region};
regionKeysByRegion.set(region, regionKey);
}
return regionKey;
}
/**
* Creates and caches a new AWS Kinesis instance with the given Kinesis constructor options for either the region
* specified in the given options (if any and region specified) or for the current region (if not) UNLESS a previously
* cached Kinesis instance exists and the given options either match the options used to construct it or are undefined,
* empty or only region was specified, in which case no new instance will be created and the cached instance will
* be returned instead. If the given options do not match existing options and are not empty and not only region, then
* logs a warning that the previously cached Kinesis instance is being replaced and returns the new AWS Kinesis
* instance.
*
* Logging should be configured before calling this function (see {@linkcode logging-utils#configureLogging}
*
* Configures the given context, if it does not already have a context.kinesis, with the cached kinesis instance for
* either the region specified in the given default kinesis options (if any and region specified) or for the current
* region (if not); otherwise with a new AWS.Kinesis instance created and cached by {@linkcode setKinesis} for
* the specified or current region using the given default Kinesis constructor options.
*
* Note that the given default Kinesis constructor options will ONLY be used if no cached Kinesis instance exists.
*
* Logging should be configured before calling this function (see {@linkcode logging-utils#configureLogging}
*
* @param {Object} context - the context to configure
* @param {Object} [context.kinesis] - the current Kinesis instance cached on the context (if any)
* @param {Object|undefined} [kinesisOptions] - the optional Kinesis constructor options to use if no cached Kinesis
* instance exists
* @param {string|undefined} [kinesisOptions.region] - an optional region to use instead of the current region
* @returns {Object} the given context
*/
function configureKinesis(context, kinesisOptions) {
if (!context.kinesis) {
context.kinesis = setKinesis(kinesisOptions, context);
}
return context;
}

5

package.json
{
"name": "aws-core-utils",
"version": "2.0.1",
"version": "2.1.0",
"description": "Core utilities for working with Amazon Web Services (AWS), including ARNs, regions, stages, Lambdas, AWS errors, stream events, etc.",

@@ -15,3 +15,4 @@ "author": "Byron du Preez",

"core-functions": "^2.0.2",
"logging-utils": "^1.0.5"
"logging-utils": "^1.0.5",
"deep-equal": "^1.0.1"
},

@@ -18,0 +19,0 @@ "devDependencies": {

@@ -1,2 +0,2 @@

# aws-core-utils v2.0.1
# aws-core-utils v2.1.0

@@ -12,3 +12,3 @@ Core utilities for working with Amazon Web Services (AWS), including ARNs, regions, stages, Kinesis, Lambdas, AWS errors, stream events, etc.

- kinesis-utils.js
- Utilities for working with AWS.Kinesis and a module-scope cache for a single AWS.Kinesis instance for Lambda.
- Utilities for working with AWS.Kinesis and a module-scope cache of AWS.Kinesis instances by region for Lambda.
- lambdas.js

@@ -67,9 +67,38 @@ - Utilities for working with AWS Lambda, which enable extraction of function names, versions and, most importantly,

* To use the Kinesis utilities
* To use the Kinesis utilities to cache and configure an AWS Kinesis instance per region
```js
const kinesisUtils = require('aws-core-utils/kinesis-utils');
// Preamble to create a context and configure logging on the context
const context = {};
const logging = require('logging-utils');
logging.configureDefaultLogging(context);
// Define the Kinesis constructor options that you want to use, e.g.
const kinesisOptions = {
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Kinesis.html#constructor-property for full details
maxRetries: 0
// ...
};
// To create and cache a new AWS Kinesis instance with the given Kinesis constructor options for either the current
// region or the region specified in the given options OR reuse a previously cached Kinesis instance (if any) that is
// compatible with the given options
const kinesis = kinesisUtils.setKinesis(kinesisOptions, context);
// To configure a new AWS.Kinesis instance (or re-use a cached instance) on a context
// Currently only creates a new AWS.Kinesis instance with the current AWS region & given maxRetries
kinesisUtils.configureKinesis(context, maxRetries);
kinesisUtils.configureKinesis(context, kinesisOptions);
console.log(context.kinesis);
// To get a previously set or configured AWS Kinesis instance for the current AWS region
const kinesis1 = kinesisUtils.getKinesis();
// ... or for a specified region
const kinesis2 = kinesisUtils.getKinesis('us-west-2');
// To get the original options that were used to construct a cached AWS Kinesis instance for the current or specified AWS region
const optionsUsed1 = kinesisUtils.getKinesisOptionsUsed();
const optionsUsed2 = kinesisUtils.getKinesisOptionsUsed('us-west-1');
// To delete and remove a cached Kinesis instance from the cache
const deleted = kinesisUtils.deleteKinesis('eu-west-1');
```

@@ -121,7 +150,29 @@

// To configure completely customised stage handling of the above 4 functions
stages.configureStageHandling(context, customToStage, convertAliasToStage,
injectStageIntoStreamName, extractStageFromStreamName, streamNameStageSeparator,
injectStageIntoResourceName, extractStageFromResourceName, resourceNameStageSeparator,
injectInCase, extractInCase, defaultStage, forceConfiguration);
// 5. To qualify an unqualified resource name with a stage
const unqualifiedResourceName = 'TestResource';
const stageQualifiedResourceName = stages.toStageQualifiedResourceName(unqualifiedResourceName, stage, context);
// 6. To extract a stage from a qualified resource name
const qualifiedResourceName = 'TestResource_QA';
const stage3 = stages.extractStageFromQualifiedResourceName(qualifiedResourceName, context);
// To configure completely customised stage handling of the above 6 functions
const settings = {
customToStage: customToStage,
convertAliasToStage: convertAliasToStage,
injectStageIntoStreamName: injectStageIntoStreamName,
extractStageFromStreamName: extractStageFromStreamName,
streamNameStageSeparator: streamNameStageSeparator,
injectStageIntoResourceName: injectStageIntoResourceName,
extractStageFromResourceName: extractStageFromResourceName,
resourceNameStageSeparator: resourceNameStageSeparator,
injectInCase: injectInCase,
extractInCase: extractInCase,
defaultStage: defaultStage,
}
stages.configureStageHandling(context, settings, forceConfiguration);

@@ -177,2 +228,15 @@ // To check if stage handling is configured

### 2.1.0
- Changes to `stages` module:
- Changed API of `configureStageHandling` function to accept a setting object instead of the multiple fixed parameters,
to simplify configuration of new, custom settings.
- Minor changes and fixes to code & unit tests to accommodate this change.
- Major overhaul of `kinesis-utils` module to enable full configuration of an AWS Kinesis instance and caching of a Kinesis
instance per region.
- Added `setKinesis`, `getKinesis`, `getKinesisOptionsUsed` & `deleteKinesis` functions and unit tests for same.
- Rewrote and changed API of `configureKinesis` function to use the new `setKinesis` function and patched its unit tests.
- Technically should have been a 3.0.0 release semantically speaking, since I changed the APIs of two existing functions,
but it did not seem warranted.
### 2.0.1

@@ -179,0 +243,0 @@ - Added new `kinesis-utils` module to provide basic configuration and caching of an AWS.Kinesis instance for Lambda

@@ -92,8 +92,10 @@ 'use strict';

/**
* Configures the given context with the given stage handling settings, but only if stage handling is not already
* configured on the given context OR if forceConfiguration is true. The stage handling settings determine how
* {@linkcode resolveStage}, {@linkcode toStageQualifiedStreamName}, {@linkcode extractStageFromQualifiedStreamName},
* {@linkcode toStageQualifiedResourceName}, {@linkcode extractStageFromQualifiedStreamName} and other internal
* functions will behave when invoked.
* Stage handling settings used for configuring and customising stage handling behaviour. The stage handling settings
* determine how {@linkcode resolveStage}, {@linkcode toStageQualifiedStreamName},
* {@linkcode extractStageFromQualifiedStreamName}, {@linkcode toStageQualifiedResourceName},
* {@linkcode extractStageFromQualifiedStreamName} and other internal functions will behave when invoked.
*
* NB: Add any, new custom settings that you need for any custom implementations of some or all of the stage handling
* functions that you develop and configure via {@linkcode configureStageHandling}.
*
* Notes:

@@ -108,48 +110,44 @@ * - If injectInCase is set to 'upper' then extractInCase should typically be set to 'lower'.

*
* @param {Object} context the context onto which to configure stage handling settings
*
* @param {Function|undefined} [customToStage] - an optional custom function that accepts: an AWS event; an AWS context;
* @typedef {Object} StageHandlingSettings
* @property {Function|undefined} [customToStage] - an optional custom function that accepts: an AWS event; an AWS context;
* and a context, and somehow extracts a usable stage from the AWS event and/or AWS context.
*
* @param {Function|undefined} [convertAliasToStage] - an optional function that accepts: an extracted alias (if any);
* @property {Function|undefined} [convertAliasToStage] - an optional function that accepts: an extracted alias (if any);
* an AWS event; an AWS context; and a context, and converts the alias into a stage
* @param {Function|undefined} [injectStageIntoStreamName] - an optional function that accepts: an unqualified stream
* @property {Function|undefined} [injectStageIntoStreamName] - an optional function that accepts: an unqualified stream
* name; a stage; and a context, and returns a stage-qualified stream name (effectively the reverse function of the
* extractStageFromStreamName function)
*
* @param {Function|undefined} [extractStageFromStreamName] - an optional function that accepts: a stage-qualified
* @property {Function|undefined} [extractStageFromStreamName] - an optional function that accepts: a stage-qualified
* stream name; and a context, and extracts a stage from the stream name
*
* @param {string|undefined} [streamNameStageSeparator] - an optional non-blank separator to use to extract a stage from
* @property {string|undefined} [streamNameStageSeparator] - an optional non-blank separator to use to extract a stage from
* a stage-qualified stream name or inject a stage into an unqualified stream name
*
* @param {Function|undefined} [injectStageIntoResourceName] - an optional function that accepts: an unqualified
* @property {Function|undefined} [injectStageIntoResourceName] - an optional function that accepts: an unqualified
* resource name; a stage; and a context, and returns a stage-qualified resource name (effectively the reverse function
* of the extractStageFromResourceName function)
*
* @param {Function|undefined} [extractStageFromResourceName] - an optional function that accepts: a stage-qualified
* @property {Function|undefined} [extractStageFromResourceName] - an optional function that accepts: a stage-qualified
* resource name; and a context, and extracts a stage from the resource name
*
* @param {string|undefined} [resourceNameStageSeparator] - an optional non-blank separator to use to extract a stage
* @property {string|undefined} [resourceNameStageSeparator] - an optional non-blank separator to use to extract a stage
* from a stage-qualified resource name or inject a stage into an unqualified resource name
*
* @param {string|undefined} [injectInCase] - optionally specifies whether to convert an injected stage to uppercase (if
* @property {string|undefined} [injectInCase] - optionally specifies whether to convert an injected stage to uppercase (if
* 'upper' or 'uppercase') or to lowercase (if 'lowercase' or 'lower') or keep it as given (if 'as_is' or anything else)
*
* @param {string|undefined} [extractInCase] - optionally specifies whether to convert an extracted stage to uppercase
* @property {string|undefined} [extractInCase] - optionally specifies whether to convert an extracted stage to uppercase
* (if 'upper' or 'uppercase') or to lowercase (if 'lowercase' or 'lower') or keep it as extracted (if 'as_is' or
* anything else)
* @property {string|undefined} [defaultStage] - an optional default stage to use as a last resort if all other attempts fail
*/
/**
* Configures the given context with the given stage handling settings, but only if stage handling is not already
* configured on the given context OR if forceConfiguration is true. The stage handling settings determine how
* {@linkcode resolveStage}, {@linkcode toStageQualifiedStreamName}, {@linkcode extractStageFromQualifiedStreamName},
* {@linkcode toStageQualifiedResourceName}, {@linkcode extractStageFromQualifiedStreamName} and other internal
* functions will behave when invoked.
*
* @param {string|undefined} [defaultStage] - an optional default stage to use as a last resort if all other attempts fail
*
* @param {Object} context the context onto which to configure stage handling settings
* @param {StageHandlingSettings} [context.stageHandling] - previously configured stage handling settings on the context (if any)
* @param {StageHandlingSettings} settings - the new stage handling settings to use
* @param {boolean|undefined} [forceConfiguration] - whether or not to force configuration of the given settings, which
* will override any previously configured stage handling settings on the given context
*
* @return {Object} the context object configured with stage handling settings
*/
function configureStageHandling(context, customToStage, convertAliasToStage,
injectStageIntoStreamName, extractStageFromStreamName, streamNameStageSeparator,
injectStageIntoResourceName, extractStageFromResourceName, resourceNameStageSeparator,
injectInCase, extractInCase, defaultStage, forceConfiguration) {
function configureStageHandling(context, settings, forceConfiguration) {

@@ -162,19 +160,3 @@ // If forceConfiguration is false check if the given context already has stage resolution configured on it

// Configure the stage handling settings
context.stageHandling = {
customToStage: customToStage,
convertAliasToStage: convertAliasToStage,
injectStageIntoStreamName: injectStageIntoStreamName,
extractStageFromStreamName: extractStageFromStreamName,
streamNameStageSeparator: streamNameStageSeparator,
injectStageIntoResourceName: injectStageIntoResourceName,
extractStageFromResourceName: extractStageFromResourceName,
resourceNameStageSeparator: resourceNameStageSeparator,
injectInCase: injectInCase,
extractInCase: extractInCase,
defaultStage: defaultStage,
};
context.stageHandling = settings;
return context;

@@ -202,3 +184,4 @@ }

*
* @param {Object} context - the context onto which to configure stage handling settings
* @param {Object} context - the context onto which to configure the default stage handling settings
* @param {StageHandlingSettings} [context.stageHandling] - previously configured stage handling settings on the context (if any)
* @param {boolean|undefined} forceConfiguration - whether or not to force configuration of the given settings, which

@@ -228,6 +211,21 @@ * will override any previously configured stage handling settings on the given context

return configureStageHandling(context, undefined, convertAliasToStage,
toStageSuffixedStreamName, extractStageFromSuffixedStreamName, streamNameStageSeparator,
toStageSuffixedResourceName, extractStageFromSuffixedResourceName, resourceNameStageSeparator,
injectInCase, extractInCase, undefined, forceConfiguration);
const settings = {
customToStage: undefined,
convertAliasToStage: convertAliasToStage,
injectStageIntoStreamName: toStageSuffixedStreamName,
extractStageFromStreamName: extractStageFromSuffixedStreamName,
streamNameStageSeparator: streamNameStageSeparator,
injectStageIntoResourceName: toStageSuffixedResourceName,
extractStageFromResourceName: extractStageFromSuffixedResourceName,
resourceNameStageSeparator: resourceNameStageSeparator,
injectInCase: injectInCase,
extractInCase: extractInCase,
defaultStage: undefined,
};
return configureStageHandling(context, settings, forceConfiguration);
}

@@ -260,2 +258,4 @@

* If no stage handling settings have been configured yet, then configure the given context with the default settings.
* @param {Object} context - the context to configure with default logging and stage handling
* @param {string} caller - a short description to identify the caller of this function
*/

@@ -315,6 +315,7 @@ function configureDefaultStageHandlingIfNotConfigured(context, caller) {

* @param {Object} awsContext - the AWS context, which was passed to your lambda
* @param {Object} context - the context, which can also be used to pass additional configuration through to any custom
* convertAliasToStage or extractStageFromStreamName functions that you configured
* @param {Object} context - the context to use, which will contain any and all of the pre-configured settings
* @param {string|undefined} [context.stage] - an optional stage on the given context, which will short-circuit
* resolution to this stage (if non-blank)
* @param {StageHandlingSettings|undefined} [context.stageHandling] - the configured stage handling settings (if any) on
* the given context, which can be used to pass additional configuration through to any custom functions that you configured
* @param {Function|undefined} [context.stageHandling.customToStage] - an optional custom function that accepts: an

@@ -714,2 +715,3 @@ * AWS event; an AWS context; and a context, and somehow extracts and returns a usable stage from the AWS event and/or

* @param {Object} context - a context on which to set the stage
* @param {Object} [context.stage] - a context on which to set the stage
* @param {Object} event - the AWS event

@@ -716,0 +718,0 @@ * @param {Object} awsContext - the AWS context, which was passed to your lambda

@@ -12,2 +12,5 @@ 'use strict';

const kinesisUtils = require('../kinesis-utils');
const setKinesis = kinesisUtils.setKinesis;
const getKinesis = kinesisUtils.getKinesis;
const deleteKinesis = kinesisUtils.deleteKinesis;
const configureKinesis = kinesisUtils.configureKinesis;

@@ -17,10 +20,11 @@

const getRegion = regions.getRegion;
const getRegionRaw = regions.ONLY_FOR_TESTING.getRegionRaw;
// const getRegionRaw = regions.ONLY_FOR_TESTING.getRegionRaw;
// const getDefaultRegion = regions.getDefaultRegion;
// const resolveRegion = regions.resolveRegion;
const setRegionIfNotSet = regions.ONLY_FOR_TESTING.setRegionIfNotSet;
// const setRegionIfNotSet = regions.ONLY_FOR_TESTING.setRegionIfNotSet;
const logging = require('logging-utils');
// const Strings = require('core-functions/strings');
const Strings = require('core-functions/strings');
const stringify = Strings.stringify;
// const isBlank = Strings.isBlank;

@@ -32,2 +36,120 @@ // const isNotBlank = Strings.isNotBlank;

// =====================================================================================================================
// Tests for setKinesis and getKinesis
// =====================================================================================================================
test('setKinesis and getKinesis', t => {
const context = {};
logging.configureLogging(context, logging.TRACE);
// Set current region
process.env.AWS_REGION = 'us-west-1';
const region1 = getRegion();
t.equal(region1, 'us-west-1', `current region must be us-west-1`);
deleteKinesis(region1); // make sure none before we start
t.notOk(getKinesis(), `getKinesis() kinesis instance must not be cached yet`);
t.notOk(getKinesis(region1), `getKinesis(${region1}) kinesis instance must not be cached yet`);
// Cache new kinesis for current region
const options0 = {};
const kinesis0 = setKinesis(options0, context);
t.ok(kinesis0, `setKinesis(${stringify(options0)}) must return an instance`);
t.equal(kinesis0.config.region, region1, `kinesis 0 region must be ${region1}`);
t.equal(kinesis0.config.maxRetries, undefined, `kinesis 0 maxRetries (${kinesis0.config.maxRetries}) must be undefined`);
t.equal(getKinesis(), kinesis0, `getKinesis() gets cached instance for current region (${region1})`);
t.equal(getKinesis(region1), kinesis0, `getKinesis(${region1}) gets cached instance`);
// Re-use cached kinesis for options with explicit region same as current
const options1 = { region: region1 }; //, maxRetries: 0 };
const kinesis1 = setKinesis(options1, context);
t.ok(kinesis1, `setKinesis(${stringify(options1)}) must return an instance`);
t.equal(kinesis1.config.region, region1, `kinesis 1 region must be ${region1}`);
t.equal(kinesis1.config.maxRetries, undefined, `kinesis 1 maxRetries must be undefined`);
t.equal(kinesis1, kinesis0, `setKinesis(${stringify(options1)}) must re-use cached instance 0 with same options`);
t.equal(getKinesis(), kinesis0, `getKinesis() gets cached instance 0 for current region (${region1})`);
t.equal(getKinesis(region1), kinesis0, `getKinesis(${region1}) gets cached instance 0`);
// Force replacement of cached instance when options differ
const maxRetries2 = 0; //kinesis1.config.maxRetries ? kinesis1.config.maxRetries * 2;
const options2 = { region: region1, maxRetries: maxRetries2 };
const kinesis2 = setKinesis(options2, context);
t.ok(kinesis2, `setKinesis(${stringify(options2)}) must return an instance`);
t.equal(kinesis2.config.region, region1, `kinesis 2 region must be ${region1}`);
t.equal(kinesis2.config.maxRetries, maxRetries2, `kinesis 2 maxRetries must be ${maxRetries2}`);
t.notEqual(kinesis2, kinesis0, `setKinesis(${stringify(options2)}) must replace incompatible cached instance 0`);
t.equal(getKinesis(), kinesis2, `getKinesis() gets cached instance 2 for current region (${region1})`);
t.equal(getKinesis(region1), kinesis2, `getKinesis(${region1}) gets cached instance 2`);
// Re-use newly cached instance when options same, but diff sequence
const maxRetries3 = 0;
const options3 = { maxRetries: maxRetries3, region: region1 };
const kinesis3 = setKinesis(options3, context);
t.ok(kinesis3, `setKinesis(${stringify(options3)}) must return an instance`);
t.equal(kinesis3.config.region, region1, `kinesis 3 region must be ${region1}`);
t.equal(kinesis3.config.maxRetries, maxRetries3, `kinesis 3 maxRetries must be ${maxRetries3}`);
t.equal(kinesis3, kinesis2, `setKinesis(${stringify(options3)}) must re-use cached instance 2 with re-ordered options`);
t.equal(getKinesis(), kinesis2, `getKinesis() gets cached instance 2 for current region (${region1})`);
t.equal(getKinesis(region1), kinesis2, `getKinesis(${region1}) gets cached instance 2`);
// Change to using a different region, which will cache a new kinesis instance under new region
const region2 = 'us-west-2';
deleteKinesis(region2); // make sure none before we start
t.notOk(getKinesis(region2), `getKinesis(${region2}) kinesis instance must not be cached yet`);
t.equal(getKinesis(), kinesis2, `getKinesis() still gets cached instance 2 for current region (${region1})`);
// Cache a new kinesis instance for the different region
const maxRetries4 = 0;
const options4 = { region: region2, maxRetries: maxRetries4 };
const kinesis4 = setKinesis(options4, context);
t.ok(kinesis4, `setKinesis(${stringify(options4)}) must return an instance`);
t.equal(kinesis4.config.region, region2, `kinesis 4 region must be ${region2}`);
t.equal(kinesis4.config.maxRetries, maxRetries4, `kinesis 4 maxRetries must be ${maxRetries4}`);
t.notEqual(kinesis4, kinesis2, `setKinesis(${stringify(options4)}) must NOT be cached instance 2 for region (${region1})`);
t.equal(getKinesis(region2), kinesis4, `getKinesis(${region2}) gets cached instance 4`);
// Check cache for current region 1 is still intact
t.equal(getKinesis(), kinesis2, `getKinesis() still gets cached instance 2 for current region (${region1})`);
t.equal(getKinesis(region1), kinesis2, `getKinesis(${region1}) gets cached instance 2`);
// Do NOT re-use new kinesis instance for the different region if maxRetries is undefined instead of zero
const maxRetries5 = '';
const options5 = { region: region2, maxRetries: maxRetries5 };
const kinesis5 = setKinesis(options5, context);
t.ok(kinesis5, `setKinesis(${stringify(options5)}) must return an instance`);
t.equal(kinesis5.config.region, region2, `kinesis 5 region must be ${region2}`);
t.equal(kinesis5.config.maxRetries, maxRetries5, `kinesis 5 maxRetries must be ${maxRetries5}`);
t.notEqual(kinesis5, kinesis4, `setKinesis(${stringify(options5)}) must NOT be cached instance 4 for region (${region2})`);
// Delete cache for region 1
t.ok(deleteKinesis(region1), `must delete cached instance for region (${region1})`); // clean up
t.equal(getKinesis(region1), undefined, `getKinesis(${region1}) gets undefined after delete`);
// Delete cache for region 1
t.ok(deleteKinesis(region2), `must delete cached instance for region (${region2})`); // clean up
t.equal(getKinesis(region2), undefined, `getKinesis(${region2}) gets undefined after delete`);
t.end();
});
// =====================================================================================================================
// Tests for configureKinesis

@@ -40,55 +162,70 @@ // =====================================================================================================================

t.notOk(context.kinesis, 'context.kinesis must not be configured yet');
process.env.AWS_REGION = 'us-west-1';
const region1 = getRegion();
t.equal(region1, 'us-west-1');
t.equal(region1, 'us-west-1', `current region must be us-west-1`);
// Ensure not cached before we configure
deleteKinesis(region1);
t.notOk(context.kinesis, 'context.kinesis must not be configured yet');
// Configure it for the first time
const maxRetries1 = 0;
configureKinesis(context, maxRetries1);
const kinesis = context.kinesis;
t.ok(context.kinesis, 'context.kinesis must be configured now');
t.equal(kinesis.config.region, region1, `context.kinesis.config.region must be ${region1}`);
t.equal(kinesis.config.maxRetries, maxRetries1, `context.kinesis.config.maxRetries must be ${maxRetries1}`);
configureKinesis(context, {maxRetries: maxRetries1});
const kinesis1 = context.kinesis;
t.ok(kinesis1, 'context.kinesis 1 must be configured now');
t.equal(kinesis1.config.region, region1, `context.kinesis 1 region must be ${region1}`);
t.equal(kinesis1.config.maxRetries, maxRetries1, `context.kinesis 1 maxRetries must be ${maxRetries1}`);
// "Configure" it for the second time with same region & maxRetries (should give same kinesis instance back again)
context.kinesis = undefined; // clear context.kinesis otherwise will always get it back
configureKinesis(context, maxRetries1);
t.equal(context.kinesis, kinesis, 'context.kinesis must be same cached kinesis');
configureKinesis(context, {region: region1, maxRetries: maxRetries1});
const kinesis1a = context.kinesis;
t.ok(kinesis1a, 'context.kinesis 1a must be configured');
t.equal(kinesis1a, kinesis1, 'context.kinesis 1a must be cached instance 1');
t.equal(kinesis1a.config.region, region1, `context.kinesis 1a region must be ${region1}`);
t.equal(kinesis1a.config.maxRetries, maxRetries1, `context.kinesis 1a maxRetries must be ${maxRetries1}`);
// Configure a new kinesis with a different maxRetries
//context.kinesis = undefined; // clear context.kinesis otherwise will always get it back
const maxRetries2 = 10;
configureKinesis(context, maxRetries2);
context.kinesis = undefined; // clear context.kinesis otherwise will always get it back
configureKinesis(context, {maxRetries: maxRetries2});
const kinesis2 = context.kinesis;
t.ok(context.kinesis, 'context.kinesis must be configured');
t.equal(kinesis2.config.region, region1, `context.kinesis.config.region must be ${region1}`);
t.equal(kinesis2.config.maxRetries, maxRetries2, `context.kinesis.config.maxRetries must be ${maxRetries2}`);
t.notEqual(kinesis2, kinesis, 'context.kinesis must NOT be same cached kinesis');
t.ok(kinesis2, 'context.kinesis 2 must be configured');
t.equal(kinesis2.config.region, region1, `context.kinesis 2 region must be ${region1}`);
t.equal(kinesis2.config.maxRetries, maxRetries2, `context.kinesis 2 maxRetries must be ${maxRetries2}`);
t.notEqual(kinesis2, kinesis1, 'context.kinesis 2 must not be cached instance 1');
// Configure same again, should hit context "cache"
configureKinesis(context, maxRetries2);
configureKinesis(context, {maxRetries: maxRetries2, region: region1});
const kinesis2a = context.kinesis;
t.ok(context.kinesis, 'context.kinesis must be configured');
t.equal(kinesis2.config.region, region1, `context.kinesis.config.region must be ${region1}`);
t.equal(kinesis2.config.maxRetries, maxRetries2, `context.kinesis.config.maxRetries must be ${maxRetries2}`);
t.ok(kinesis2a, 'context.kinesis 2a must be configured');
t.equal(kinesis2a.config.region, region1, `context.kinesis 2a region must be ${region1}`);
t.equal(kinesis2a.config.maxRetries, maxRetries2, `context.kinesis 2a maxRetries must be ${maxRetries2}`);
t.equal(context.kinesis, kinesis2, 'context.kinesis must be same "cached" context.kinesis');
t.notEqual(context.kinesis, kinesis, 'context.kinesis must NOT be original cached kinesis');
t.equal(kinesis2a, kinesis2, 'context.kinesis 2a must be cached instance 2');
t.notEqual(kinesis2a, kinesis1, 'context.kinesis 2a must not be cached instance 1');
// Reconfigure original again
configureKinesis(context, maxRetries1);
const kinesis1 = context.kinesis;
// Reconfigure "original" again
context.kinesis = undefined; // clear context.kinesis otherwise will always get it back
//deleteKinesis(region1); // make sure its gone before we start
t.ok(context.kinesis, 'context.kinesis must be configured');
t.equal(kinesis1.config.region, region1, `context.kinesis.config.region must be ${region1}`);
t.equal(kinesis1.config.maxRetries, maxRetries1, `context.kinesis.config.maxRetries must be ${maxRetries1}`);
configureKinesis(context, {maxRetries: maxRetries1});
const kinesis3 = context.kinesis;
t.equal(context.kinesis, kinesis, 'context.kinesis must be original cached kinesis again');
t.ok(kinesis3, 'context.kinesis 3 must be configured');
t.equal(kinesis3.config.region, region1, `context.kinesis 3 region must be ${region1}`);
t.equal(kinesis3.config.maxRetries, maxRetries1, `context.kinesis 3 maxRetries must be ${maxRetries1}`);
t.notEqual(kinesis3, kinesis2, 'context.kinesis 3 must not be cached instance 2');
t.notEqual(kinesis3, kinesis1, 'context.kinesis 3 must not be cached instance 1');
// Change the region

@@ -98,29 +235,35 @@ process.env.AWS_REGION = 'us-west-2';

t.equal(region2, 'us-west-2');
t.equal(region2, 'us-west-2', `current region must be us-west-2`);
// Configure for new region
configureKinesis(context, maxRetries1);
const kinesis3 = context.kinesis;
context.kinesis = undefined; // clear context.kinesis otherwise will always get it back
deleteKinesis(region2); // make sure none before we start
t.ok(context.kinesis, 'context.kinesis must be configured');
t.equal(kinesis3.config.region, region2, `context.kinesis.config.region must be ${region2}`);
t.equal(kinesis3.config.maxRetries, maxRetries1, `context.kinesis.config.maxRetries must be ${maxRetries1}`);
configureKinesis(context, {maxRetries: maxRetries1});
const kinesis4 = context.kinesis;
t.notEqual(context.kinesis, kinesis, 'context.kinesis must NOT be original cached kinesis');
t.notEqual(context.kinesis, kinesis2, 'context.kinesis must NOT be kinesis2 either');
t.ok(kinesis4, 'context.kinesis 4 must be configured');
t.equal(kinesis4.config.region, region2, `context.kinesis 4 region must be ${region2}`);
t.equal(kinesis4.config.maxRetries, maxRetries1, `context.kinesis 4 maxRetries must be ${maxRetries1}`);
t.notEqual(kinesis4, kinesis3, 'context.kinesis 4 must NOT be cached instance 3');
t.notEqual(kinesis4, kinesis2, 'context.kinesis 4 must NOT be cached instance 2');
t.notEqual(kinesis4, kinesis1, 'context.kinesis 4 must NOT be cached instance 1');
// Switch the region back again
process.env.AWS_REGION = 'us-west-1';
t.equal(getRegion(), 'us-west-1');
t.equal(getRegion(), 'us-west-1', `current region must be us-west-1`);
// Reconfigure original again
configureKinesis(context, maxRetries1);
const kinesis4 = context.kinesis;
// "Reconfigure" original again
context.kinesis = undefined; // clear context.kinesis otherwise will always get it back
configureKinesis(context, {maxRetries: maxRetries1});
const kinesis5 = context.kinesis;
t.ok(context.kinesis, 'context.kinesis must be configured');
t.equal(kinesis4.config.region, region1, `context.kinesis.config.region must be ${region1}`);
t.equal(kinesis4.config.maxRetries, maxRetries1, `context.kinesis.config.maxRetries must be ${maxRetries1}`);
t.ok(kinesis5, 'context.kinesis must be configured');
t.equal(kinesis5.config.region, region1, `context.kinesis 5 region must be ${region1}`);
t.equal(kinesis5.config.maxRetries, maxRetries1, `context.kinesis 5 maxRetries must be ${maxRetries1}`);
t.equal(context.kinesis, kinesis, 'context.kinesis must be original cached kinesis again');
t.equal(kinesis5, kinesis3, 'context.kinesis 5 must be cached instance 3');
t.end();
});
{
"name": "aws-core-utils-tests",
"description": "Unit tests for aws-core-utils modules",
"version": "2.0.1",
"version": "2.1.0",
"author": "Byron du Preez",

@@ -6,0 +6,0 @@ "license": "Apache-2.0",

@@ -121,7 +121,21 @@ 'use strict';

// Configure it
configureStageHandling(context, customToStage, convertAliasToStage,
injectStageIntoStreamName, extractStageFromStreamName, streamNameStageSeparator,
injectStageIntoResourceName, extractStageFromResourceName, resourceNameStageSeparator,
injectInCase, extractInCase, defaultStage, forceConfiguration);
const settings = {
customToStage: customToStage,
convertAliasToStage: convertAliasToStage,
injectStageIntoStreamName: injectStageIntoStreamName,
extractStageFromStreamName: extractStageFromStreamName,
streamNameStageSeparator: streamNameStageSeparator,
injectStageIntoResourceName: injectStageIntoResourceName,
extractStageFromResourceName: extractStageFromResourceName,
resourceNameStageSeparator: resourceNameStageSeparator,
injectInCase: injectInCase,
extractInCase: extractInCase,
defaultStage: defaultStage,
};
configureStageHandling(context, settings, forceConfiguration);
const after = context.stageHandling;

@@ -128,0 +142,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc