-
Notifications
You must be signed in to change notification settings - Fork 254
Improvement/cldsrv 724-backbeat-related-functional-tests #5985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
a1fff68
91fe932
7408990
0ff38c1
1c371b1
03dc295
ac83417
b07e438
c2f4c3a
0be0667
b534e28
3699de7
b3e16fb
536ef7f
1af0814
1ce0df8
cede1b9
553c156
768b263
5313153
eee9699
1d9770c
7e3a81d
4f3c944
f9fbace
ce181cb
42ed39e
908ba8d
e30a7b0
c73a9c1
31d137c
80e3e93
82472d0
74d7db3
1783b09
df480a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,28 +1,46 @@ | ||
| const { S3 } = require('aws-sdk'); | ||
| const { S3Client, ListObjectsCommand } = require('@aws-sdk/client-s3'); | ||
| const { NodeHttpHandler } = require('@smithy/node-http-handler'); | ||
| const http = require('http'); | ||
|
|
||
| const config = { | ||
| sslEnabled: false, | ||
| endpoint: 'http://127.0.0.1:8000', | ||
| signatureCache: false, | ||
| signatureVersion: 'v4', | ||
| region: 'us-east-1', | ||
| s3ForcePathStyle: true, | ||
| accessKeyId: 'accessKey1', | ||
| secretAccessKey: 'verySecretKey1', | ||
| forcePathStyle: true, | ||
| credentials: { | ||
| accessKeyId: 'accessKey1', | ||
| secretAccessKey: 'verySecretKey1', | ||
| }, | ||
| requestHandler: new NodeHttpHandler({ | ||
| httpAgent: new http.Agent({ keepAlive: false }), | ||
| }), | ||
| }; | ||
| const s3Client = new S3(config); | ||
|
|
||
| const encodedSearch = | ||
| encodeURIComponent('x-amz-meta-color="blue"'); | ||
| const req = s3Client.listObjects({ Bucket: 'bucketname' }); | ||
| const s3Client = new S3Client(config); | ||
|
|
||
| const encodedSearch = encodeURIComponent('x-amz-meta-color="blue"'); | ||
|
|
||
| const command = new ListObjectsCommand({ Bucket: 'bucketname' }); | ||
|
|
||
| command.middlewareStack.add( | ||
| next => async args => { | ||
| if (args.request && args.request.path) { | ||
| // eslint-disable-next-line no-param-reassign | ||
| args.request.path = `${args.request.path}?search=${encodedSearch}`; | ||
| } | ||
| return next(args); | ||
| }, | ||
| { | ||
| step: 'build', | ||
| name: 'addSearchParameter', | ||
| priority: 'high' | ||
| } | ||
| ); | ||
|
|
||
| // the build event | ||
| req.on('build', () => { | ||
| req.httpRequest.path = `${req.httpRequest.path}?search=${encodedSearch}`; | ||
| }); | ||
| req.on('success', res => { | ||
| process.stdout.write(`Result ${res.data}`); | ||
| }); | ||
| req.on('error', err => { | ||
| process.stdout.write(`Error ${err}`); | ||
| }); | ||
| req.send(); | ||
| // Send command and handle response | ||
| s3Client.send(command) | ||
| .then(data => { | ||
| process.stdout.write(`Result ${JSON.stringify(data)}`); | ||
| }) | ||
| .catch(err => { | ||
| process.stdout.write(`Error ${err}`); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,13 @@ if (config.backends.data === 'mem') { | |
| client = new DataFileInterface(config); | ||
| implName = 'file'; | ||
| } else if (config.backends.data === 'multiple') { | ||
| Object.keys(config.locationConstraints).filter(k => | ||
|
||
| config.locationConstraints[k].type === 'aws_s3' | ||
| ).map(k => ({ | ||
| name: k, | ||
| region: config.locationConstraints[k].details.region, | ||
| https: config.locationConstraints[k].details.https | ||
| })); | ||
| const clients = parseLC(config, vault); | ||
| client = new MultipleBackendGateway( | ||
| clients, metadata, locationStorageCheck); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -712,6 +712,41 @@ function putMetadata(request, response, bucketInfo, objMd, log, callback) { | |
| return metadata.putObjectMD(bucketName, objectKey, omVal, options, log, | ||
| (err, md) => { | ||
| if (err) { | ||
| // Handle duplicate key error during repair operation | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come we have this in sdkv3 migration ? Is it because you found a bug/flaky test and needed this to fix it ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes , this was found in tests flakiness and was added to fix it |
||
| // This can happen due to race conditions when multiple operations | ||
| // try to repair the master version simultaneously. Since repair | ||
| // is idempotent, if the master version already exists, we can | ||
| // treat this as success. | ||
| const errorMessage = err.message || err.toString() || ''; | ||
| const isRepairDuplicateKeyError = options.repairMaster && | ||
| (errorMessage.includes('E11000') || | ||
| errorMessage.includes('duplicate key') || | ||
| errorMessage.includes('repair')); | ||
|
|
||
| if (isRepairDuplicateKeyError) { | ||
| log.warn('duplicate key error during repair - treating as success', { | ||
| error: err, | ||
| method: 'putMetadata', | ||
| bucketName, | ||
| objectKey, | ||
| note: 'Repair operation is idempotent, master version already exists', | ||
| }); | ||
| // Treat as success - the repair already completed | ||
| // Get the current metadata to return | ||
| return metadata.getObjectMD(bucketName, objectKey, {}, log, | ||
| (getErr, currentMD) => { | ||
| if (getErr) { | ||
| log.warn('could not retrieve metadata after repair duplicate key error', { | ||
| error: getErr, | ||
| method: 'putMetadata', | ||
| }); | ||
| // Still treat as success since repair likely completed | ||
| return next(null, md || {}); | ||
| } | ||
| return next(null, currentMD || md || {}); | ||
| }); | ||
| } | ||
|
|
||
| log.error('error putting object metadata', { | ||
| error: err, | ||
| method: 'putMetadata', | ||
|
|
@@ -1521,7 +1556,7 @@ function routeBackbeatAPIProxy(request, response, requestContexts, log) { | |
| }); | ||
| return responseJSONBody(err, null, response, log); | ||
| } | ||
| // We don't use the authorization results for now | ||
| // We don't use the authorization results for now | ||
| // as the UI uses the external Cloudserver instance | ||
| // as a proxy to access the Backbeat API service. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just delete them ? We have githistory if needed