New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@cumulus/cumulus-message-adapter-js

Package Overview
Dependencies
Maintainers
3
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cumulus/cumulus-message-adapter-js - npm Package Compare versions

Comparing version 0.0.1-beta.2 to 0.0.1-beta.3

CONTRIBUTING.md

52

index.js

@@ -25,19 +25,19 @@ 'use strict';

return new Promise((resolve, reject) => {
const sled = cp.spawn('python', ['./cumulus-message-adapter.zip', command]);
const cumulusMessageAdapter = cp.spawn('python', ['./cumulus-message-adapter', command]);
// Collect STDOUT
let sledStdout = '';
sled.stdout.on('data', (chunk) => {
sledStdout += chunk;
let cumulusMessageAdapterStdout = '';
cumulusMessageAdapter.stdout.on('data', (chunk) => {
cumulusMessageAdapterStdout += chunk;
});
// Collect STDERR
let sledStderr = '';
sled.stderr.on('data', (chunk) => {
sledStderr += chunk;
let cumulusMessageAdapterStderr = '';
cumulusMessageAdapter.stderr.on('data', (chunk) => {
cumulusMessageAdapterStderr += chunk;
});
sled.on('close', (code) => {
if (code === 0) resolve(JSON.parse(sledStdout));
else reject(new CumulusMessageAdapterExecutionError(sledStderr));
cumulusMessageAdapter.on('close', (code) => {
if (code === 0) resolve(JSON.parse(cumulusMessageAdapterStdout));
else reject(new CumulusMessageAdapterExecutionError(cumulusMessageAdapterStderr));
});

@@ -49,5 +49,5 @@

// result in an unhandled "Error: write EPIPE".
sled.stdin.on('error', () => {});
cumulusMessageAdapter.stdin.on('error', () => {});
sled.stdin.end(JSON.stringify(input));
cumulusMessageAdapter.stdin.end(JSON.stringify(input));
});

@@ -121,17 +121,2 @@ }

/**
* Call the callback with an error or a Cumulus message
*
* @param {Error} err - an error to be handled
* @param {Object} cumulusMessage - a full Cumulus message
* @param {Fuction} callback - the callback to be invoked with the parsed error
* @returns {undefined} - undefined
*/
function handleError(err, cumulusMessage, callback) {
if (err.name && err.name.includes('WorkflowError')) {
callback(null, Object.assign({}, cumulusMessage, { payload: null, exception: err.name }));
}
else callback(err);
}
/**
* Build a nested Cumulus event and pass it to a tasks's business function

@@ -144,3 +129,5 @@ *

* has completed. This should be the callback passed to the Lambda handler.
* @returns {Promise} - resolves when the task has completed
* @returns {undefined} - there is no return value from this function, but
* the callback function will be invoked with either an error or a full
* Cumulus message containing the result of the business logic function.
*/

@@ -173,6 +160,11 @@ function runCumulusTask(taskFunction, cumulusMessage, context, callback) {

return promisedNextEvent
promisedNextEvent
.then((nextEvent) => callback(null, nextEvent))
.catch((err) => handleError(err, cumulusMessage, callback));
.catch((err) => {
if (err.name && err.name.includes('WorkflowError')) {
callback(null, Object.assign({}, cumulusMessage, { payload: null, exception: err.name }));
}
else callback(err);
});
}
exports.runCumulusTask = runCumulusTask;
{
"name": "@cumulus/cumulus-message-adapter-js",
"version": "0.0.1-beta.2",
"version": "0.0.1-beta.3",
"description": "Cumulus message adapter",
"main": "index.js",
"scripts": {
"test": "cp test/cumulus-message-adapter.zip . && ava; rm cumulus-message-adapter.zip"
"test": "rm -rf cumulus-message-adapter && cp -R test/cumulus-message-adapter . && ava; rm -rf cumulus-message-adapter"
},

@@ -9,0 +9,0 @@ "ava": {

@@ -1,1 +0,125 @@

# cumulus-message-adapter-js
# @cumulus/cumulus-message-adapter-js
[![CircleCI](https://circleci.com/gh/cumulus-nasa/cumulus-message-adapter-js.svg?style=svg)](https://circleci.com/gh/cumulus-nasa/cumulus-message-adapter-js)
## What is Cumulus?
Cumulus is a cloud-based data ingest, archive, distribution and management
prototype for NASA's future Earth science data streams.
Read the [Cumulus Documentation](https://cumulus-nasa.github.io/)
## What is the Cumulus Message Adapter?
The Cumulus Message Adapter is a library that adapts incoming messages in the
Cumulus protocol to a format more easily consumable by Cumulus tasks, invokes
the tasks, and then adapts their response back to the Cumulus message protocol
to be sent to the next task.
## Installation
The cumulus-message-adapter-js can be installed via Node Package Manager (NPM) and the package is located [here](https://www.npmjs.com/package/@cumulus/cumulus-message-adapter-js).
The package can be added to your project by running `npm install @cumulus/cumulus-message-adapter-js --save`.
## Task definition
In order to use the Cumulus Message Adapter, you will need to create two
methods in your task module: a handler function and a business logic function.
The handler function is a standard Lambda handler function which takes three
parameters (as specified by AWS): `event`, `context`, and `callback`.
The business logic function is where the actual work of your task occurs. It
should take two parameters: `nestedEvent` and `context`.
The `nestedEvent` object contains two keys:
* `input` - the task's input, typically the `payload` of the message,
produced at runtime
* `config` - the task's configuration, with any templated variables
resolved
The `context` parameter is the standard Lambda context as passed by AWS.
The return value of the business logic function will be placed in the
`payload` of the resulting Cumulus message.
Expectations for input, config, and return values are all defined by the task,
and should be well documented. Tasks should thoughtfully consider their inputs
and return values, as breaking changes may have cascading effects on tasks
throughout a workflow. Configuration changes are slightly less impactful, but
must be communicated to those using the task.
## Cumulus Message Adapter interface
The Cumulus Message adapter for Javascript provides one method:
`runCumulusTask`. It takes four parameters:
* `taskFunction` - the function containing your business logic (as described
above)
* `cumulusMessage` - the event passed by Lambda, and should be a Cumulus
Message
* `context` - the Lambda context
* `callback` - the callback passed by Lambda
## Example Cumulus task
```javascript
const cumulusMessageAdapter = require('@cumulus/cumulus-message-adapter-js');
function myBusinessLogic(nestedEvent, context) {
console.log('Hello, example!');
return { answer: 42 };
}
// The handler function should rarely, if ever, contain more than this line
function handler(event, context, callback) {
cumulusMessageAdapter.runCumulusTask(myBusinessLogic, event, callback);
}
exports.handler = handler;
```
## Creating a deployment package
Tasks that use this library are just standard AWS Lambda tasks. Information on
creating release packages is available [here](https://docs.aws.amazon.com/lambda/latest/dg/deployment-package-v2.html).
## Usage in Cumulus Deployments
During deployment, Cumulus will automatically obtain and inject the [Cumulus Message Adapter](https://github.com/cumulus-nasa/cumulus-message-adapter)
into the compiled code and create a zip file to be deployed to Lambda.
A task using the message adapter would be configured in lambdas.yml as follows:
```yaml
NodeTest:
handler: index.handler
timeout: 300
memory: 256
source: 'node_modules/@cumulus/task-task/dist/'
useMessageAdapter: true
```
## Development
### Running Tests
To run the tests for this package, run `npm test`
## Why?
This approach has a few major advantages:
1. It explicitly prevents tasks from making assumptions about data structures
like `meta` and `cumulus_meta` that are owned internally and may therefore
be broken in future updates. To gain access to fields in these structures,
tasks must be passed the data explicitly in the workflow configuration.
1. It provides clearer ownership of the various data structures. Operators own
`meta`. Cumulus owns `cumulus_meta`. Tasks define their own `config`,
`input`, and `output` formats.
1. The Cumulus Message Adapter greatly simplifies running Lambda functions not
explicitly created for Cumulus.
1. The approach greatly simplifies testing for tasks, as tasks don't need to
set up cumbersome structures to emulate the message protocol and can just
test their business function.

@@ -6,3 +6,3 @@ /* eslint-disable require-jsdoc */

test('CUMULUS_MESSAGE_ADAPTER_DISABLED="true" bypasses the message adapter', (t) => {
test.cb('CUMULUS_MESSAGE_ADAPTER_DISABLED="true" bypasses the message adapter', (t) => {
process.env.CUMULUS_MESSAGE_ADAPTER_DISABLED = 'true';

@@ -23,2 +23,3 @@

t.deepEqual(data, { result: 42 });
t.end();
}

@@ -25,0 +26,0 @@

@@ -6,3 +6,3 @@ /* eslint-disable require-jsdoc */

test('The correct cumulus message is returned', (t) => {
test.cb('The correct cumulus message is returned', (t) => {
const businessLogicOutput = 42;

@@ -24,2 +24,3 @@ const businessLogic = () => businessLogicOutput;

t.deepEqual(data, expectedOutput);
t.end();
}

@@ -30,3 +31,3 @@

test('The businessLogic receives the correct arguments', (t) => {
test.cb('The businessLogic receives the correct arguments', (t) => {
const inputEvent = { a: 1 };

@@ -45,6 +46,6 @@ const context = { b: 2 };

return cumulusMessageAdapter.runCumulusTask(businessLogic, inputEvent, context, () => true);
return cumulusMessageAdapter.runCumulusTask(businessLogic, inputEvent, context, t.end);
});
test('A WorkflowError is returned properly', (t) => {
test.cb('A WorkflowError is returned properly', (t) => {
const inputEvent = { a: 1 };

@@ -67,2 +68,3 @@

t.deepEqual(data, expectedOutput);
t.end();
}

@@ -73,3 +75,3 @@

test('A non-WorkflowError is raised', (t) => {
test.cb('A non-WorkflowError is raised', (t) => {
function businessLogic() {

@@ -83,2 +85,3 @@ throw new Error('oh snap');

t.is(data, undefined);
t.end();
}

@@ -85,0 +88,0 @@

Sorry, the diff of this file is not supported yet

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