diff --git a/packages/i18n/src/locales/en_US.ts b/packages/i18n/src/locales/en_US.ts index 7f175e8de1..489c3b7da7 100644 --- a/packages/i18n/src/locales/en_US.ts +++ b/packages/i18n/src/locales/en_US.ts @@ -2045,6 +2045,30 @@ const translations: Catalog = { 'Returns a cursor with information about metadata inconsistencies', example: 'sh.checkMetadataConsistency()', }, + moveCollection: { + link: 'https://docs.mongodb.com/manual/reference/method/sh.moveCollection', + description: + 'Moves a single unsharded collection to a different shard.', + example: 'sh.moveCollection(ns, toShard)', + }, + abortMoveCollection: { + link: 'https://docs.mongodb.com/manual/reference/method/sh.abortMoveCollection', + description: + 'Abort the current moveCollection operation on a given collection', + example: 'sh.abortMoveCollection(ns)', + }, + unshardCollection: { + link: 'https://docs.mongodb.com/manual/reference/method/sh.unshardCollection', + description: + 'Unshard the given collection and move all data to the given shard.', + example: 'sh.unshardCollection(ns, toShard)', + }, + abortUnshardCollection: { + link: 'https://docs.mongodb.com/manual/reference/method/sh.abortUnshardCollection', + description: + 'Abort the current unshardCollection operation on a given collection', + example: 'sh.abortUnshardCollection(ns)', + }, }, }, }, diff --git a/packages/shell-api/src/shard.spec.ts b/packages/shell-api/src/shard.spec.ts index 2391149018..a502601cc8 100644 --- a/packages/shell-api/src/shard.spec.ts +++ b/packages/shell-api/src/shard.spec.ts @@ -1790,6 +1790,120 @@ describe('Shard', function () { ); }); }); + + describe('moveCollection', function () { + it('calls serviceProvider.runCommandWithCheck', async function () { + await shard.moveCollection('db.coll', 'shard1'); + expect(serviceProvider.runCommandWithCheck).to.have.been.calledWith( + ADMIN_DB, + { + moveCollection: 'db.coll', + toShard: 'shard1', + } + ); + }); + + it('returns whatever serviceProvider.runCommandWithCheck returns', async function () { + const expectedResult = { ok: 1 }; + serviceProvider.runCommandWithCheck.resolves(expectedResult); + const result = await shard.moveCollection('db.coll', 'shard1'); + expect(result).to.deep.equal(expectedResult); + }); + + it('throws if serviceProvider.runCommandWithCheck rejects', async function () { + const expectedError = new Error(); + serviceProvider.runCommandWithCheck.rejects(expectedError); + const caughtError = await shard + .moveCollection('db.coll', 'shard1') + .catch((e) => e); + expect(caughtError).to.equal(expectedError); + }); + }); + + describe('abortMoveCollection', function () { + it('calls serviceProvider.runCommandWithCheck', async function () { + await shard.abortMoveCollection('db.coll'); + expect(serviceProvider.runCommandWithCheck).to.have.been.calledWith( + ADMIN_DB, + { + abortMoveCollection: 'db.coll', + } + ); + }); + + it('returns whatever serviceProvider.runCommandWithCheck returns', async function () { + const expectedResult = { ok: 1 }; + serviceProvider.runCommandWithCheck.resolves(expectedResult); + const result = await shard.abortMoveCollection('db.coll'); + expect(result).to.deep.equal(expectedResult); + }); + + it('throws if serviceProvider.runCommandWithCheck rejects', async function () { + const expectedError = new Error(); + serviceProvider.runCommandWithCheck.rejects(expectedError); + const caughtError = await shard + .abortMoveCollection('db.coll') + .catch((e) => e); + expect(caughtError).to.equal(expectedError); + }); + }); + + describe('unshardCollection', function () { + it('calls serviceProvider.runCommandWithCheck', async function () { + await shard.unshardCollection('db.coll', 'shard1'); + expect(serviceProvider.runCommandWithCheck).to.have.been.calledWith( + ADMIN_DB, + { + unshardCollection: 'db.coll', + toShard: 'shard1', + } + ); + }); + + it('returns whatever serviceProvider.runCommandWithCheck returns', async function () { + const expectedResult = { ok: 1 }; + serviceProvider.runCommandWithCheck.resolves(expectedResult); + const result = await shard.unshardCollection('db.coll', 'shard1'); + expect(result).to.deep.equal(expectedResult); + }); + + it('throws if serviceProvider.runCommandWithCheck rejects', async function () { + const expectedError = new Error(); + serviceProvider.runCommandWithCheck.rejects(expectedError); + const caughtError = await shard + .unshardCollection('db.coll', 'shard1') + .catch((e) => e); + expect(caughtError).to.equal(expectedError); + }); + }); + + describe('abortUnshardCollection', function () { + it('calls serviceProvider.runCommandWithCheck', async function () { + await shard.abortUnshardCollection('db.coll'); + expect(serviceProvider.runCommandWithCheck).to.have.been.calledWith( + ADMIN_DB, + { + abortUnshardCollection: 'db.coll', + } + ); + }); + + it('returns whatever serviceProvider.runCommandWithCheck returns', async function () { + const expectedResult = { ok: 1 }; + serviceProvider.runCommandWithCheck.resolves(expectedResult); + const result = await shard.abortUnshardCollection('db.coll'); + expect(result).to.deep.equal(expectedResult); + }); + + it('throws if serviceProvider.runCommandWithCheck rejects', async function () { + const expectedError = new Error(); + serviceProvider.runCommandWithCheck.rejects(expectedError); + const caughtError = await shard + .abortUnshardCollection('db.coll') + .catch((e) => e); + expect(caughtError).to.equal(expectedError); + }); + }); }); describe('integration', function () { diff --git a/packages/shell-api/src/shard.ts b/packages/shell-api/src/shard.ts index 9a700c9ff8..5df46f13e4 100644 --- a/packages/shell-api/src/shard.ts +++ b/packages/shell-api/src/shard.ts @@ -693,4 +693,61 @@ export default class Shard extends ShellApiWithMongoClass { checkMetadataConsistency: 1, }); } + + @serverVersions(['8.0.0', ServerVersions.latest]) + @apiVersions([]) + @returnsPromise + async moveCollection(ns: string, toShard: string): Promise { + assertArgsDefinedType( + [ns, toShard], + ['string', 'string'], + 'Shard.moveCollection' + ); + this._emitShardApiCall('moveCollection', { moveCollection: ns, toShard }); + return await this._database._runAdminCommand({ + moveCollection: ns, + toShard, + }); + } + + @serverVersions(['8.0.0', ServerVersions.latest]) + @apiVersions([]) + @returnsPromise + async abortMoveCollection(ns: string): Promise { + assertArgsDefinedType([ns], ['string'], 'Shard.abortMoveCollection'); + this._emitShardApiCall('abortMoveCollection', { abortMoveCollection: ns }); + return await this._database._runAdminCommand({ abortMoveCollection: ns }); + } + + @serverVersions(['8.0.0', ServerVersions.latest]) + @apiVersions([]) + @returnsPromise + async unshardCollection(ns: string, toShard: string): Promise { + assertArgsDefinedType( + [ns, toShard], + ['string', 'string'], + 'Shard.unshardCollection' + ); + this._emitShardApiCall('unshardCollection', { + unshardCollection: ns, + toShard, + }); + return await this._database._runAdminCommand({ + unshardCollection: ns, + toShard, + }); + } + + @serverVersions(['8.0.0', ServerVersions.latest]) + @apiVersions([]) + @returnsPromise + async abortUnshardCollection(ns: string): Promise { + assertArgsDefinedType([ns], ['string'], 'Shard.abortUnshardCollection'); + this._emitShardApiCall('abortUnshardCollection', { + abortUnshardCollection: ns, + }); + return await this._database._runAdminCommand({ + abortUnshardCollection: ns, + }); + } }