From 6063ef524fe8e4bf0cfdb6dc042abd1b95b6fdcb Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Mon, 15 Dec 2025 10:48:59 +0100 Subject: [PATCH 1/8] added quotas apis ISSUE: CLDSRVCLT-4 --- models/quotas/deleteBucketQuota.smithy | 14 ++++++ models/quotas/getBucketQuota.smithy | 17 ++++++++ models/quotas/updateBucketQuota.smithy | 23 ++++++++++ package.json | 21 +++++++-- service/cloudserverBucketQuota.smithy | 19 ++++++++ smithy-build.json | 22 ++++++++-- src/clients/bucketQuota.ts | 21 +++++++++ src/clients/cloudserver.ts | 18 ++++++++ src/index.ts | 21 +-------- src/utils.ts | 2 +- tests/testQuotaApis.test.ts | 60 ++++++++++++++++++++++++++ tests/testSetup.ts | 11 +++-- 12 files changed, 218 insertions(+), 31 deletions(-) create mode 100644 models/quotas/deleteBucketQuota.smithy create mode 100644 models/quotas/getBucketQuota.smithy create mode 100644 models/quotas/updateBucketQuota.smithy create mode 100644 service/cloudserverBucketQuota.smithy create mode 100644 src/clients/bucketQuota.ts create mode 100644 src/clients/cloudserver.ts create mode 100644 tests/testQuotaApis.test.ts diff --git a/models/quotas/deleteBucketQuota.smithy b/models/quotas/deleteBucketQuota.smithy new file mode 100644 index 00000000..61266c3d --- /dev/null +++ b/models/quotas/deleteBucketQuota.smithy @@ -0,0 +1,14 @@ +$version: "2.0" + +namespace cloudserver.bucketquota + +@http(method: "DELETE", uri: "/{Bucket}?quota=true") +@idempotent +operation DeleteBucketQuota { + input := { + @required + @httpLabel + Bucket: String + } + output := {} +} diff --git a/models/quotas/getBucketQuota.smithy b/models/quotas/getBucketQuota.smithy new file mode 100644 index 00000000..614615ac --- /dev/null +++ b/models/quotas/getBucketQuota.smithy @@ -0,0 +1,17 @@ +$version: "2.0" + +namespace cloudserver.bucketquota + +@http(method: "GET", uri: "/{Bucket}?quota=true") +@readonly +operation GetBucketQuota { + input := { + @required + @httpLabel + Bucket: String + } + output := { + Name: String + Quota: Long + } +} diff --git a/models/quotas/updateBucketQuota.smithy b/models/quotas/updateBucketQuota.smithy new file mode 100644 index 00000000..8c69dd00 --- /dev/null +++ b/models/quotas/updateBucketQuota.smithy @@ -0,0 +1,23 @@ +$version: "2.0" +namespace cloudserver.bucketquota + +@http(method: "PUT", uri: "/{Bucket}?quota=true") +@idempotent +operation UpdateBucketQuota { + input: QuotaConfiguration + output: UpdateBucketQuotaOutput +} + +structure QuotaConfiguration { + @required + @httpLabel + Bucket: String + + @required + Quota: Long +} + +structure UpdateBucketQuotaOutput { + @httpPayload + body: String +} \ No newline at end of file diff --git a/package.json b/package.json index 91cc0b65..a8d86723 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,20 @@ "description": "Smithy-generated TypeScript client for Cloudserver's internal APIs", "main": "dist/index.js", "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./*": { + "types": "./dist/*.d.ts", + "default": "./dist/*.js" + } + }, "files": [ "dist", - "build/smithy/source/typescript-codegen" + "build/smithy/cloudserver/typescript-codegen", + "build/smithy/cloudserverBucketQuota/typescript-codegen" ], "publishConfig": { "access": "public", @@ -18,9 +29,10 @@ "scripts": { "clean:build": "rm -rf build dist", "build:smithy": "smithy build", - "build:generated": "cd build/smithy/source/typescript-codegen && yarn install && yarn build", + "build:generated": "cd build/smithy/cloudserver/typescript-codegen && yarn install && yarn build", + "build:generated:bucketQuota": "cd build/smithy/cloudserverBucketQuota/typescript-codegen && yarn install && yarn build", "build:wrapper": "tsc", - "build": "yarn install && yarn clean:build && yarn build:smithy && yarn build:generated && yarn build:wrapper", + "build": "yarn install && yarn clean:build && yarn build:smithy && yarn build:generated && yarn build:generated:bucketQuota && yarn build:wrapper", "test": "jest", "test:indexes": "jest tests/testIndexesApis.test.ts", "test:error-handling": "jest tests/testErrorHandling.test.ts", @@ -29,7 +41,8 @@ "test:lifecycle": "jest tests/testLifecycleApis.test.ts", "test:metadata": "jest tests/testMetadataApis.test.ts", "test:raft": "jest tests/testRaftApis.test.ts", - "test:mongo-backend": "yarn test:indexes && yarn test:error-handling && yarn test:multiple-backend", + "test:bucketQuotas": "jest tests/testQuotaApis.test.ts", + "test:mongo-backend": "yarn test:indexes && yarn test:error-handling && yarn test:multiple-backend && yarn test:bucketQuotas", "test:metadata-backend": "yarn test:api && yarn test:lifecycle && yarn test:metadata && yarn test:raft", "lint": "eslint src tests", "typecheck": "tsc --noEmit" diff --git a/service/cloudserverBucketQuota.smithy b/service/cloudserverBucketQuota.smithy new file mode 100644 index 00000000..4a75ad78 --- /dev/null +++ b/service/cloudserverBucketQuota.smithy @@ -0,0 +1,19 @@ +$version: "2.0" + +namespace cloudserver.bucketquota + +use aws.protocols#restXml +use aws.auth#sigv4 +use aws.api#service + +@restXml(noErrorWrapping: true) +@sigv4(name: "s3") +@service(sdkId: "cloudserverBucketQuota") +service CloudserverBucketQuota { + version: "2018-07-11", + operations: [ + GetBucketQuota, + UpdateBucketQuota, + DeleteBucketQuota, + ] +} diff --git a/smithy-build.json b/smithy-build.json index 5f07bc34..5a475dd5 100644 --- a/smithy-build.json +++ b/smithy-build.json @@ -7,10 +7,24 @@ "software.amazon.smithy.typescript:smithy-aws-typescript-codegen:0.34.0" ] }, - "plugins": { - "typescript-codegen": { - "package": "@scality/cloudserverclient", - "packageVersion": "1.0.0" + "projections": { + "cloudserver": { + "plugins": { + "typescript-codegen": { + "service": "cloudserver.client#cloudserver", + "package": "@scality/cloudserverclient", + "packageVersion": "1.0.0" + } + } + }, + "cloudserverBucketQuota": { + "plugins": { + "typescript-codegen": { + "service": "cloudserver.bucketquota#CloudserverBucketQuota", + "package": "@scality/cloudserverclient-bucket", + "packageVersion": "1.0.0" + } + } } } } diff --git a/src/clients/bucketQuota.ts b/src/clients/bucketQuota.ts new file mode 100644 index 00000000..26e7603b --- /dev/null +++ b/src/clients/bucketQuota.ts @@ -0,0 +1,21 @@ +import { CloudserverClientConfig } from '../../build/smithy/cloudserver/typescript-codegen'; +import { + CloudserverBucketQuotaClient, + CloudserverBucketQuotaClientConfig, +} from '../../build/smithy/cloudserverBucketQuota/typescript-codegen'; + +export { + CloudserverBucketQuotaClientConfig, + GetBucketQuotaCommand, + GetBucketQuotaCommandOutput, + UpdateBucketQuotaCommand, + UpdateBucketQuotaCommandOutput, + DeleteBucketQuotaCommand, + DeleteBucketQuotaCommandOutput, +} from '../../build/smithy/cloudserverBucketQuota/typescript-codegen'; + +export class BucketQuotaClient extends CloudserverBucketQuotaClient { + constructor(config: CloudserverClientConfig | CloudserverBucketQuotaClientConfig) { + super(config); + } +} diff --git a/src/clients/cloudserver.ts b/src/clients/cloudserver.ts new file mode 100644 index 00000000..a3812459 --- /dev/null +++ b/src/clients/cloudserver.ts @@ -0,0 +1,18 @@ +import { + CloudserverClient as GeneratedCloudserverClient, + CloudserverClientConfig +} from '../../build/smithy/cloudserver/typescript-codegen'; +import { createCustomErrorMiddleware } from '../utils'; + +export * from '../../build/smithy/cloudserver/typescript-codegen'; +export class CloudserverClient extends GeneratedCloudserverClient { + constructor(config: CloudserverClientConfig) { + super(config); + + this.middlewareStack.add(createCustomErrorMiddleware(), { + step: 'deserialize', + name: 'cloudserverErrorHandler', + priority: 'normal', + }); + } +} diff --git a/src/index.ts b/src/index.ts index 88d50bd9..27edc3a6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,3 @@ -import { - CloudserverClient as GeneratedCloudserverClient, - CloudserverClientConfig -} from '../build/smithy/source/typescript-codegen'; -import { createCustomErrorMiddleware } from './utils'; - -export * from '../build/smithy/source/typescript-codegen'; +export * from './clients/cloudserver'; +export { BucketQuotaClient } from './clients/bucketQuota'; export * from './utils'; - -export class CloudserverClient extends GeneratedCloudserverClient { - constructor(config: CloudserverClientConfig) { - super(config); - - this.middlewareStack.add(createCustomErrorMiddleware(), { - step: 'deserialize', - name: 'cloudserverErrorHandler', - priority: 'normal', - }); - } -} diff --git a/src/utils.ts b/src/utils.ts index 83e2c4eb..9151fca7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,5 @@ import { XMLParser } from 'fast-xml-parser'; -import { CloudserverServiceException } from '../build/smithy/source/typescript-codegen'; +import { CloudserverServiceException } from '../build/smithy/cloudserver/typescript-codegen'; /** * Adds middleware to manually set the Content-Length header on a command. diff --git a/tests/testQuotaApis.test.ts b/tests/testQuotaApis.test.ts new file mode 100644 index 00000000..90530715 --- /dev/null +++ b/tests/testQuotaApis.test.ts @@ -0,0 +1,60 @@ +import { + BucketQuotaClient, + GetBucketQuotaCommand, + UpdateBucketQuotaCommand, + DeleteBucketQuotaCommand, +} from '../src/clients/bucketQuota'; +import { createTestClient, testConfig } from './testSetup'; +import assert from 'assert'; + +describe('Quota API Tests', () => { + let bucketQuotaClient: BucketQuotaClient; + const quotaValue = 12321; + + beforeAll(() => { + ({bucketQuotaClient} = createTestClient()); + }); + + it('should test Bucket quotas apis', async () => { + try { + await bucketQuotaClient.send(new GetBucketQuotaCommand({ Bucket: testConfig.bucketName })); + assert.fail('Expected NoSuchQuota error but got success response'); + } catch (error: any) { + assert.strictEqual(error.name, 'NoSuchQuota'); + assert.strictEqual(error.message, 'The specified resource does not have a quota.'); + } + + await bucketQuotaClient.send(new UpdateBucketQuotaCommand( + { Bucket: testConfig.bucketName, Quota: quotaValue }) + ); + + const getData = await bucketQuotaClient.send(new GetBucketQuotaCommand({ Bucket: testConfig.bucketName })); + assert.strictEqual(getData.Quota, quotaValue); + assert.strictEqual(getData.Name, testConfig.bucketName); + + await bucketQuotaClient.send(new DeleteBucketQuotaCommand({ Bucket: testConfig.bucketName })); + try { + await bucketQuotaClient.send(new GetBucketQuotaCommand({ Bucket: testConfig.bucketName })); + assert.fail('Expected NoSuchQuota error but got success response'); + } catch (error: any) { + assert.strictEqual(error.name, 'NoSuchQuota'); + assert.strictEqual(error.message, 'The specified resource does not have a quota.'); + } + }); + + it('should test Bucket quotas apis larger numbers', async () => { + const quotas = [ + 2_147_483_647, + 2_147_483_647 + 1, + 2**52, + ]; + for (const quota of quotas) { + await bucketQuotaClient.send(new UpdateBucketQuotaCommand( + { Bucket: testConfig.bucketName, Quota: quota }) + ); + + const getData = await bucketQuotaClient.send(new GetBucketQuotaCommand({ Bucket: testConfig.bucketName })); + assert.strictEqual(getData.Quota, quota); + } + }); +}); diff --git a/tests/testSetup.ts b/tests/testSetup.ts index d2b338b4..cebf7775 100644 --- a/tests/testSetup.ts +++ b/tests/testSetup.ts @@ -1,9 +1,9 @@ import https from 'https'; import assert from 'assert'; -import { CloudserverClient, CloudserverClientConfig } from '../src/index'; +import { CloudserverClient, CloudserverClientConfig } from '../src/clients/cloudserver'; import { S3Client, PutObjectCommand, CreateBucketCommand, PutBucketVersioningCommand } from '@aws-sdk/client-s3'; import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@aws-sdk/types'; - +import { BucketQuotaClient } from '../src/clients/bucketQuota'; jest.setTimeout(30000); const credentialsProvider: AwsCredentialIdentityProvider = async (): Promise => ({ @@ -76,9 +76,14 @@ async function initBucketForTests() { } } -export function createTestClient(): {client: CloudserverClient, s3client: S3Client} { +export function createTestClient(): { + client: CloudserverClient, + bucketQuotaClient: BucketQuotaClient, + s3client: S3Client + } { return { client: new CloudserverClient(config), + bucketQuotaClient: new BucketQuotaClient(config), s3client, }; } From c882857f581f880f0f032e53e9e1709c2fe6d522 Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Tue, 16 Dec 2025 17:49:04 +0100 Subject: [PATCH 2/8] extract smithy version from smithy-build for single source version ISSUE: CLDSRVCLT-4 --- .github/actions/setup-smithy/action.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/actions/setup-smithy/action.yml b/.github/actions/setup-smithy/action.yml index 18147e19..69339ecc 100644 --- a/.github/actions/setup-smithy/action.yml +++ b/.github/actions/setup-smithy/action.yml @@ -6,9 +6,11 @@ runs: steps: - name: Install Smithy CLI shell: bash - env: - SMITHY_VERSION: '1.61.0' run: | + # Extract Smithy version from smithy-build.json + SMITHY_VERSION=$(jq -r '.maven.dependencies[] | select(contains("smithy-aws-traits")) | split(":")[2]' smithy-build.json) + echo "Installing Smithy CLI version ${SMITHY_VERSION}" + mkdir -p smithy-install/smithy curl -L https://github.com/smithy-lang/smithy/releases/download/${SMITHY_VERSION}/smithy-cli-linux-x86_64.zip -o smithy-install/smithy-cli-linux-x86_64.zip unzip -qo smithy-install/smithy-cli-linux-x86_64.zip -d smithy-install From 96dd3385b27f1388f8542b0f998f0a54701fdc3a Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Tue, 30 Dec 2025 15:11:13 +0100 Subject: [PATCH 3/8] added example for bucket quota client ISSUE: CLDSRVCLT-4 --- examples/bucketQuota.ts | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/bucketQuota.ts diff --git a/examples/bucketQuota.ts b/examples/bucketQuota.ts new file mode 100644 index 00000000..f3f3b9d7 --- /dev/null +++ b/examples/bucketQuota.ts @@ -0,0 +1,47 @@ +import { + BucketQuotaClient, + CloudserverBucketQuotaClientConfig, + GetBucketQuotaCommand +} from '@scality/cloudserverclient/clients/bucketQuota'; + +const config: CloudserverBucketQuotaClientConfig = { + endpoint: 'http://localhost:8000', + credentials: { + accessKeyId: 'accessKey1', + secretAccessKey: 'verySecretKey1', + }, + region: 'us-east-1', + maxAttempts: 1, +}; + +const bucketQuotaClient = new BucketQuotaClient(config); +try { + const getBucketQuotaCommand = new GetBucketQuotaCommand({ + Bucket: 'aBucketName', + }); + + const quotaData = await bucketQuotaClient.send(getBucketQuotaCommand); + // { + // "$metadata": { + // "httpStatusCode": 200, + // "requestId": "aa0681fd844c9a2272fa", + // "extendedRequestId": "aa0681fd844c9a2272fa", + // "attempts": 1, + // "totalRetryDelay": 0 + // }, + // "Name": "aBucketName", + // "Quota": 42 + // } +} catch (error: any) { + console.error(error.name); // NoSuchBucket + console.error(error.message); // The specified bucket does not exist. + // { + // httpStatusCode: 404, + // requestId: "0caf000bc140bb9e62e9", + // extendedRequestId: "0caf000bc140bb9e62e9", + // cfId: undefined, + // attempts: 1, + // totalRetryDelay: 0, + // } + console.error(error.$metadata); +} From 677bfd9949cd4758c19a9450bffd7bf5ce696e14 Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Mon, 12 Jan 2026 15:55:09 +0100 Subject: [PATCH 4/8] refactor client : renamed cloudserver as backbeatRoutes client and reorganize folders ISSUE: CLDSRVCLT-4 --- .../{ => backbeatRoutes}/batchDelete.smithy | 2 +- .../commonStructures.smithy | 2 +- .../deleteBucketIndexes.smithy | 2 +- .../deleteObjectFromExpiration.smithy | 2 +- .../{ => backbeatRoutes}/getBucketCseq.smithy | 2 +- .../getBucketIndexes.smithy | 2 +- .../getBucketMetadata.smithy | 2 +- .../{ => backbeatRoutes}/getMetadata.smithy | 2 +- models/{ => backbeatRoutes}/getObject.smithy | 2 +- .../{ => backbeatRoutes}/getObjectList.smithy | 2 +- .../getRaftBuckets.smithy | 2 +- models/{ => backbeatRoutes}/getRaftId.smithy | 2 +- models/{ => backbeatRoutes}/getRaftLog.smithy | 2 +- .../listLifecycleCurrents.smithy | 2 +- .../listLifecycleNonCurrents.smithy | 2 +- .../listLifecycleOrphans.smithy | 2 +- .../multipleBackendAbortMPU.smithy | 2 +- .../multipleBackendCompleteMPU.smithy | 2 +- .../multipleBackendDeleteObject.smithy | 2 +- .../multipleBackendDeleteObjectTagging.smithy | 2 +- .../multipleBackendHeadObject.smithy | 2 +- .../multipleBackendInitiateMPU.smithy | 2 +- .../multipleBackendPutMPUPart.smithy | 2 +- .../multipleBackendPutObject.smithy | 2 +- .../multipleBackendPutObjectTagging.smithy | 2 +- .../putBucketIndexes.smithy | 2 +- .../{ => backbeatRoutes}/putMetadata.smithy | 2 +- models/{ => backbeatRoutes}/putdata.smithy | 2 +- package.json | 6 ++-- ...mithy => cloudserverBackbeatRoutes.smithy} | 6 ++-- service/cloudserverBucketQuota.smithy | 2 +- smithy-build.json | 4 +-- src/clients/backbeatRoutes.ts | 18 +++++++++++ src/clients/bucketQuota.ts | 3 +- src/clients/cloudserver.ts | 18 ----------- src/index.ts | 2 +- src/utils.ts | 8 +++-- tests/testApis.test.ts | 14 ++++----- tests/testErrorHandling.test.ts | 10 +++---- tests/testIndexesApis.test.ts | 12 ++++---- tests/testLifecycleApis.test.ts | 14 ++++----- tests/testMetadataApis.test.ts | 12 ++++---- tests/testMultipleBackendApis.test.ts | 30 +++++++++---------- tests/testRaftApis.test.ts | 14 ++++----- tests/testSetup.ts | 8 ++--- 45 files changed, 119 insertions(+), 118 deletions(-) rename models/{ => backbeatRoutes}/batchDelete.smithy (96%) rename models/{ => backbeatRoutes}/commonStructures.smithy (96%) rename models/{ => backbeatRoutes}/deleteBucketIndexes.smithy (92%) rename models/{ => backbeatRoutes}/deleteObjectFromExpiration.smithy (94%) rename models/{ => backbeatRoutes}/getBucketCseq.smithy (92%) rename models/{ => backbeatRoutes}/getBucketIndexes.smithy (94%) rename models/{ => backbeatRoutes}/getBucketMetadata.smithy (98%) rename models/{ => backbeatRoutes}/getMetadata.smithy (92%) rename models/{ => backbeatRoutes}/getObject.smithy (99%) rename models/{ => backbeatRoutes}/getObjectList.smithy (94%) rename models/{ => backbeatRoutes}/getRaftBuckets.smithy (93%) rename models/{ => backbeatRoutes}/getRaftId.smithy (91%) rename models/{ => backbeatRoutes}/getRaftLog.smithy (96%) rename models/{ => backbeatRoutes}/listLifecycleCurrents.smithy (98%) rename models/{ => backbeatRoutes}/listLifecycleNonCurrents.smithy (98%) rename models/{ => backbeatRoutes}/listLifecycleOrphans.smithy (98%) rename models/{ => backbeatRoutes}/multipleBackendAbortMPU.smithy (95%) rename models/{ => backbeatRoutes}/multipleBackendCompleteMPU.smithy (97%) rename models/{ => backbeatRoutes}/multipleBackendDeleteObject.smithy (94%) rename models/{ => backbeatRoutes}/multipleBackendDeleteObjectTagging.smithy (97%) rename models/{ => backbeatRoutes}/multipleBackendHeadObject.smithy (95%) rename models/{ => backbeatRoutes}/multipleBackendInitiateMPU.smithy (97%) rename models/{ => backbeatRoutes}/multipleBackendPutMPUPart.smithy (96%) rename models/{ => backbeatRoutes}/multipleBackendPutObject.smithy (97%) rename models/{ => backbeatRoutes}/multipleBackendPutObjectTagging.smithy (97%) rename models/{ => backbeatRoutes}/putBucketIndexes.smithy (92%) rename models/{ => backbeatRoutes}/putMetadata.smithy (95%) rename models/{ => backbeatRoutes}/putdata.smithy (96%) rename service/{cloudserver.smithy => cloudserverBackbeatRoutes.smithy} (88%) create mode 100644 src/clients/backbeatRoutes.ts delete mode 100644 src/clients/cloudserver.ts diff --git a/models/batchDelete.smithy b/models/backbeatRoutes/batchDelete.smithy similarity index 96% rename from models/batchDelete.smithy rename to models/backbeatRoutes/batchDelete.smithy index 5e9ff938..2585d46c 100644 --- a/models/batchDelete.smithy +++ b/models/backbeatRoutes/batchDelete.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @idempotent @http(method: "POST", uri: "/_/backbeat/batchdelete/{Bucket}/{Key+}") diff --git a/models/commonStructures.smithy b/models/backbeatRoutes/commonStructures.smithy similarity index 96% rename from models/commonStructures.smithy rename to models/backbeatRoutes/commonStructures.smithy index 02b67741..0f3556dc 100644 --- a/models/commonStructures.smithy +++ b/models/backbeatRoutes/commonStructures.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Streaming blob type for binary data transfer @streaming diff --git a/models/deleteBucketIndexes.smithy b/models/backbeatRoutes/deleteBucketIndexes.smithy similarity index 92% rename from models/deleteBucketIndexes.smithy rename to models/backbeatRoutes/deleteBucketIndexes.smithy index 54a14ac4..1a350b1f 100644 --- a/models/deleteBucketIndexes.smithy +++ b/models/backbeatRoutes/deleteBucketIndexes.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @http(method: "POST", uri: "/_/backbeat/index/{Bucket}?operation=delete") @idempotent diff --git a/models/deleteObjectFromExpiration.smithy b/models/backbeatRoutes/deleteObjectFromExpiration.smithy similarity index 94% rename from models/deleteObjectFromExpiration.smithy rename to models/backbeatRoutes/deleteObjectFromExpiration.smithy index a03890b0..4eaba01f 100644 --- a/models/deleteObjectFromExpiration.smithy +++ b/models/backbeatRoutes/deleteObjectFromExpiration.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @idempotent @http(method: "DELETE", uri: "/_/backbeat/expiration/{Bucket}/{Key+}") diff --git a/models/getBucketCseq.smithy b/models/backbeatRoutes/getBucketCseq.smithy similarity index 92% rename from models/getBucketCseq.smithy rename to models/backbeatRoutes/getBucketCseq.smithy index 95832bfc..8320d9ea 100644 --- a/models/getBucketCseq.smithy +++ b/models/backbeatRoutes/getBucketCseq.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Retrieves bucket sequence information @readonly diff --git a/models/getBucketIndexes.smithy b/models/backbeatRoutes/getBucketIndexes.smithy similarity index 94% rename from models/getBucketIndexes.smithy rename to models/backbeatRoutes/getBucketIndexes.smithy index f99de06e..044a5092 100644 --- a/models/getBucketIndexes.smithy +++ b/models/backbeatRoutes/getBucketIndexes.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @readonly @http(method: "GET", uri: "/_/backbeat/index/{Bucket}") diff --git a/models/getBucketMetadata.smithy b/models/backbeatRoutes/getBucketMetadata.smithy similarity index 98% rename from models/getBucketMetadata.smithy rename to models/backbeatRoutes/getBucketMetadata.smithy index 7749c55d..3cf1b0ab 100644 --- a/models/getBucketMetadata.smithy +++ b/models/backbeatRoutes/getBucketMetadata.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @readonly @http(method: "GET", uri: "/_/metadata/default/attributes/{Bucket}") diff --git a/models/getMetadata.smithy b/models/backbeatRoutes/getMetadata.smithy similarity index 92% rename from models/getMetadata.smithy rename to models/backbeatRoutes/getMetadata.smithy index 1ec56b81..f91f4667 100644 --- a/models/getMetadata.smithy +++ b/models/backbeatRoutes/getMetadata.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @http(method: "GET", uri: "/_/backbeat/metadata/{Bucket}/{Key+}") @readonly diff --git a/models/getObject.smithy b/models/backbeatRoutes/getObject.smithy similarity index 99% rename from models/getObject.smithy rename to models/backbeatRoutes/getObject.smithy index 6a65c6f4..3e08ebed 100644 --- a/models/getObject.smithy +++ b/models/backbeatRoutes/getObject.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @readonly @http(method: "GET", uri: "/{Bucket}/{Key+}", code: 200) diff --git a/models/getObjectList.smithy b/models/backbeatRoutes/getObjectList.smithy similarity index 94% rename from models/getObjectList.smithy rename to models/backbeatRoutes/getObjectList.smithy index 84958f74..df3d453f 100644 --- a/models/getObjectList.smithy +++ b/models/backbeatRoutes/getObjectList.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @readonly @http(method: "GET", uri: "/_/metadata/default/bucket/{Bucket}") diff --git a/models/getRaftBuckets.smithy b/models/backbeatRoutes/getRaftBuckets.smithy similarity index 93% rename from models/getRaftBuckets.smithy rename to models/backbeatRoutes/getRaftBuckets.smithy index b78acbc7..63ffb2e2 100644 --- a/models/getRaftBuckets.smithy +++ b/models/backbeatRoutes/getRaftBuckets.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Retrieves buckets associated with a specific Raft log ID @readonly diff --git a/models/getRaftId.smithy b/models/backbeatRoutes/getRaftId.smithy similarity index 91% rename from models/getRaftId.smithy rename to models/backbeatRoutes/getRaftId.smithy index 74dde516..0040fd29 100644 --- a/models/getRaftId.smithy +++ b/models/backbeatRoutes/getRaftId.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @readonly @http(method: "GET", uri: "/_/metadata/admin/buckets/{Bucket}/id") diff --git a/models/getRaftLog.smithy b/models/backbeatRoutes/getRaftLog.smithy similarity index 96% rename from models/getRaftLog.smithy rename to models/backbeatRoutes/getRaftLog.smithy index 8cbc04e9..0a614a0b 100644 --- a/models/getRaftLog.smithy +++ b/models/backbeatRoutes/getRaftLog.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Retrieves Raft log entries for a specific log ID @readonly diff --git a/models/listLifecycleCurrents.smithy b/models/backbeatRoutes/listLifecycleCurrents.smithy similarity index 98% rename from models/listLifecycleCurrents.smithy rename to models/backbeatRoutes/listLifecycleCurrents.smithy index dccf0427..8cdcc550 100644 --- a/models/listLifecycleCurrents.smithy +++ b/models/backbeatRoutes/listLifecycleCurrents.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// List lifecycle current objects operation @readonly diff --git a/models/listLifecycleNonCurrents.smithy b/models/backbeatRoutes/listLifecycleNonCurrents.smithy similarity index 98% rename from models/listLifecycleNonCurrents.smithy rename to models/backbeatRoutes/listLifecycleNonCurrents.smithy index 882e59db..5f9281d7 100644 --- a/models/listLifecycleNonCurrents.smithy +++ b/models/backbeatRoutes/listLifecycleNonCurrents.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// List lifecycle non-current objects operation @readonly diff --git a/models/listLifecycleOrphans.smithy b/models/backbeatRoutes/listLifecycleOrphans.smithy similarity index 98% rename from models/listLifecycleOrphans.smithy rename to models/backbeatRoutes/listLifecycleOrphans.smithy index 94a7fff5..a9a51b17 100644 --- a/models/listLifecycleOrphans.smithy +++ b/models/backbeatRoutes/listLifecycleOrphans.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// List lifecycle orphan objects operation @readonly diff --git a/models/multipleBackendAbortMPU.smithy b/models/backbeatRoutes/multipleBackendAbortMPU.smithy similarity index 95% rename from models/multipleBackendAbortMPU.smithy rename to models/backbeatRoutes/multipleBackendAbortMPU.smithy index fdd097e0..3249efdf 100644 --- a/models/multipleBackendAbortMPU.smithy +++ b/models/backbeatRoutes/multipleBackendAbortMPU.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Aborts a multipart upload for multiple backend storage @idempotent diff --git a/models/multipleBackendCompleteMPU.smithy b/models/backbeatRoutes/multipleBackendCompleteMPU.smithy similarity index 97% rename from models/multipleBackendCompleteMPU.smithy rename to models/backbeatRoutes/multipleBackendCompleteMPU.smithy index 450b0a16..8d4eb83d 100644 --- a/models/multipleBackendCompleteMPU.smithy +++ b/models/backbeatRoutes/multipleBackendCompleteMPU.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Completes a multipart upload for multiple backend storage @http(method: "POST", uri: "/_/backbeat/multiplebackenddata/{Bucket}/{Key+}?operation=completempu") diff --git a/models/multipleBackendDeleteObject.smithy b/models/backbeatRoutes/multipleBackendDeleteObject.smithy similarity index 94% rename from models/multipleBackendDeleteObject.smithy rename to models/backbeatRoutes/multipleBackendDeleteObject.smithy index f310f479..69e9f3e7 100644 --- a/models/multipleBackendDeleteObject.smithy +++ b/models/backbeatRoutes/multipleBackendDeleteObject.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @idempotent @http(method: "DELETE", uri: "/_/backbeat/multiplebackenddata/{Bucket}/{Key+}?operation=deleteobject", code: 200) diff --git a/models/multipleBackendDeleteObjectTagging.smithy b/models/backbeatRoutes/multipleBackendDeleteObjectTagging.smithy similarity index 97% rename from models/multipleBackendDeleteObjectTagging.smithy rename to models/backbeatRoutes/multipleBackendDeleteObjectTagging.smithy index c06d31d3..52908f4e 100644 --- a/models/multipleBackendDeleteObjectTagging.smithy +++ b/models/backbeatRoutes/multipleBackendDeleteObjectTagging.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Removes tags from an object in multiple backend storage @idempotent diff --git a/models/multipleBackendHeadObject.smithy b/models/backbeatRoutes/multipleBackendHeadObject.smithy similarity index 95% rename from models/multipleBackendHeadObject.smithy rename to models/backbeatRoutes/multipleBackendHeadObject.smithy index 567c3863..f224dfc2 100644 --- a/models/multipleBackendHeadObject.smithy +++ b/models/backbeatRoutes/multipleBackendHeadObject.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Retrieves metadata for an object from multiple backend storage @readonly diff --git a/models/multipleBackendInitiateMPU.smithy b/models/backbeatRoutes/multipleBackendInitiateMPU.smithy similarity index 97% rename from models/multipleBackendInitiateMPU.smithy rename to models/backbeatRoutes/multipleBackendInitiateMPU.smithy index 55ffc6cf..89982299 100644 --- a/models/multipleBackendInitiateMPU.smithy +++ b/models/backbeatRoutes/multipleBackendInitiateMPU.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Initiates a multipart upload for multiple backend storage @http(method: "POST", uri: "/_/backbeat/multiplebackenddata/{Bucket}/{Key+}?operation=initiatempu") diff --git a/models/multipleBackendPutMPUPart.smithy b/models/backbeatRoutes/multipleBackendPutMPUPart.smithy similarity index 96% rename from models/multipleBackendPutMPUPart.smithy rename to models/backbeatRoutes/multipleBackendPutMPUPart.smithy index debc395b..a571489e 100644 --- a/models/multipleBackendPutMPUPart.smithy +++ b/models/backbeatRoutes/multipleBackendPutMPUPart.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes use aws.auth#unsignedPayload diff --git a/models/multipleBackendPutObject.smithy b/models/backbeatRoutes/multipleBackendPutObject.smithy similarity index 97% rename from models/multipleBackendPutObject.smithy rename to models/backbeatRoutes/multipleBackendPutObject.smithy index 18974e1a..85cd5c29 100644 --- a/models/multipleBackendPutObject.smithy +++ b/models/backbeatRoutes/multipleBackendPutObject.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes use aws.auth#unsignedPayload diff --git a/models/multipleBackendPutObjectTagging.smithy b/models/backbeatRoutes/multipleBackendPutObjectTagging.smithy similarity index 97% rename from models/multipleBackendPutObjectTagging.smithy rename to models/backbeatRoutes/multipleBackendPutObjectTagging.smithy index 30b9d703..948133aa 100644 --- a/models/multipleBackendPutObjectTagging.smithy +++ b/models/backbeatRoutes/multipleBackendPutObjectTagging.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes /// Adds or updates tags for an object in multiple backend storage @http(method: "POST", uri: "/_/backbeat/multiplebackenddata/{Bucket}/{Key+}?operation=puttagging") diff --git a/models/putBucketIndexes.smithy b/models/backbeatRoutes/putBucketIndexes.smithy similarity index 92% rename from models/putBucketIndexes.smithy rename to models/backbeatRoutes/putBucketIndexes.smithy index 37b7def6..7d5d2781 100644 --- a/models/putBucketIndexes.smithy +++ b/models/backbeatRoutes/putBucketIndexes.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @http(method: "POST", uri: "/_/backbeat/index/{Bucket}?operation=add") operation PutBucketIndexes { diff --git a/models/putMetadata.smithy b/models/backbeatRoutes/putMetadata.smithy similarity index 95% rename from models/putMetadata.smithy rename to models/backbeatRoutes/putMetadata.smithy index 60faaae7..2aa181d9 100644 --- a/models/putMetadata.smithy +++ b/models/backbeatRoutes/putMetadata.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes @http(method: "PUT", uri: "/_/backbeat/metadata/{Bucket}/{Key+}") operation PutMetadata { diff --git a/models/putdata.smithy b/models/backbeatRoutes/putdata.smithy similarity index 96% rename from models/putdata.smithy rename to models/backbeatRoutes/putdata.smithy index a7d75f2a..45e45780 100644 --- a/models/putdata.smithy +++ b/models/backbeatRoutes/putdata.smithy @@ -1,5 +1,5 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes use aws.auth#unsignedPayload diff --git a/package.json b/package.json index a8d86723..e1cc5dcb 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "files": [ "dist", - "build/smithy/cloudserver/typescript-codegen", + "build/smithy/cloudserverBackbeatRoutes/typescript-codegen", "build/smithy/cloudserverBucketQuota/typescript-codegen" ], "publishConfig": { @@ -29,10 +29,10 @@ "scripts": { "clean:build": "rm -rf build dist", "build:smithy": "smithy build", - "build:generated": "cd build/smithy/cloudserver/typescript-codegen && yarn install && yarn build", + "build:generated:backbeatRoutes": "cd build/smithy/cloudserverBackbeatRoutes/typescript-codegen && yarn install && yarn build", "build:generated:bucketQuota": "cd build/smithy/cloudserverBucketQuota/typescript-codegen && yarn install && yarn build", "build:wrapper": "tsc", - "build": "yarn install && yarn clean:build && yarn build:smithy && yarn build:generated && yarn build:generated:bucketQuota && yarn build:wrapper", + "build": "yarn install && yarn clean:build && yarn build:smithy && yarn build:generated:backbeatRoutes && yarn build:generated:bucketQuota && yarn build:wrapper", "test": "jest", "test:indexes": "jest tests/testIndexesApis.test.ts", "test:error-handling": "jest tests/testErrorHandling.test.ts", diff --git a/service/cloudserver.smithy b/service/cloudserverBackbeatRoutes.smithy similarity index 88% rename from service/cloudserver.smithy rename to service/cloudserverBackbeatRoutes.smithy index 607f87cb..caac538b 100644 --- a/service/cloudserver.smithy +++ b/service/cloudserverBackbeatRoutes.smithy @@ -1,6 +1,6 @@ $version: "2.0" -namespace cloudserver.client +namespace cloudserver.backbeatRoutes use aws.protocols#restJson1 use aws.auth#sigv4 @@ -8,8 +8,8 @@ use aws.api#service @restJson1 @sigv4(name: "s3") -@service(sdkId: "cloudserver") -service cloudserver { +@service(sdkId: "CloudserverBackbeatRoutes") +service CloudserverBackbeatRoutes { version: "2017-07-01", operations: [ BatchDelete, diff --git a/service/cloudserverBucketQuota.smithy b/service/cloudserverBucketQuota.smithy index 4a75ad78..c21cfb1a 100644 --- a/service/cloudserverBucketQuota.smithy +++ b/service/cloudserverBucketQuota.smithy @@ -8,7 +8,7 @@ use aws.api#service @restXml(noErrorWrapping: true) @sigv4(name: "s3") -@service(sdkId: "cloudserverBucketQuota") +@service(sdkId: "CloudserverBucketQuota") service CloudserverBucketQuota { version: "2018-07-11", operations: [ diff --git a/smithy-build.json b/smithy-build.json index 5a475dd5..00589e82 100644 --- a/smithy-build.json +++ b/smithy-build.json @@ -8,10 +8,10 @@ ] }, "projections": { - "cloudserver": { + "cloudserverBackbeatRoutes": { "plugins": { "typescript-codegen": { - "service": "cloudserver.client#cloudserver", + "service": "cloudserver.backbeatRoutes#CloudserverBackbeatRoutes", "package": "@scality/cloudserverclient", "packageVersion": "1.0.0" } diff --git a/src/clients/backbeatRoutes.ts b/src/clients/backbeatRoutes.ts new file mode 100644 index 00000000..95089064 --- /dev/null +++ b/src/clients/backbeatRoutes.ts @@ -0,0 +1,18 @@ +import { + CloudserverBackbeatRoutesClient, + CloudserverBackbeatRoutesClientConfig, +} from '../../build/smithy/cloudserverBackbeatRoutes/typescript-codegen'; +import { createCustomErrorMiddleware } from '../utils'; + +export * from '../../build/smithy/cloudserverBackbeatRoutes/typescript-codegen'; +export class BackbeatRoutesClient extends CloudserverBackbeatRoutesClient { + constructor(config: CloudserverBackbeatRoutesClientConfig) { + super(config); + + this.middlewareStack.add(createCustomErrorMiddleware(), { + step: 'deserialize', + name: 'cloudserverErrorHandler', + priority: 'normal', + }); + } +} diff --git a/src/clients/bucketQuota.ts b/src/clients/bucketQuota.ts index 26e7603b..6e7af6a9 100644 --- a/src/clients/bucketQuota.ts +++ b/src/clients/bucketQuota.ts @@ -1,4 +1,3 @@ -import { CloudserverClientConfig } from '../../build/smithy/cloudserver/typescript-codegen'; import { CloudserverBucketQuotaClient, CloudserverBucketQuotaClientConfig, @@ -15,7 +14,7 @@ export { } from '../../build/smithy/cloudserverBucketQuota/typescript-codegen'; export class BucketQuotaClient extends CloudserverBucketQuotaClient { - constructor(config: CloudserverClientConfig | CloudserverBucketQuotaClientConfig) { + constructor(config: CloudserverBucketQuotaClientConfig) { super(config); } } diff --git a/src/clients/cloudserver.ts b/src/clients/cloudserver.ts deleted file mode 100644 index a3812459..00000000 --- a/src/clients/cloudserver.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { - CloudserverClient as GeneratedCloudserverClient, - CloudserverClientConfig -} from '../../build/smithy/cloudserver/typescript-codegen'; -import { createCustomErrorMiddleware } from '../utils'; - -export * from '../../build/smithy/cloudserver/typescript-codegen'; -export class CloudserverClient extends GeneratedCloudserverClient { - constructor(config: CloudserverClientConfig) { - super(config); - - this.middlewareStack.add(createCustomErrorMiddleware(), { - step: 'deserialize', - name: 'cloudserverErrorHandler', - priority: 'normal', - }); - } -} diff --git a/src/index.ts b/src/index.ts index 27edc3a6..46715b50 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ -export * from './clients/cloudserver'; +export * from './clients/backbeatRoutes'; export { BucketQuotaClient } from './clients/bucketQuota'; export * from './utils'; diff --git a/src/utils.ts b/src/utils.ts index 9151fca7..11eaebef 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,7 @@ import { XMLParser } from 'fast-xml-parser'; -import { CloudserverServiceException } from '../build/smithy/cloudserver/typescript-codegen'; +import { + CloudserverBackbeatRoutesServiceException +} from '../build/smithy/cloudserverBackbeatRoutes/typescript-codegen'; /** * Adds middleware to manually set the Content-Length header on a command. @@ -68,7 +70,7 @@ export function createCustomErrorMiddleware() { const xml = body?.toString() || ''; const errorInfo = parseXmlError(xml); - const xmlError: any = new CloudserverServiceException({ + const xmlError: any = new CloudserverBackbeatRoutesServiceException({ name: errorInfo.code || error.name, message: errorInfo.message || 'XML error response', $fault: statusCode >= 500 ? 'server' : 'client', @@ -88,7 +90,7 @@ export function createCustomErrorMiddleware() { const title = html.match(/]*>([^<]+)<\/title>/i); const message = title && title[1] || 'HTML error response'; - const htmlError: any = new CloudserverServiceException({ + const htmlError: any = new CloudserverBackbeatRoutesServiceException({ name: `HTML ${response?.reason || 'Error'}`, message, $fault: statusCode >= 500 ? 'server' : 'client', diff --git a/tests/testApis.test.ts b/tests/testApis.test.ts index 9733c379..dd566083 100644 --- a/tests/testApis.test.ts +++ b/tests/testApis.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, PutDataCommandInput, PutDataCommand, GetObjectInput, @@ -16,11 +16,11 @@ import { createTestClient, testConfig } from './testSetup'; import assert from 'assert'; describe('CloudServer API Tests', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; let s3client: S3Client; beforeAll(() => { - ({client, s3client} = createTestClient()); + ({backbeatRoutesClient, s3client} = createTestClient()); }); it('should test PutData', async () => { @@ -44,7 +44,7 @@ describe('CloudServer API Tests', () => { command2, getData.ContentLength ); - const data = await client.send(command2); + const data = await backbeatRoutesClient.send(command2); const locationAny: any = data.Location as any; assert.ok(locationAny[0].key !== undefined); }); @@ -56,7 +56,7 @@ describe('CloudServer API Tests', () => { RequestUids: '123', }; const getCommand = new GetObjectCommand(getInput); - const getData = await client.send(getCommand); + const getData = await backbeatRoutesClient.send(getCommand); const bodyStr = await getData.Body.transformToString(); assert.strictEqual(bodyStr, testConfig.objectData); }); @@ -67,7 +67,7 @@ describe('CloudServer API Tests', () => { Bucket: testConfig.bucketName, }; const getCommand = new GetObjectListCommand(getInput); - const getData = await client.send(getCommand); + const getData = await backbeatRoutesClient.send(getCommand); const contents = getData.Contents || []; assert.strictEqual(Array.isArray(contents), true); const found = contents.some(c => c?.key === testConfig.objectKey); @@ -94,7 +94,7 @@ describe('CloudServer API Tests', () => { }; const batchDeleteCommand = new BatchDeleteCommand(batchDeleteInput); - const result = await client.send(batchDeleteCommand); + const result = await backbeatRoutesClient.send(batchDeleteCommand); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); }); diff --git a/tests/testErrorHandling.test.ts b/tests/testErrorHandling.test.ts index acb78f74..c78cd031 100644 --- a/tests/testErrorHandling.test.ts +++ b/tests/testErrorHandling.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, MultipleBackendDeleteObjectInput, MultipleBackendDeleteObjectCommand, GetObjectInput, @@ -9,10 +9,10 @@ import assert from 'assert'; import { createTestClient, testConfig } from './testSetup'; describe('CloudServer test error handling', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; beforeAll(() => { - ({client} = createTestClient()); + ({backbeatRoutesClient} = createTestClient()); }); it('should test xml parsing', async () => { @@ -22,7 +22,7 @@ describe('CloudServer test error handling', () => { Key: 'notAKey', }; const getCommand = new GetObjectCommand(getInput); - await client.send(getCommand); + await backbeatRoutesClient.send(getCommand); assert.fail('Expected an error but none was thrown'); } catch (err: any) { assert.strictEqual(err.name, 'NoSuchKey'); @@ -42,7 +42,7 @@ describe('CloudServer test error handling', () => { StorageType: 'file' }; const commandDelete = new MultipleBackendDeleteObjectCommand(deleteInput); - await client.send(commandDelete); + await backbeatRoutesClient.send(commandDelete); } catch (err: any) { assert.strictEqual(err.name, 'NoSuchKey'); assert.strictEqual(err.$metadata?.httpStatusCode, 404); diff --git a/tests/testIndexesApis.test.ts b/tests/testIndexesApis.test.ts index b777cf83..253b05e8 100644 --- a/tests/testIndexesApis.test.ts +++ b/tests/testIndexesApis.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, GetBucketIndexesInput, GetBucketIndexesCommand, PutBucketIndexesInput, @@ -11,10 +11,10 @@ import assert from 'assert'; import { createTestClient, testConfig } from './testSetup'; describe('CloudServer Indexes API Tests', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; beforeAll(() => { - ({client} = createTestClient()); + ({backbeatRoutesClient} = createTestClient()); }); it('should test PutBucketIndexes', async () => { @@ -32,7 +32,7 @@ describe('CloudServer Indexes API Tests', () => { Body: new TextEncoder().encode(indexData), }; const putBucketIndexesCommand = new PutBucketIndexesCommand(putBucketIndexesInput); - const result = await client.send(putBucketIndexesCommand); + const result = await backbeatRoutesClient.send(putBucketIndexesCommand); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); @@ -41,7 +41,7 @@ describe('CloudServer Indexes API Tests', () => { Bucket: testConfig.bucketName, }; const getBucketIndexesCommand = new GetBucketIndexesCommand(getBucketIndexesInput); - const indexesData = await client.send(getBucketIndexesCommand); + const indexesData = await backbeatRoutesClient.send(getBucketIndexesCommand); assert.ok(indexesData.Indexes && indexesData.Indexes.length >= 1); }); @@ -60,7 +60,7 @@ describe('CloudServer Indexes API Tests', () => { Body: new TextEncoder().encode(indexesToDelete), }; const deleteBucketIndexesCommand = new DeleteBucketIndexesCommand(deleteBucketIndexesInput); - const result = await client.send(deleteBucketIndexesCommand); + const result = await backbeatRoutesClient.send(deleteBucketIndexesCommand); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); }); diff --git a/tests/testLifecycleApis.test.ts b/tests/testLifecycleApis.test.ts index d33a5c7f..c4052e78 100644 --- a/tests/testLifecycleApis.test.ts +++ b/tests/testLifecycleApis.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, ListLifecycleCurrentsInput, ListLifecycleCurrentsCommand, ListLifecycleNonCurrentsInput, @@ -13,10 +13,10 @@ import assert from 'assert'; import { createTestClient, testConfig } from './testSetup'; describe('CloudServer Lifecycle API Tests', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; beforeAll(() => { - ({client} = createTestClient()); + ({backbeatRoutesClient} = createTestClient()); }); it('should test ListLifecycleCurrents', async () => { @@ -25,7 +25,7 @@ describe('CloudServer Lifecycle API Tests', () => { MaxKeys: 1, }; const command = new ListLifecycleCurrentsCommand(listInput); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); assert.strictEqual(result.Contents?.[0].Key, testConfig.objectKey); }); @@ -35,7 +35,7 @@ describe('CloudServer Lifecycle API Tests', () => { MaxKeys: 5, }; const command = new ListLifecycleNonCurrentsCommand(listInput); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); @@ -45,7 +45,7 @@ describe('CloudServer Lifecycle API Tests', () => { MaxKeys: 5, }; const command = new ListLifecycleOrphansCommand(listInput); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); @@ -55,7 +55,7 @@ describe('CloudServer Lifecycle API Tests', () => { Key: testConfig.objectKey, }; const command = new DeleteObjectFromExpirationCommand(deleteInput); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); }); diff --git a/tests/testMetadataApis.test.ts b/tests/testMetadataApis.test.ts index 54b43f14..2d5ef60d 100644 --- a/tests/testMetadataApis.test.ts +++ b/tests/testMetadataApis.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, GetMetadataInput, GetMetadataCommand, PutMetadataInput, @@ -11,10 +11,10 @@ import assert from 'assert'; import { createTestClient, testConfig } from './testSetup'; describe('CloudServer Metadata API Tests', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; beforeAll(() => { - ({client} = createTestClient()); + ({backbeatRoutesClient} = createTestClient()); }); it('should test GetMetadata API', async () => { @@ -23,7 +23,7 @@ describe('CloudServer Metadata API Tests', () => { Key: testConfig.objectKey, }; const getMetadataCommand = new GetMetadataCommand(getMetadataInput); - const metadataData = await client.send(getMetadataCommand); + const metadataData = await backbeatRoutesClient.send(getMetadataCommand); assert.ok(metadataData.Body?.includes(testConfig.objectKey)); }); @@ -48,7 +48,7 @@ describe('CloudServer Metadata API Tests', () => { }; const command = new PutMetadataCommand(putInput); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); assert.strictEqual(result.$metadata.httpStatusCode, 200); }); @@ -58,7 +58,7 @@ describe('CloudServer Metadata API Tests', () => { Bucket: testConfig.bucketName, }; const getBucketMetadataCommand = new GetBucketMetadataCommand(getBucketMetadataInput); - const bucketMetadata = await client.send(getBucketMetadataCommand); + const bucketMetadata = await backbeatRoutesClient.send(getBucketMetadataCommand); assert.strictEqual(bucketMetadata.name, testConfig.bucketName); }); }); diff --git a/tests/testMultipleBackendApis.test.ts b/tests/testMultipleBackendApis.test.ts index 1f0310f0..6947f528 100644 --- a/tests/testMultipleBackendApis.test.ts +++ b/tests/testMultipleBackendApis.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, MultipleBackendPutObjectInput, MultipleBackendPutObjectCommand, MultipleBackendDeleteObjectInput, @@ -25,10 +25,10 @@ import assert from 'assert'; import crypto from 'crypto'; describe('CloudServer Multiple Backend API Tests', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; beforeAll(() => { - ({client} = createTestClient()); + ({backbeatRoutesClient} = createTestClient()); }); it('should test MultipleBackendPutObject and delete API', async () => { @@ -39,7 +39,7 @@ describe('CloudServer Multiple Backend API Tests', () => { RequestUids: '123', }; const getCommand = new GetObjectCommand(getInput); - const getData = await client.send(getCommand); + const getData = await backbeatRoutesClient.send(getCommand); const etag = getData.ETag?.replace(/"/g, '') || ''; const incomingMsg = getData.Body as any; @@ -69,7 +69,7 @@ describe('CloudServer Multiple Backend API Tests', () => { command, contentLength ); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); assert.ok(result.location && result.location.length > 0, 'Location should not be empty'); const location = result.location[0]; @@ -87,7 +87,7 @@ describe('CloudServer Multiple Backend API Tests', () => { StorageType: 'file' }; const commandDelete = new MultipleBackendDeleteObjectCommand(deleteInput); - const deleteResult = await client.send(commandDelete); + const deleteResult = await backbeatRoutesClient.send(commandDelete); assert.strictEqual(deleteResult.$metadata.httpStatusCode, 200); }); @@ -97,7 +97,7 @@ describe('CloudServer Multiple Backend API Tests', () => { Key: testConfig.objectKey, }; const getCommand = new GetObjectCommand(getInput); - const getData = await client.send(getCommand); + const getData = await backbeatRoutesClient.send(getCommand); const dataBody = await getData.Body.transformToString(); const bodyBuffer = Buffer.from(dataBody); const contentMD5 = crypto.createHash('md5').update(bodyBuffer).digest('hex'); @@ -121,7 +121,7 @@ describe('CloudServer Multiple Backend API Tests', () => { }; const command = new MultipleBackendPutObjectCommand(putInput as any); - const result = await client.send(command); + const result = await backbeatRoutesClient.send(command); const locationKey = result.location?.[0]?.key || ''; const headInput: MultipleBackendHeadObjectInput = { @@ -133,7 +133,7 @@ describe('CloudServer Multiple Backend API Tests', () => { }]) }; const headCommand = new MultipleBackendHeadObjectCommand(headInput); - const headResult = await client.send(headCommand); + const headResult = await backbeatRoutesClient.send(headCommand); assert.strictEqual(headResult.$metadata.httpStatusCode, 200); }); @@ -162,7 +162,7 @@ describe('CloudServer Multiple Backend API Tests', () => { ReplicationEndpointSite: 'aVal' }; const putTaggingCommand = new MultipleBackendPutObjectTaggingCommand(putTaggingInput); - const putTaggingResult = await client.send(putTaggingCommand); + const putTaggingResult = await backbeatRoutesClient.send(putTaggingCommand); assert.strictEqual(putTaggingResult.$metadata.httpStatusCode, 200); }); @@ -179,7 +179,7 @@ describe('CloudServer Multiple Backend API Tests', () => { }; const deleteTaggingCommand = new MultipleBackendDeleteObjectTaggingCommand(deleteTaggingInput); - const deleteTaggingResult = await client.send(deleteTaggingCommand); + const deleteTaggingResult = await backbeatRoutesClient.send(deleteTaggingCommand); assert.strictEqual(deleteTaggingResult.$metadata.httpStatusCode, 200); }); @@ -198,7 +198,7 @@ describe('CloudServer Multiple Backend API Tests', () => { }; const initiateMPUCommand = new MultipleBackendInitiateMPUCommand(initiateMPUInput); - const initiateMPUResult = await client.send(initiateMPUCommand); + const initiateMPUResult = await backbeatRoutesClient.send(initiateMPUCommand); const uploadId = initiateMPUResult.uploadId; assert.strictEqual(initiateMPUResult.$metadata.httpStatusCode, 200); @@ -208,7 +208,7 @@ describe('CloudServer Multiple Backend API Tests', () => { Key: testConfig.objectKey, }; const getCommand = new GetObjectCommand(getInput); - const getData = await client.send(getCommand); + const getData = await backbeatRoutesClient.send(getCommand); const putPartInput: MultipleBackendPutMPUPartInput = { Bucket: testConfig.bucketName, Key: `${testConfig.objectKey}-mpu`, @@ -220,7 +220,7 @@ describe('CloudServer Multiple Backend API Tests', () => { }; const putPartCommand = new MultipleBackendPutMPUPartCommand(putPartInput as any); - const putPartResult = await client.send(putPartCommand); + const putPartResult = await backbeatRoutesClient.send(putPartCommand); assert.strictEqual(putPartResult.$metadata.httpStatusCode, 200); const completeMPUInput: MultipleBackendCompleteMPUInput = { @@ -238,7 +238,7 @@ describe('CloudServer Multiple Backend API Tests', () => { })) }; const completeMPUCommand = new MultipleBackendCompleteMPUCommand(completeMPUInput); - const completeMPUResult = await client.send(completeMPUCommand); + const completeMPUResult = await backbeatRoutesClient.send(completeMPUCommand); assert.strictEqual(completeMPUResult.$metadata.httpStatusCode, 200); }); }); diff --git a/tests/testRaftApis.test.ts b/tests/testRaftApis.test.ts index 229f1a4f..0b23455b 100644 --- a/tests/testRaftApis.test.ts +++ b/tests/testRaftApis.test.ts @@ -1,5 +1,5 @@ import { - CloudserverClient, + BackbeatRoutesClient, GetRaftIdInput, GetRaftIdCommand, GetRaftBucketsInput, @@ -15,10 +15,10 @@ import stream from 'stream'; import JSONStream from 'JSONStream'; describe('CloudServer Raft API Tests', () => { - let client: CloudserverClient; + let backbeatRoutesClient: BackbeatRoutesClient; beforeAll(() => { - ({client} = createTestClient()); + ({backbeatRoutesClient} = createTestClient()); }); it('should test GetRaftId API', async () => { @@ -27,7 +27,7 @@ describe('CloudServer Raft API Tests', () => { Bucket: testConfig.bucketName, }; const getRaftIdCommand = new GetRaftIdCommand(getRaftIdInput); - const raftIdData = await client.send(getRaftIdCommand); + const raftIdData = await backbeatRoutesClient.send(getRaftIdCommand); assert.strictEqual(raftIdData.RaftId, '1'); }); @@ -37,7 +37,7 @@ describe('CloudServer Raft API Tests', () => { LogId: '1', }; const getRaftBucketsCommand = new GetRaftBucketsCommand(getRaftBucketsInput); - const raftBucketsData = await client.send(getRaftBucketsCommand); + const raftBucketsData = await backbeatRoutesClient.send(getRaftBucketsCommand); const raftBucketsDataAny: any = raftBucketsData.Buckets as any; assert.ok(raftBucketsDataAny.length >= 1); }); @@ -63,7 +63,7 @@ describe('CloudServer Raft API Tests', () => { Limit: 2, }; const getRaftLogCommand = new GetRaftLogCommand(getRaftLogInput); - const raftLogData = await client.send(getRaftLogCommand); + const raftLogData = await backbeatRoutesClient.send(getRaftLogCommand); function getRaftLogStreaming(done: any) { const recordStream = new ListRecordStream(); @@ -132,7 +132,7 @@ describe('CloudServer Raft API Tests', () => { Bucket: testConfig.bucketName, }; const getBucketCseqCommand = new GetBucketCseqCommand(getBucketCseqInput); - const bucketCseqData = await client.send(getBucketCseqCommand); + const bucketCseqData = await backbeatRoutesClient.send(getBucketCseqCommand); assert.ok(bucketCseqData.CseqInfo && Array.isArray(bucketCseqData.CseqInfo)); assert.ok(bucketCseqData.CseqInfo.length > 0, 'CseqInfo should not be empty'); }); diff --git a/tests/testSetup.ts b/tests/testSetup.ts index cebf7775..383a76e2 100644 --- a/tests/testSetup.ts +++ b/tests/testSetup.ts @@ -1,6 +1,6 @@ import https from 'https'; import assert from 'assert'; -import { CloudserverClient, CloudserverClientConfig } from '../src/clients/cloudserver'; +import { BackbeatRoutesClient, CloudserverBackbeatRoutesClientConfig } from '../src/clients/backbeatRoutes'; import { S3Client, PutObjectCommand, CreateBucketCommand, PutBucketVersioningCommand } from '@aws-sdk/client-s3'; import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@aws-sdk/types'; import { BucketQuotaClient } from '../src/clients/bucketQuota'; @@ -12,7 +12,7 @@ const credentialsProvider: AwsCredentialIdentityProvider = async (): Promise Date: Mon, 12 Jan 2026 18:19:01 +0100 Subject: [PATCH 5/8] added cloudserver global client to wrap all other clients ISSUE: CLDSRVCLT-4 --- src/clients/cloudserver.ts | 15 +++++++++++++++ src/index.ts | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/clients/cloudserver.ts diff --git a/src/clients/cloudserver.ts b/src/clients/cloudserver.ts new file mode 100644 index 00000000..d279de43 --- /dev/null +++ b/src/clients/cloudserver.ts @@ -0,0 +1,15 @@ +import { BackbeatRoutesClient } from './backbeatRoutes'; +import { BucketQuotaClient } from './bucketQuota'; +import { CloudserverBackbeatRoutesClientConfig } from '../../build/smithy/cloudserverBackbeatRoutes/typescript-codegen'; + +export type CloudserverClientConfig = CloudserverBackbeatRoutesClientConfig; + +export class CloudserverClient { + public readonly backbeatRoutes: BackbeatRoutesClient; + public readonly bucketQuota: BucketQuotaClient; + + constructor(config: CloudserverClientConfig) { + this.backbeatRoutes = new BackbeatRoutesClient(config); + this.bucketQuota = new BucketQuotaClient(config); + } +} diff --git a/src/index.ts b/src/index.ts index 46715b50..5c274a04 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export * from './clients/backbeatRoutes'; -export { BucketQuotaClient } from './clients/bucketQuota'; +export * from './clients/bucketQuota'; +export { CloudserverClient, CloudserverClientConfig } from './clients/cloudserver'; export * from './utils'; From 7f476de99d397066754e61c1c275c711ccfbfe09 Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Mon, 12 Jan 2026 18:19:25 +0100 Subject: [PATCH 6/8] added cloudserver global client example ISSUE: CLDSRVCLT-4 --- examples/cloudserverClient.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 examples/cloudserverClient.ts diff --git a/examples/cloudserverClient.ts b/examples/cloudserverClient.ts new file mode 100644 index 00000000..9b4b31b1 --- /dev/null +++ b/examples/cloudserverClient.ts @@ -0,0 +1,27 @@ +// cloudserverClient is a meta client that imports all other clients. +// In this library, you can either use individual clients (like BackbeatRoutesClient or BucketQuotaClient), +// or use this global client. + +import { + CloudserverClient, + CloudserverClientConfig, + GetObjectCommand +} from '@scality/cloudserverclient'; + +const command = new GetObjectCommand({ + Bucket: 'aBucketName', + Key: 'anObjectKey', +}); + +const config: CloudserverClientConfig = { + endpoint: 'http://localhost:8000', + credentials: { + accessKeyId: 'accessKey1', + secretAccessKey: 'verySecretKey1', + }, + region: 'us-east-1', +}; +const client = new CloudserverClient(config); + +const getData = await client.backbeatRoutes.send(command); +const bodyStr = await getData.Body.transformToString(); \ No newline at end of file From 2348f8fd2a11806f4c85a73432398392d53815cb Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Tue, 13 Jan 2026 10:36:02 +0100 Subject: [PATCH 7/8] use cloudserver 9.3.0-preview.1 in ci ISSUE: CLDSRVCLT-4 --- .github/docker-compose.cloudserver-metadata.yml | 2 +- .github/docker-compose.cloudserver-mongo.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/docker-compose.cloudserver-metadata.yml b/.github/docker-compose.cloudserver-metadata.yml index 25a9e2e5..52abc17f 100644 --- a/.github/docker-compose.cloudserver-metadata.yml +++ b/.github/docker-compose.cloudserver-metadata.yml @@ -7,7 +7,7 @@ services: - ./md-config.json:/mnt/standalone_workdir/config.json:ro cloudserver-metadata: - image: ghcr.io/scality/cloudserver:9.1.4 + image: ghcr.io/scality/cloudserver:9.3.0-preview.1 platform: linux/amd64 network_mode: 'host' environment: diff --git a/.github/docker-compose.cloudserver-mongo.yml b/.github/docker-compose.cloudserver-mongo.yml index 0fd3471c..7f208901 100644 --- a/.github/docker-compose.cloudserver-mongo.yml +++ b/.github/docker-compose.cloudserver-mongo.yml @@ -24,7 +24,7 @@ services: restart: "no" cloudserver: - image: ghcr.io/scality/cloudserver:9.1.4 + image: ghcr.io/scality/cloudserver:9.3.0-preview.1 platform: linux/amd64 ports: - "8000:8000" From 7271bada364d1385e1a9cd45b11cf8010796f86f Mon Sep 17 00:00:00 2001 From: sylvain senechal Date: Mon, 15 Dec 2025 14:50:28 +0100 Subject: [PATCH 8/8] bump version to 1.0.1 ISSUE: CLDSRVCLT-4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e1cc5dcb..c1b9fbce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@scality/cloudserverclient", - "version": "1.0.0", + "version": "1.0.1", "engines": { "node": ">=20" },