Skip to content

Commit 18ffb74

Browse files
committed
Merge branch 'improvement/S3UTILS-199' into q/1.16
2 parents c42eac4 + ce38a0e commit 18ffb74

File tree

6 files changed

+1303
-136
lines changed

6 files changed

+1303
-136
lines changed

CRR/ReplicationStatusUpdater.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
const {
2-
doWhilst, eachSeries, eachLimit, waterfall, series,
2+
doWhilst, eachSeries, eachLimit, waterfall,
33
} = require('async');
44
const { ObjectMD } = require('arsenal').models;
5-
65
const { setupClients } = require('./clients');
6+
const {
7+
ListObjectVersionsCommand,
8+
GetBucketReplicationCommand
9+
} = require('@aws-sdk/client-s3');
710

811
const LOG_PROGRESS_INTERVAL_MS = 10000;
912

@@ -26,6 +29,7 @@ class ReplicationStatusUpdater {
2629
* @param {number} [params.maxScanned] - (Optional) Maximum number of items to scan.
2730
* @param {string} [params.keyMarker] - (Optional) Key marker for resuming object listing.
2831
* @param {string} [params.versionIdMarker] - (Optional) Version ID marker for resuming object listing.
32+
* @param {boolean} [params.currentVersionOnly] - (Optional) Whether to process only the current version of objects.
2933
*/
3034
constructor(params, log) {
3135
const {
@@ -266,13 +270,15 @@ class ReplicationStatusUpdater {
266270
* @returns {void}
267271
*/
268272
_listObjectVersions(bucket, VersionIdMarker, KeyMarker, cb) {
269-
return this.s3.listObjectVersions({
273+
this.s3.send(new ListObjectVersionsCommand({
270274
Bucket: bucket,
271275
MaxKeys: this.listingLimit,
272276
Prefix: this.targetPrefix,
273277
VersionIdMarker,
274278
KeyMarker,
275-
}, cb);
279+
}))
280+
.then(data => cb(null, data))
281+
.catch(cb);
276282
}
277283

278284
/**
@@ -284,15 +290,16 @@ class ReplicationStatusUpdater {
284290
* @returns {void}
285291
*/
286292
_markPending(bucket, versions, cb) {
287-
const options = { Bucket: bucket };
288293
waterfall([
289-
next => this.s3.getBucketReplication(options, (err, res) => {
290-
if (err) {
294+
async () => {
295+
try {
296+
const res = await this.s3.send(new GetBucketReplicationCommand({ Bucket: bucket }));
297+
return res.ReplicationConfiguration;
298+
} catch (err) {
291299
this.log.error('error getting bucket replication', { error: err });
292-
return next(err);
300+
throw err;
293301
}
294-
return next(null, res.ReplicationConfiguration);
295-
}),
302+
},
296303
(repConfig, next) => {
297304
const { Rules } = repConfig;
298305
const storageClass = this.siteName || Rules[0].Destination.StorageClass;
@@ -348,7 +355,8 @@ class ReplicationStatusUpdater {
348355
this.log.error('error listing object versions', { error: err });
349356
return done(err);
350357
}
351-
return this._markPending(bucket, data.Versions.concat(data.DeleteMarkers), err => {
358+
const versions = (data.Versions || []).concat(data.DeleteMarkers || []);
359+
return this._markPending(bucket, versions, err => {
352360
if (err) {
353361
return done(err);
354362
}

CRR/clients.js

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
const AWS = require('aws-sdk');
1+
const { S3Client } = require('@aws-sdk/client-s3');
2+
const { NodeHttpHandler } = require('@aws-sdk/node-http-handler');
3+
const { ConfiguredRetryStrategy } = require('@smithy/util-retry');
24
const http = require('http');
5+
const https = require('https');
36
const BackbeatClient = require('../BackbeatClient');
47

58
const AWS_SDK_REQUEST_DELAY_MS = 30;
69
const AWS_SDK_REQUEST_RETRIES = 100;
7-
const LOG_PROGRESS_INTERVAL_MS = 10000;
810

911
/**
1012
* Sets up and configures AWS S3 and Backbeat clients.
@@ -27,7 +29,37 @@ function setupClients({
2729
secretKey,
2830
endpoint,
2931
}, log) {
30-
const awsConfig = {
32+
const awsv3Config = {
33+
region: 'us-east-1',
34+
credentials: {
35+
accessKeyId: accessKey,
36+
secretAccessKey: secretKey,
37+
},
38+
endpoint,
39+
forcePathStyle: true,
40+
requestHandler: new NodeHttpHandler({
41+
httpAgent: new http.Agent({ keepAlive: true }),
42+
httpsAgent: new https.Agent({
43+
keepAlive: true,
44+
// With SDK v2, SSL was disabled. Here we added this
45+
// to be able to run the script locally on a lab for testing,
46+
// so https will work but there will be no security enforced
47+
rejectUnauthorized: false
48+
}),
49+
requestTimeout: 60000,
50+
}),
51+
retryStrategy: new ConfiguredRetryStrategy(
52+
AWS_SDK_REQUEST_RETRIES, // maxAttempts
53+
attempt => {
54+
log.error('aws sdk request error', { retryCount: attempt });
55+
// The delay is not truly exponential; it resets to the minimum after every 10 calls,
56+
// with a maximum delay of 15 seconds.
57+
return AWS_SDK_REQUEST_DELAY_MS * (2 ** (attempt % 10));
58+
}
59+
)
60+
};
61+
62+
const awsv2Config = {
3163
accessKeyId: accessKey,
3264
secretAccessKey: secretKey,
3365
endpoint,
@@ -38,37 +70,15 @@ function setupClients({
3870
signatureVersion: 'v4',
3971
signatureCache: false,
4072
httpOptions: {
41-
timeout: 0,
73+
timeout: 60000,
4274
agent: new http.Agent({ keepAlive: true }),
4375
},
4476
};
4577

46-
/**
47-
* Custom backoff strategy for AWS SDK requests.
48-
* @param {number} retryCount - The current retry attempt.
49-
* @param {Error} error - The error that caused the retry.
50-
* @returns {number} The delay in milliseconds before the next retry.
51-
*/
52-
function customBackoffStrategy(retryCount, error) {
53-
this.log.error('aws sdk request error', { error, retryCount });
54-
// The delay is not truly exponential; it resets to the minimum after every 10 calls,
55-
// with a maximum delay of 15 seconds.
56-
return AWS_SDK_REQUEST_DELAY_MS * (2 ** (retryCount % 10));
57-
}
58-
59-
// Specific options for S3 requests
60-
const s3SpecificOptions = {
61-
maxRetries: AWS_SDK_REQUEST_RETRIES,
62-
customBackoff: customBackoffStrategy,
78+
return {
79+
s3: new S3Client(awsv3Config),
80+
bb: new BackbeatClient(awsv2Config),
6381
};
64-
65-
// Create an S3 client instance
66-
const s3 = new AWS.S3({ ...awsConfig, ...s3SpecificOptions });
67-
68-
// Create a BackbeatClient instance
69-
const bb = new BackbeatClient(awsConfig);
70-
71-
return { s3, bb };
7282
}
7383

7484
module.exports = { setupClients };

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
},
2727
"homepage": "https://github.com/scality/s3utils#readme",
2828
"dependencies": {
29+
"@aws-sdk/client-s3": "^3.873.0",
30+
"@aws-sdk/node-http-handler": "^3.374.0",
2931
"@senx/warp10": "^2.0.3",
32+
"@smithy/util-retry": "^4.0.7",
3033
"JSONStream": "^1.3.5",
3134
"arsenal": "git+https://github.com/scality/arsenal#8.2.26",
3235
"async": "^3.2.6",

0 commit comments

Comments
 (0)