Skip to content
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

fix composeObject api bug and update functional tests #1376

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/compose-object-test-example.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ const sampleRunComposeObject = async () => {
const destObjConfig = new Minio.CopyDestinationOptions({
Bucket: bucketName,
Object: composedObjName,
Headers: {
'Content-Type': 'application/octet-stream', //example to set headers
},
})

try {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ export interface ICopyDestinationOptions {
RetainUntilDate?: string
Mode?: RETENTION_MODES
MetadataDirective?: 'COPY' | 'REPLACE'
/**
* Extra headers for the target object
*/
Headers?: Record<string, string>
}

export class CopyDestinationOptions {
Expand All @@ -189,6 +193,7 @@ export class CopyDestinationOptions {
private readonly RetainUntilDate?: string
private readonly Mode?: RETENTION_MODES
private readonly MetadataDirective?: string
private readonly Headers?: Record<string, string>

constructor({
Bucket,
Expand All @@ -200,6 +205,7 @@ export class CopyDestinationOptions {
RetainUntilDate,
Mode,
MetadataDirective,
Headers,
}: ICopyDestinationOptions) {
this.Bucket = Bucket
this.Object = Object
Expand All @@ -210,6 +216,7 @@ export class CopyDestinationOptions {
this.Mode = Mode // retention mode
this.RetainUntilDate = RetainUntilDate
this.MetadataDirective = MetadataDirective
this.Headers = Headers
}

getHeaders(): RequestHeaders {
Expand Down Expand Up @@ -254,6 +261,12 @@ export class CopyDestinationOptions {
headerOptions[key] = value
}
}
if (this.Headers) {
for (const [key, value] of Object.entries(this.Headers)) {
headerOptions[key] = value
}
}

return headerOptions
}

Expand Down
5 changes: 4 additions & 1 deletion src/internal/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ import {
parseListObjects,
parseObjectLegalHoldConfig,
parseSelectObjectContentResponse,
uploadPartParser,
} from './xml-parser.ts'
import * as xmlParsers from './xml-parser.ts'

Expand Down Expand Up @@ -2670,8 +2671,10 @@ export class TypedClient {
const query = `uploadId=${uploadID}&partNumber=${partNumber}`
const requestOptions = { method, bucketName, objectName: objectName, query, headers }
const res = await this.makeRequestAsync(requestOptions, payload)
const body = await readAsString(res)
const partRes = uploadPartParser(body)
return {
etag: sanitizeETag(res.headers.etag),
etag: sanitizeETag(partRes.ETag),
key: objectName,
part: partNumber,
}
Expand Down
6 changes: 6 additions & 0 deletions src/internal/xml-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -734,3 +734,9 @@ export function parseListObjects(xml: string) {
}
return result
}

export function uploadPartParser(xml: string) {
const xmlObj = parseXml(xml)
const respEl = xmlObj.CopyPartResult
return respEl
}
36 changes: 23 additions & 13 deletions tests/functional/functional-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -3629,13 +3629,13 @@
const metadata = { 'X-Amz-Meta-Test': 'test-value' }

before(() => {
return client.makeBucket(bucketName, '').then((res) => {

Check warning on line 3632 in tests/functional/functional-tests.js

View workflow job for this annotation

GitHub Actions / lint

'res' is defined but never used
return client.putObject(bucketName, objectName, fdObject, fdObject.length, metadata).then((res) => {

Check warning on line 3633 in tests/functional/functional-tests.js

View workflow job for this annotation

GitHub Actions / lint

'res' is defined but never used
return client.setObjectTagging(bucketName, objectName, tags)
})
})
})
after(() => client.removeObject(bucketName, objectName).then((_) => client.removeBucket(bucketName)))

Check warning on line 3638 in tests/functional/functional-tests.js

View workflow job for this annotation

GitHub Actions / lint

'_' is defined but never used

step(
`extensions.listObjectsV2WithMetadata(bucketName, prefix, recursive)_bucketName:${bucketName}, prefix:"", recursive:true`,
Expand Down Expand Up @@ -4066,19 +4066,26 @@
* 7. Remove bucket. (Clean up)
*/

var _100mbFileToBeSplitAndComposed = Buffer.alloc(100 * 1024 * 1024, 0)
let composeObjectTestBucket = 'minio-js-test-compose-obj-' + uuid.v4()
const _100mbFileToBeSplitAndComposed = Buffer.alloc(100 * 1024 * 1024, 0)
const composeObjectTestBucket = 'minio-js-test-compose-obj-' + uuid.v4()
before(() => client.makeBucket(composeObjectTestBucket, ''))
after(() => client.removeBucket(composeObjectTestBucket))

const composedObjName = '_100-mb-file-to-test-compose'
const tmpSubDir = `${tmpDir}/compose`
var fileToSplit = `${tmpSubDir}/${composedObjName}`
const fileToSplit = `${tmpSubDir}/${composedObjName}`
let partFilesNamesWithPath = []
let partObjNameList = []
let isSplitSuccess = false
step(`Create a local file of 100 MB and split `, (done) => {
try {
if (!fs.existsSync(tmpSubDir)) {
fs.mkdirSync(tmpSubDir, { recursive: true }, function (err) {
if (err) {
done(err)
}
})
}
fs.writeFileSync(fileToSplit, _100mbFileToBeSplitAndComposed)
// 100 MB split into 26 MB part size.
splitFile
Expand All @@ -4088,11 +4095,11 @@
isSplitSuccess = true
done()
})
.catch(() => {
done()
.catch((err) => {
done(err)
})
} catch (err) {
done()
done(err)
}
})

Expand Down Expand Up @@ -4130,12 +4137,15 @@
Object: composedObjName,
})

client.composeObject(destObjConfig, sourcePartObjList).then((e) => {
if (e) {
return done(e)
}
done()
})
client
.composeObject(destObjConfig, sourcePartObjList)
.then((e) => {
if (!e) {
return done(e)
}
done()
})
.catch(done)
} else {
done()
}
Expand Down Expand Up @@ -4195,7 +4205,7 @@

step('Clean up temp directory part files', (done) => {
if (isSplitSuccess) {
fs.rmdirSync(tmpSubDir)
fs.rmSync(tmpSubDir, { recursive: true, force: true })
}
done()
})
Expand Down
Loading