-
Notifications
You must be signed in to change notification settings - Fork 103
/
index.js
121 lines (106 loc) · 3.8 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
'use strict';
const fs = require('fs');
const path = require('path');
const spawn = require('child_process').spawn;
const spawnSync = require('child_process').spawnSync;
const Task = require('@cumulus/common/task');
const log = require('@cumulus/common/log');
const util = require('@cumulus/common/util');
const aws = require('@cumulus/common/aws');
const configGen = require('./config-gen');
const Mutex = require('@cumulus/common/concurrency').Mutex;
const LOCK_TIMEOUT_MS = 20 * 60 * 1000; // 20 minutes
const execSync = require('child_process').execSync;
module.exports = class GenerateMrfTask extends Task {
async run() {
const message = this.message;
if (message.payload.length === 0) {
log.info('No files to process');
return [];
}
const tempDir = util.mkdtempSync(this.constructor.name);
try {
const paths = {
mrfgenConfig: path.join(tempDir, 'mrfgenConfig.xml'),
templates: path.join(__dirname, 'templates')
};
for (const tempPath of ['work', 'input', 'output', 'logs', 'emptyTiles']) {
paths[tempPath] = path.join(tempDir, tempPath);
if (!fs.existsSync(paths[tempPath])) {
fs.mkdirSync(paths[tempPath]);
}
}
const emptyTileSrcDir = path.join(paths.templates, 'empty-tiles');
fs.readdirSync(emptyTileSrcDir).forEach((tilefile) => {
fs.linkSync(path.join(emptyTileSrcDir, tilefile),
path.join(paths.emptyTiles, tilefile));
});
const mrfConfig = configGen.generateConfig(
`EPSG:${this.config.epsg}`,
this.config.date,
this.config.zoom,
this.config.mrfgen,
paths
);
const destBucket = this.config.output.bucket;
const destKey = this.config.output.key_prefix;
log.info("Writing mrfgen config", mrfConfig);
fs.writeFileSync(paths.mrfgenConfig, mrfConfig, {
mode: 0o600
});
for (const file of (this.config.files || [])) {
if (file.filename) {
const name = file.filename || path.basename(file.Key);
const fullpath = path.join(paths.input, name);
fs.writeFileSync(fullpath, file.contents, { mode: 0o600 });
}
else {
await aws.downloadS3Files([file], paths.input);
}
}
const messageInfo = `(${message.payload.length} files from ${this.message.meta.key})`;
await aws.downloadS3Files(message.payload, paths.input);
log.info(`Completed source download ${messageInfo}`);
log.info('==== MRF CONFIG ====');
log.info(mrfConfig);
log.info('========');
await this.runMrfgen(paths.mrfgenConfig);
log.info(`Completed MRF generation ${messageInfo}`);
const fullPaths = fs.readdirSync(paths.output).map((f) => path.join(paths.output, f));
// Upload under the destKey bucket, inserting an underscore before the file extension
const destKeyFn = (filename) =>
path.join(destKey, path.basename(filename).replace(/\.([^\.]*)$/, '_.$1'));
await aws.uploadS3Files(fullPaths, destBucket, destKeyFn);
}
finally {
execSync(`rm -rf ${tempDir}`);
}
}
runMrfgen(configPath) {
log.info(`==== ${configPath} ====`);
spawnSync('cat', [configPath], { stdio: 'inherit' });
log.info('========');
return new Promise((resolve, reject) => {
const mrfgen = spawn('mrfgen', ['-c', configPath], {
stdio: 'inherit',
shell: true
});
mrfgen.on('close', (code) => {
if (code === 0) {
resolve(configPath);
}
else {
reject(`mrfgen exited with code ${code}`);
}
});
});
}
/**
* Entrypoint for Lambda
* @param {array} args The arguments passed by AWS Lambda
* @return The handler return value
*/
static handler(...args) {
return GenerateMrfTask.handle(...args);
}
};