@cumulus/ingest 16.0.3-alpha.0 → 16.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nycrc.json +7 -0
- package/HttpProviderClient.d.ts +14 -2
- package/HttpProviderClient.d.ts.map +1 -1
- package/HttpProviderClient.js +29 -2
- package/HttpProviderClient.js.map +1 -1
- package/S3ProviderClient.d.ts +17 -3
- package/S3ProviderClient.d.ts.map +1 -1
- package/S3ProviderClient.js +21 -4
- package/S3ProviderClient.js.map +1 -1
- package/consumer.d.ts.map +1 -1
- package/consumer.js +15 -3
- package/consumer.js.map +1 -1
- package/lock.d.ts +27 -24
- package/lock.d.ts.map +1 -1
- package/lock.js +39 -36
- package/lock.js.map +1 -1
- package/package.json +15 -14
- package/queue.d.ts +7 -6
- package/queue.d.ts.map +1 -1
- package/queue.js +7 -16
- package/queue.js.map +1 -1
- package/src/HttpProviderClient.js +36 -2
- package/src/S3ProviderClient.ts +31 -4
- package/src/consumer.ts +13 -3
- package/src/lock.ts +44 -41
- package/src/queue.js +9 -27
- package/tsconfig.tsbuildinfo +1 -1
package/queue.d.ts
CHANGED
|
@@ -29,10 +29,10 @@ export function enqueueParsePdrMessage({ collection, parentExecutionArn, parsePd
|
|
|
29
29
|
* Enqueue a granule to be ingested
|
|
30
30
|
*
|
|
31
31
|
* @param {Object} params
|
|
32
|
-
* @param {Object} params.
|
|
32
|
+
* @param {Object} params.granules - the granules to be enqueued for ingest
|
|
33
33
|
* @param {string} params.queueUrl - the SQS queue to add the message to
|
|
34
|
-
* @param {
|
|
35
|
-
*
|
|
34
|
+
* @param {Object} params.messageTemplate - Message template for the workflow
|
|
35
|
+
* @param {Object} params.workflow - workflow name & arn object
|
|
36
36
|
* @param {Object} params.provider - the provider config to be attached to the message
|
|
37
37
|
* @param {Object} params.collection - the collection config to be attached to the
|
|
38
38
|
* message
|
|
@@ -43,10 +43,11 @@ export function enqueueParsePdrMessage({ collection, parentExecutionArn, parsePd
|
|
|
43
43
|
* @param {Object} [params.additionalCustomMeta] - additional object to merge into meta object
|
|
44
44
|
* @returns {Promise} - resolves when the message has been enqueued
|
|
45
45
|
*/
|
|
46
|
-
export function enqueueGranuleIngestMessage({ collection, granules,
|
|
47
|
-
|
|
46
|
+
export function enqueueGranuleIngestMessage({ collection, granules, parentExecutionArn, pdr, provider, messageTemplate, workflow, queueUrl, executionNamePrefix, additionalCustomMeta, }: {
|
|
47
|
+
granules: Object;
|
|
48
48
|
queueUrl: string;
|
|
49
|
-
|
|
49
|
+
messageTemplate: Object;
|
|
50
|
+
workflow: Object;
|
|
50
51
|
provider: Object;
|
|
51
52
|
collection: Object;
|
|
52
53
|
pdr: Object;
|
package/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["src/queue.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;GAgBG;AACH;IAb0B,GAAG,EAAlB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,0BAA0B,EAAzC,MAAM;IAES,QAAQ,EAAvB,MAAM;IACS,UAAU,EAAzB,MAAM;IAES,kBAAkB,EAAjC,MAAM;IACU,mBAAmB;IAEnB,oBAAoB;iBA+C9C;AAGD;;;;;;;;;;;;;;;;;GAiBG;AACH;IAd0B,
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["src/queue.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;GAgBG;AACH;IAb0B,GAAG,EAAlB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,0BAA0B,EAAzC,MAAM;IAES,QAAQ,EAAvB,MAAM;IACS,UAAU,EAAzB,MAAM;IAES,kBAAkB,EAAjC,MAAM;IACU,mBAAmB;IAEnB,oBAAoB;iBA+C9C;AAGD;;;;;;;;;;;;;;;;;GAiBG;AACH;IAd0B,QAAQ,EAAvB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,eAAe,EAA9B,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,UAAU,EAAzB,MAAM;IAES,GAAG,EAAlB,MAAM;IACS,kBAAkB,EAAjC,MAAM;IACU,mBAAmB;IAEnB,oBAAoB;iBAkC9C;AAGD;;;;;;;;;;;;;;GAcG;AACH;IAX0B,QAAQ,EAAvB,MAAM;IACS,aAAa,EAA5B,MAAM;IACU,QAAQ;IACT,QAAQ,EAAvB,MAAM;IACS,UAAU,EAAzB,MAAM;IAES,kBAAkB,EAAjC,MAAM;IACU,mBAAmB;iBAqD7C"}
|
package/queue.js
CHANGED
|
@@ -50,10 +50,10 @@ module.exports.enqueueParsePdrMessage = enqueueParsePdrMessage;
|
|
|
50
50
|
* Enqueue a granule to be ingested
|
|
51
51
|
*
|
|
52
52
|
* @param {Object} params
|
|
53
|
-
* @param {Object} params.
|
|
53
|
+
* @param {Object} params.granules - the granules to be enqueued for ingest
|
|
54
54
|
* @param {string} params.queueUrl - the SQS queue to add the message to
|
|
55
|
-
* @param {
|
|
56
|
-
*
|
|
55
|
+
* @param {Object} params.messageTemplate - Message template for the workflow
|
|
56
|
+
* @param {Object} params.workflow - workflow name & arn object
|
|
57
57
|
* @param {Object} params.provider - the provider config to be attached to the message
|
|
58
58
|
* @param {Object} params.collection - the collection config to be attached to the
|
|
59
59
|
* message
|
|
@@ -64,31 +64,22 @@ module.exports.enqueueParsePdrMessage = enqueueParsePdrMessage;
|
|
|
64
64
|
* @param {Object} [params.additionalCustomMeta] - additional object to merge into meta object
|
|
65
65
|
* @returns {Promise} - resolves when the message has been enqueued
|
|
66
66
|
*/
|
|
67
|
-
async function enqueueGranuleIngestMessage({ collection, granules,
|
|
68
|
-
const messageTemplate = await getJsonS3Object(systemBucket, templateKey(stack));
|
|
69
|
-
const { arn: ingestGranuleArn } = await getJsonS3Object(systemBucket, getWorkflowFileKey(stack, granuleIngestWorkflow));
|
|
70
|
-
const payload = { granules };
|
|
71
|
-
const workflow = {
|
|
72
|
-
name: granuleIngestWorkflow,
|
|
73
|
-
arn: ingestGranuleArn,
|
|
74
|
-
};
|
|
67
|
+
async function enqueueGranuleIngestMessage({ collection, granules, parentExecutionArn, pdr, provider, messageTemplate, workflow, queueUrl, executionNamePrefix, additionalCustomMeta = {}, }) {
|
|
75
68
|
const message = buildQueueMessageFromTemplate({
|
|
76
69
|
messageTemplate,
|
|
77
70
|
parentExecutionArn,
|
|
78
|
-
payload,
|
|
71
|
+
payload: { granules },
|
|
79
72
|
workflow,
|
|
80
73
|
customMeta: {
|
|
81
74
|
...additionalCustomMeta,
|
|
75
|
+
...(pdr ? { pdr } : {}),
|
|
82
76
|
collection,
|
|
83
77
|
provider,
|
|
84
78
|
},
|
|
85
79
|
executionNamePrefix,
|
|
86
80
|
});
|
|
87
|
-
if (pdr)
|
|
88
|
-
message.meta.pdr = pdr;
|
|
89
|
-
const arn = buildExecutionArn(message.cumulus_meta.state_machine, message.cumulus_meta.execution_name);
|
|
90
81
|
await sendSQSMessage(queueUrl, message);
|
|
91
|
-
return
|
|
82
|
+
return buildExecutionArn(message.cumulus_meta.state_machine, message.cumulus_meta.execution_name);
|
|
92
83
|
}
|
|
93
84
|
exports.enqueueGranuleIngestMessage = enqueueGranuleIngestMessage;
|
|
94
85
|
/**
|
package/queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["src/queue.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAC9D,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAE9D,MAAM,EAAE,6BAA6B,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAC5E,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;AAErE,MAAM,EACJ,kBAAkB,EAClB,WAAW,GACZ,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;AAEzC;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,UAAU,sBAAsB,CAAC,EACpC,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,GAAG,EACH,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,mBAAmB,EACnB,oBAAoB,GAAG,EAAE,GAC1B;IACC,MAAM,eAAe,GAAG,MAAM,eAAe,CAAC,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAChF,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,MAAM,eAAe,CAChD,YAAY,EACZ,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAC5C,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC;IACxB,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,gBAAgB;QACtB,GAAG,EAAE,WAAW;KACjB,CAAC;IAEF,MAAM,OAAO,GAAG,6BAA6B,CAAC;QAC5C,eAAe;QACf,kBAAkB;QAClB,OAAO;QACP,QAAQ;QACR,UAAU,EAAE;YACV,GAAG,oBAAoB;YACvB,UAAU;YACV,QAAQ;SACT;QACD,mBAAmB;KACpB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,iBAAiB,CAC3B,OAAO,CAAC,YAAY,CAAC,aAAa,EAClC,OAAO,CAAC,YAAY,CAAC,cAAc,CACpC,CAAC;IAEF,MAAM,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAExC,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,CAAC,OAAO,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,KAAK,UAAU,2BAA2B,CAAC,EACzC,UAAU,EACV,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["src/queue.js"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ const Crawler = require('simplecrawler');
|
|
|
9
9
|
const got = require('got');
|
|
10
10
|
const { CookieJar } = require('tough-cookie');
|
|
11
11
|
const { promisify } = require('util');
|
|
12
|
+
const stream = require('node:stream');
|
|
12
13
|
|
|
13
14
|
const {
|
|
14
15
|
buildS3Uri,
|
|
@@ -206,7 +207,7 @@ class HttpProviderClient {
|
|
|
206
207
|
/**
|
|
207
208
|
* Download a remote file to disk
|
|
208
209
|
*
|
|
209
|
-
* @param {
|
|
210
|
+
* @param {object} params
|
|
210
211
|
* @param {string} params.remotePath - the full path to the remote file to be fetched
|
|
211
212
|
* @param {string} params.localPath - the full local destination file path
|
|
212
213
|
* @returns {Promise.<string>} - the path that the file was saved to
|
|
@@ -244,7 +245,7 @@ class HttpProviderClient {
|
|
|
244
245
|
/**
|
|
245
246
|
* Download the remote file to a given s3 location
|
|
246
247
|
*
|
|
247
|
-
* @param {
|
|
248
|
+
* @param {object} params
|
|
248
249
|
* @param {string} params.fileRemotePath - the full path to the remote file to be fetched
|
|
249
250
|
* @param {string} params.destinationBucket - destination s3 bucket of the file
|
|
250
251
|
* @param {string} params.destinationKey - destination s3 key of the file
|
|
@@ -291,6 +292,39 @@ class HttpProviderClient {
|
|
|
291
292
|
return { s3uri, etag };
|
|
292
293
|
}
|
|
293
294
|
|
|
295
|
+
/**
|
|
296
|
+
* Upload a file
|
|
297
|
+
*
|
|
298
|
+
* @param {object} params
|
|
299
|
+
* @param {string} params.localPath - the full local file path
|
|
300
|
+
* @param {string} params.uploadPath - the full remote file path for uploading file to
|
|
301
|
+
* @returns {Promise<string>} the uri of the uploaded file
|
|
302
|
+
*/
|
|
303
|
+
async upload(params) {
|
|
304
|
+
const { localPath, uploadPath } = params;
|
|
305
|
+
log.info(params);
|
|
306
|
+
await this.setUpGotOptions();
|
|
307
|
+
await this.downloadTLSCertificate();
|
|
308
|
+
const options = {
|
|
309
|
+
protocol: this.protocol,
|
|
310
|
+
host: this.host,
|
|
311
|
+
port: this.port,
|
|
312
|
+
path: uploadPath,
|
|
313
|
+
method: 'POST',
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const remoteUrl = buildURL(options);
|
|
317
|
+
got.stream.options = options;
|
|
318
|
+
await promisify(pipeline)(
|
|
319
|
+
fs.createReadStream(localPath),
|
|
320
|
+
await got.stream.post(remoteUrl),
|
|
321
|
+
new stream.PassThrough()
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
log.info(`Finishing uploading ${localPath} to ${remoteUrl}`);
|
|
325
|
+
return remoteUrl;
|
|
326
|
+
}
|
|
327
|
+
|
|
294
328
|
/* eslint-disable no-empty-function */
|
|
295
329
|
async connect() {}
|
|
296
330
|
|
package/src/S3ProviderClient.ts
CHANGED
|
@@ -15,7 +15,7 @@ class S3ProviderClient implements ProviderClient {
|
|
|
15
15
|
/**
|
|
16
16
|
* Download a remote file to disk
|
|
17
17
|
*
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {object} params
|
|
19
19
|
* @param {string} params.remotePath - the full path to the remote file to be fetched
|
|
20
20
|
* @param {string} params.localPath - the full local destination file path
|
|
21
21
|
* @param {string} params.remoteAltBucket - alternate per-file bucket override to this.bucket
|
|
@@ -79,8 +79,8 @@ class S3ProviderClient implements ProviderClient {
|
|
|
79
79
|
/**
|
|
80
80
|
* Download the remote file to a given s3 location
|
|
81
81
|
*
|
|
82
|
-
* @param {
|
|
83
|
-
* @param {string} params.
|
|
82
|
+
* @param {object} params
|
|
83
|
+
* @param {string} params.fileRemotePath - the full path to the remote file to be fetched
|
|
84
84
|
* @param {string} params.bucket - destination s3 bucket of the file
|
|
85
85
|
* @param {string} params.destinationBucket - destination s3 bucket of the file
|
|
86
86
|
* @param {string} params.destinationKey - destination s3 key of the file
|
|
@@ -132,7 +132,6 @@ class S3ProviderClient implements ProviderClient {
|
|
|
132
132
|
sourceObject,
|
|
133
133
|
destinationBucket,
|
|
134
134
|
destinationKey,
|
|
135
|
-
ACL: 'private',
|
|
136
135
|
copyTags: true,
|
|
137
136
|
});
|
|
138
137
|
return { s3uri, etag };
|
|
@@ -146,6 +145,34 @@ class S3ProviderClient implements ProviderClient {
|
|
|
146
145
|
}
|
|
147
146
|
}
|
|
148
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Upload a file
|
|
150
|
+
*
|
|
151
|
+
* @param {object} params
|
|
152
|
+
* @param {string} params.localPath - the full local file path
|
|
153
|
+
* @param {string} params.uploadPath - the full remote file path for uploading file to
|
|
154
|
+
* @param {string} [params.remoteAltBucket] - alternate per-file bucket override to this.bucket
|
|
155
|
+
* @returns {Promise<string>} the uri of the uploaded file
|
|
156
|
+
*/
|
|
157
|
+
async upload(params: {
|
|
158
|
+
localPath: string,
|
|
159
|
+
uploadPath: string,
|
|
160
|
+
remoteAltBucket?: string,
|
|
161
|
+
}) {
|
|
162
|
+
const { localPath, uploadPath, remoteAltBucket } = params;
|
|
163
|
+
log.info(params);
|
|
164
|
+
const remoteBucket = remoteAltBucket || this.bucket;
|
|
165
|
+
await S3.putFile(
|
|
166
|
+
remoteBucket,
|
|
167
|
+
uploadPath,
|
|
168
|
+
localPath
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const s3Uri = S3.buildS3Uri(remoteBucket, uploadPath);
|
|
172
|
+
log.info(`Finishing uploading ${localPath} to ${s3Uri}`);
|
|
173
|
+
return s3Uri;
|
|
174
|
+
}
|
|
175
|
+
|
|
149
176
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
150
177
|
async connect(): Promise<void> {}
|
|
151
178
|
|
package/src/consumer.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { receiveSQSMessages,
|
|
2
|
-
import * as
|
|
1
|
+
import { receiveSQSMessages, SQSMessage } from '@cumulus/aws-client/SQS';
|
|
2
|
+
import * as sqs from '@cumulus/aws-client/SQS';
|
|
3
|
+
import Logger from '@cumulus/logger';
|
|
3
4
|
|
|
4
5
|
export type MessageConsumerFunction = (queueUrl: string, message: SQSMessage) => Promise<void>;
|
|
5
6
|
|
|
7
|
+
const log = new Logger({ sender: '@cumulus/ingest/consumer' });
|
|
6
8
|
export interface ConsumerConstructorParams {
|
|
7
9
|
queueUrl: string,
|
|
8
10
|
messageLimit?: number,
|
|
@@ -42,9 +44,17 @@ export class Consumer {
|
|
|
42
44
|
): Promise<0 | 1> {
|
|
43
45
|
try {
|
|
44
46
|
await fn(this.queueUrl, message);
|
|
45
|
-
if (this.deleteProcessedMessage)
|
|
47
|
+
if (this.deleteProcessedMessage) {
|
|
48
|
+
await sqs.deleteSQSMessage(this.queueUrl, message.ReceiptHandle);
|
|
49
|
+
}
|
|
46
50
|
return 1;
|
|
47
51
|
} catch (error) {
|
|
52
|
+
if (error.code === 'ExecutionAlreadyExists') {
|
|
53
|
+
log.debug('Deleting message for execution that already exists...');
|
|
54
|
+
await sqs.deleteSQSMessage(this.queueUrl, message.ReceiptHandle);
|
|
55
|
+
log.debug('Completed deleting message.');
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
48
58
|
log.error(error);
|
|
49
59
|
return 0;
|
|
50
60
|
}
|
package/src/lock.ts
CHANGED
|
@@ -14,25 +14,27 @@ export interface Lock {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Checks all locks and removes those older than five minutes. Returns a count
|
|
18
|
-
* of locks that are not older than
|
|
19
|
-
*
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {Array} locks - The list of locks in the bucket
|
|
22
|
-
* @
|
|
23
|
-
|
|
17
|
+
* Checks all locks and removes those older than five minutes. Returns a count
|
|
18
|
+
* of locks that are not older than configured retention period or 5 minutes.
|
|
19
|
+
*
|
|
20
|
+
* @param {object} bucket - The AWS S3 bucket with the locks to check
|
|
21
|
+
* @param {Array} locks - The list of locks in the bucket
|
|
22
|
+
* @param {number} retentionTimeInSeconds - lock retention time in seconds, default is 300
|
|
23
|
+
* @returns {integer} - Number of locks remaining in bucket
|
|
24
|
+
*/
|
|
24
25
|
export async function checkOldLocks(
|
|
25
26
|
bucket: string,
|
|
26
|
-
locks: Lock[] = []
|
|
27
|
+
locks: Lock[] = [],
|
|
28
|
+
retentionTimeInSeconds: number = 300
|
|
27
29
|
): Promise<number> {
|
|
28
|
-
const
|
|
30
|
+
const expirationTimestamp = Date.now() - (retentionTimeInSeconds * 1000);
|
|
29
31
|
|
|
30
32
|
const expiredLocks = locks.filter(
|
|
31
33
|
(lock) => {
|
|
32
34
|
if (!lock.LastModified) {
|
|
33
35
|
throw new TypeError(`Could not find LastModified on ${JSON.stringify(lock)}`);
|
|
34
36
|
}
|
|
35
|
-
return lock.LastModified.getTime() <
|
|
37
|
+
return lock.LastModified.getTime() < expirationTimestamp;
|
|
36
38
|
}
|
|
37
39
|
);
|
|
38
40
|
|
|
@@ -40,6 +42,7 @@ export async function checkOldLocks(
|
|
|
40
42
|
if (!lock.Key) {
|
|
41
43
|
throw new TypeError(`Could not find Key on ${JSON.stringify(lock)}`);
|
|
42
44
|
}
|
|
45
|
+
log.debug(`Removing expired lock ${JSON.stringify(lock)}`);
|
|
43
46
|
return deleteS3Object(bucket, lock.Key);
|
|
44
47
|
}));
|
|
45
48
|
|
|
@@ -47,92 +50,92 @@ export async function checkOldLocks(
|
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/**
|
|
50
|
-
* Counts the number of locks in a bucket.
|
|
51
|
-
*
|
|
52
|
-
* @param {
|
|
53
|
-
* @param {string} providerName - The provider name
|
|
54
|
-
* @
|
|
55
|
-
|
|
53
|
+
* Counts the number of locks in a bucket.
|
|
54
|
+
*
|
|
55
|
+
* @param {object} bucket - The AWS S3 bucket to check
|
|
56
|
+
* @param {string} providerName - The provider name
|
|
57
|
+
* @param {number} retentionTimeInSeconds - lock retention time in seconds, default is 300
|
|
58
|
+
* @returns {integer} - Number of current locks in the bucket
|
|
59
|
+
*/
|
|
56
60
|
export async function countLock(
|
|
57
61
|
bucket: string,
|
|
58
|
-
providerName: string
|
|
62
|
+
providerName: string,
|
|
63
|
+
retentionTimeInSeconds?: number
|
|
59
64
|
): Promise<number> {
|
|
60
65
|
const locks = await listS3ObjectsV2({
|
|
61
66
|
Bucket: bucket,
|
|
62
67
|
Prefix: `${lockPrefix}/${providerName}`,
|
|
63
68
|
});
|
|
64
69
|
|
|
65
|
-
return checkOldLocks(bucket, locks);
|
|
70
|
+
return checkOldLocks(bucket, locks, retentionTimeInSeconds);
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
async function addLock(
|
|
69
74
|
bucket: string,
|
|
70
75
|
providerName: string,
|
|
71
|
-
|
|
72
|
-
ACL?: string
|
|
76
|
+
granuleId: string
|
|
73
77
|
): Promise<void> {
|
|
74
|
-
const key = `${lockPrefix}/${providerName}/${
|
|
78
|
+
const key = `${lockPrefix}/${providerName}/${granuleId}`;
|
|
75
79
|
await s3PutObject({
|
|
76
80
|
Bucket: bucket,
|
|
77
81
|
Key: key,
|
|
78
82
|
Body: '',
|
|
79
|
-
ACL,
|
|
80
83
|
});
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
export async function removeLock(
|
|
84
87
|
bucket: string,
|
|
85
88
|
providerName: string,
|
|
86
|
-
|
|
89
|
+
granuleId: string
|
|
87
90
|
): Promise<void> {
|
|
88
91
|
await deleteS3Object(
|
|
89
92
|
bucket,
|
|
90
|
-
`${lockPrefix}/${providerName}/${
|
|
93
|
+
`${lockPrefix}/${providerName}/${granuleId}`
|
|
91
94
|
);
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
/**
|
|
95
98
|
*
|
|
96
|
-
* @param {string} bucket
|
|
97
|
-
* @param {
|
|
98
|
-
* @param {string} provider.id
|
|
99
|
-
* @param {number} provider.globalConnectionLimit
|
|
100
|
-
* @param {
|
|
101
|
-
* @param {
|
|
102
|
-
* @param {
|
|
99
|
+
* @param {string} bucket - system bucket to place the lock files
|
|
100
|
+
* @param {object} provider - provider object
|
|
101
|
+
* @param {string} provider.id - provider id
|
|
102
|
+
* @param {number} provider.globalConnectionLimit - provider globalConnectionLimit
|
|
103
|
+
* @param {number} provider.maxDownloadTime - provider maxDownloadTime for a granule
|
|
104
|
+
* @param {string} granuleId - id of downloading granule
|
|
105
|
+
* @param {number} counter - retry counter
|
|
103
106
|
* @returns {Promise<boolean>}
|
|
104
107
|
*/
|
|
105
108
|
export async function proceed(
|
|
106
109
|
bucket: string,
|
|
107
110
|
provider: {
|
|
108
111
|
id: string,
|
|
109
|
-
globalConnectionLimit?: number
|
|
112
|
+
globalConnectionLimit?: number,
|
|
113
|
+
maxDownloadTime?: number,
|
|
110
114
|
},
|
|
111
|
-
|
|
112
|
-
counter = 0
|
|
113
|
-
ACL: string
|
|
115
|
+
granuleId: string,
|
|
116
|
+
counter = 0
|
|
114
117
|
): Promise<boolean> {
|
|
115
|
-
|
|
118
|
+
const { globalConnectionLimit, maxDownloadTime } = provider;
|
|
119
|
+
if (globalConnectionLimit === undefined) {
|
|
116
120
|
return true;
|
|
117
121
|
}
|
|
118
122
|
|
|
119
123
|
// Fail if lock is not removed after 270 tries.
|
|
120
124
|
if (counter > 270) {
|
|
125
|
+
log.debug(`The "${provider.id}" provider has no lock available after ${counter} retries`);
|
|
121
126
|
return false;
|
|
122
127
|
}
|
|
123
128
|
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
const count = await countLock(bucket, provider.id);
|
|
129
|
+
const count = await countLock(bucket, provider.id, maxDownloadTime);
|
|
127
130
|
|
|
128
131
|
if (count >= globalConnectionLimit) {
|
|
129
132
|
log.debug(`The "${provider.id}" provider's globalConnectionLimit of "${provider.globalConnectionLimit}" has been reached.`);
|
|
130
133
|
// wait for 5 second and try again
|
|
131
134
|
await sleep(5000);
|
|
132
|
-
return proceed(bucket, provider,
|
|
135
|
+
return proceed(bucket, provider, granuleId, counter + 1);
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
// add the lock
|
|
136
|
-
await addLock(bucket, provider.id,
|
|
139
|
+
await addLock(bucket, provider.id, granuleId);
|
|
137
140
|
return true;
|
|
138
141
|
}
|
package/src/queue.js
CHANGED
|
@@ -79,10 +79,10 @@ module.exports.enqueueParsePdrMessage = enqueueParsePdrMessage;
|
|
|
79
79
|
* Enqueue a granule to be ingested
|
|
80
80
|
*
|
|
81
81
|
* @param {Object} params
|
|
82
|
-
* @param {Object} params.
|
|
82
|
+
* @param {Object} params.granules - the granules to be enqueued for ingest
|
|
83
83
|
* @param {string} params.queueUrl - the SQS queue to add the message to
|
|
84
|
-
* @param {
|
|
85
|
-
*
|
|
84
|
+
* @param {Object} params.messageTemplate - Message template for the workflow
|
|
85
|
+
* @param {Object} params.workflow - workflow name & arn object
|
|
86
86
|
* @param {Object} params.provider - the provider config to be attached to the message
|
|
87
87
|
* @param {Object} params.collection - the collection config to be attached to the
|
|
88
88
|
* message
|
|
@@ -96,52 +96,34 @@ module.exports.enqueueParsePdrMessage = enqueueParsePdrMessage;
|
|
|
96
96
|
async function enqueueGranuleIngestMessage({
|
|
97
97
|
collection,
|
|
98
98
|
granules,
|
|
99
|
-
granuleIngestWorkflow,
|
|
100
99
|
parentExecutionArn,
|
|
101
100
|
pdr,
|
|
102
101
|
provider,
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
messageTemplate,
|
|
103
|
+
workflow,
|
|
105
104
|
queueUrl,
|
|
106
105
|
executionNamePrefix,
|
|
107
106
|
additionalCustomMeta = {},
|
|
108
107
|
}) {
|
|
109
|
-
const messageTemplate = await getJsonS3Object(systemBucket, templateKey(stack));
|
|
110
|
-
const { arn: ingestGranuleArn } = await getJsonS3Object(
|
|
111
|
-
systemBucket,
|
|
112
|
-
getWorkflowFileKey(stack, granuleIngestWorkflow)
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
const payload = { granules };
|
|
116
|
-
|
|
117
|
-
const workflow = {
|
|
118
|
-
name: granuleIngestWorkflow,
|
|
119
|
-
arn: ingestGranuleArn,
|
|
120
|
-
};
|
|
121
|
-
|
|
122
108
|
const message = buildQueueMessageFromTemplate({
|
|
123
109
|
messageTemplate,
|
|
124
110
|
parentExecutionArn,
|
|
125
|
-
payload,
|
|
111
|
+
payload: { granules },
|
|
126
112
|
workflow,
|
|
127
113
|
customMeta: {
|
|
128
114
|
...additionalCustomMeta,
|
|
115
|
+
...(pdr ? { pdr } : {}),
|
|
129
116
|
collection,
|
|
130
117
|
provider,
|
|
131
118
|
},
|
|
132
119
|
executionNamePrefix,
|
|
133
120
|
});
|
|
134
121
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const arn = buildExecutionArn(
|
|
122
|
+
await sendSQSMessage(queueUrl, message);
|
|
123
|
+
return buildExecutionArn(
|
|
138
124
|
message.cumulus_meta.state_machine,
|
|
139
125
|
message.cumulus_meta.execution_name
|
|
140
126
|
);
|
|
141
|
-
|
|
142
|
-
await sendSQSMessage(queueUrl, message);
|
|
143
|
-
|
|
144
|
-
return arn;
|
|
145
127
|
}
|
|
146
128
|
exports.enqueueGranuleIngestMessage = enqueueGranuleIngestMessage;
|
|
147
129
|
|