Skip to content

Commit

Permalink
Merge pull request #2 from nsidc/NDCUM-914
Browse files Browse the repository at this point in the history
NDCUM-914
  • Loading branch information
colecu authored Mar 27, 2023
2 parents b208325 + 13d4f66 commit 90adec8
Show file tree
Hide file tree
Showing 17 changed files with 48,996 additions and 104 deletions.
103 changes: 103 additions & 0 deletions packages/pvl/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
'use strict';

const PVLRoot = require('./lib/models').PVLRoot;
const PVLObject = require('./lib/models').PVLObject;
const PVLGroup = require('./lib/models').PVLGroup;
const PVLNumeric = require('./lib/models').PVLNumeric;
const PVLDateTime = require('./lib/models').PVLDateTime;
const PVLTextString = require('./lib/models').PVLTextString;
const patterns = require('./lib/patterns');
const checkRegexes = require('./lib/utils').checkRegexes;

function parseValue(value, key) {
const numericValue = checkRegexes(value, patterns.numericPatterns);
if (numericValue !== null) return new PVLNumeric(numericValue);

const dateTimeValue = checkRegexes(value, patterns.dateTimePatterns);
if (dateTimeValue !== null) return new PVLDateTime(dateTimeValue);

const textStringValue = checkRegexes(value, patterns.textStringPatterns);
if (textStringValue !== null) return new PVLTextString(textStringValue);

throw new Error(`Failed to parse value ('${value}') of ${key}`);
}

function pvlToJS(pvlString) {
const result = new PVLRoot();
// Keep track of which aggregate is "active" in the stack,
// as far as assigning further attributes and aggregates
const aggregates = [result];

// Split into statements
// Currently assumes single-line statements, not allowing multi-line values
const pvlStatements = pvlString
.split('\n')
.map((s) => s.trim())
// Strip statement-ending semicolons
.map((s) => s.replace(/;$/, ''))
// Ignore blank lines
.filter((s) => s !== '')
// Ignore full-line comments
.filter((s) => !(s.startsWith('/*') && s.endsWith('*/')));

let keyAndValue;
let key;
let aggregate;
let s = pvlStatements.shift();
while (s !== undefined && s !== 'END') {
keyAndValue = s.split(/ = /);
key = keyAndValue[0].trim();
// Need to account for string-embedded `=`s
let value = keyAndValue.slice(1).join(' = ').trim();

if (['BEGIN_GROUP', 'GROUP', 'BEGIN_OBJECT', 'OBJECT'].includes(key)) {
// Group names _can_ be wrapped in quotes
value = value.replace(/["']/g, '');
aggregate = key.includes('GROUP') ? new PVLGroup(value) : new PVLObject(value);
aggregates[aggregates.length - 1].addAggregate(aggregate);
aggregates.push(aggregate);
} else if (['END_OBJECT', 'END_GROUP'].includes(key)) {
aggregates.pop();
} else {
aggregates[aggregates.length - 1].add(key, parseValue(value, key));
}

s = pvlStatements.shift();
}

return result;
}

function jsToPVL(pvlObject) {
const stringified = pvlObject.toPVL();
const INDENTATION_WIDTH = 2;

// Spec doesn't require indentation, but does highly recommended it
let depth = 0;
const indented = stringified.split('\n').map((s) => {
if (s.match(/^END_(GROUP|OBJECT)( = .+)?$/)) {
depth -= 1;
}
const thisLine = `${' '.repeat(depth * INDENTATION_WIDTH)}${s}`;
if (s.match(/^(BEGIN_)?(GROUP|OBJECT) = .+$/)) {
depth += 1;
}
return thisLine;
}).join('\n');

return indented;
}

module.exports = {
pvlToJS: pvlToJS,
jsToPVL: jsToPVL,
parseValue: parseValue,
models: {
PVLRoot: PVLRoot,
PVLObject: PVLObject,
PVLGroup: PVLGroup,
PVLNumeric: PVLNumeric,
PVLDateTime: PVLDateTime,
PVLTextString: PVLTextString,
},
};
103 changes: 0 additions & 103 deletions packages/pvl/t.js

This file was deleted.

2 changes: 1 addition & 1 deletion tasks/parse-pdr/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const isString = require('lodash/isString');
const S3 = require('@cumulus/aws-client/S3');
const { buildProviderClient, fetchTextFile } = require('@cumulus/ingest/providerClientUtils');
const { PDRParsingError } = require('@cumulus/errors');
const { pvlToJS } = require('@cumulus/pvl/t');
const { pvlToJS } = require('@cumulus/pvl');
const {
collections: collectionsApi,
providers: providersApi,
Expand Down
14 changes: 14 additions & 0 deletions tasks/send-pan/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"comments": false,
"sourceMaps": "both",
"presets": [
["env", {
"targets": {
"node": "14.19.1"
}
}]
],
"plugins": [
"source-map-support"
]
}
2 changes: 2 additions & 0 deletions tasks/send-pan/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/nyc.config.js
/tests/
13 changes: 13 additions & 0 deletions tasks/send-pan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# @cumulus/send-pan

`@cumulus/send-pan` contains code for a lambda function that generates a PAN response and sends that response to a configured provider, then returns the payload that was passed to it.

## About Cumulus

Cumulus is a cloud-based data ingest, archive, distribution and management prototype for NASA's future Earth science data streams.

[Cumulus Documentation](https://nasa.github.io/cumulus)

## Contributing

To make a contribution, please [see our contributing guidelines](https://github.com/nasa/cumulus/blob/master/CONTRIBUTING.md).
54 changes: 54 additions & 0 deletions tasks/send-pan/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use strict';

const pdrs = require('@cumulus/api/models/pdrs');
const cumulusMessageAdapter = require('@cumulus/cumulus-message-adapter-js');
const fs = require('fs');
const path = require('path');
const { buildUploaderClient } = require('./uploader');

/**
* Return Input payload
*
* @param {object} event - input from the message adapter
* @returns {object} sample JSON object
*/
async function sendPAN(event) {
const config = event.config;
const provider = config.provider;
const remoteDir = config.remoteDir;
const panName = config.pdrName.replace(/pdr/ig, 'pan');
const uploadPath = path.join(remoteDir, panName);

const pan = pdrs.generatePAN();

const localPath = `/tmp/${panName}`;
fs.writeFile(localPath, pan, (err) => {
if (err) {
throw new Error(`Unable to write file ${localPath}: ${err.message}`);
}
});

const providerClient = buildUploaderClient(provider);
await providerClient.upload({ localPath, uploadPath });

fs.unlink(localPath, (err) => {
if (err) {
throw new Error(`Unable to unlink file ${localPath}: ${err.message}.`);
}
});

return event;
}
/**
* Lambda handler
*
* @param {object} event - a Cumulus Message
* @param {object} context - an AWS Lambda context
* @returns {Promise<object>} - sample JSON object
*/
async function handler(event, context) {
return await cumulusMessageAdapter.runCumulusTask(sendPAN, event, context);
}

exports.handler = handler;
exports.sendPAN = sendPAN; // exported to support testing
6 changes: 6 additions & 0 deletions tasks/send-pan/nyc.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

module.exports = {
extends: '../../nyc.config.js',
include: ['*.js'],
};
Loading

0 comments on commit 90adec8

Please sign in to comment.