Compare commits
1 Commits
developmen
...
feature/AR
Author | SHA1 | Date |
---|---|---|
Nicolas Humbert | f91f75c97a |
|
@ -866,6 +866,42 @@ class MongoClientInterface {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update master with specific version if provided.
|
||||
* @param {Object} c bucket collection
|
||||
* @param {String} bucketName bucket name
|
||||
* @param {String} objName object name
|
||||
* @param {Object} objVal object metadata
|
||||
* @param {Object} params params
|
||||
* @param {String} params.masterVersionId master version id
|
||||
* @param {Object} log logger
|
||||
* @param {Function} cb callback
|
||||
* @return {undefined}
|
||||
*/
|
||||
putObjectMasterVer(c, bucketName, objName, objVal, params, log, cb) {
|
||||
const { masterVersionId, vFormat } = params;
|
||||
if (masterVersionId) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
objVal.versionId = masterVersionId;
|
||||
}
|
||||
const masterKey = formatMasterKey(objName, vFormat);
|
||||
c.update({
|
||||
_id: masterKey,
|
||||
}, {
|
||||
_id: masterKey,
|
||||
value: objVal,
|
||||
}, {
|
||||
upsert: true,
|
||||
}, err => {
|
||||
if (err) {
|
||||
log.error('putObjectNoVer: error updating master with specific version', { error: err.message });
|
||||
return cb(errors.InternalError);
|
||||
}
|
||||
const versionId = objVal.versionId || '';
|
||||
return cb(null, `{"versionId": "${versionId}"}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the putObjectVerCase function to use
|
||||
* depending on params
|
||||
|
@ -873,6 +909,9 @@ class MongoClientInterface {
|
|||
* @return {Function} suitable putObjectVerCase function
|
||||
*/
|
||||
getPutObjectVerStrategy(params) {
|
||||
if (params.masterVersionId || params.masterVersionId === '') {
|
||||
return this.putObjectMasterVer;
|
||||
}
|
||||
if (params.versionId === '') {
|
||||
return this.putObjectVerCase2;
|
||||
} else if (params.versionId) {
|
||||
|
|
|
@ -251,6 +251,7 @@ class VersioningRequestProcessor {
|
|||
put(request, logger, callback) {
|
||||
const { db, key, value, options } = request;
|
||||
// valid combinations of versioning options:
|
||||
// - masterVersionId: update master version.
|
||||
// - !versioning && !versionId: normal non-versioning put
|
||||
// - versioning && !versionId: create a new version
|
||||
// - versionId: update (PUT/DELETE) an existing version, and
|
||||
|
@ -261,6 +262,8 @@ class VersioningRequestProcessor {
|
|||
(options.versioning || options.versioning === '');
|
||||
const versionId = options &&
|
||||
(options.versionId || options.versionId === '');
|
||||
const masterVersionId = options &&
|
||||
(options.masterVersionId || options.masterVersionId === '');
|
||||
|
||||
const versioningCb = (err, array, vid) => {
|
||||
if (err) {
|
||||
|
@ -270,6 +273,9 @@ class VersioningRequestProcessor {
|
|||
logger, err => callback(err, `{"versionId":"${vid}"}`));
|
||||
};
|
||||
|
||||
if (masterVersionId) {
|
||||
return this.processMasterUpdate(request, logger, versioningCb);
|
||||
}
|
||||
if (versionId) {
|
||||
return this.processVersionSpecificPut(request, logger,
|
||||
versioningCb);
|
||||
|
@ -306,6 +312,30 @@ class VersioningRequestProcessor {
|
|||
return callback(null, ops, versionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a version specific putObject request.
|
||||
* This will update the master version.
|
||||
*
|
||||
* @param {object} request - the request in original
|
||||
* RepdConnection format { db, key
|
||||
* [, value][, type], method, options }
|
||||
* @param {object} logger - logger
|
||||
* @param {function} callback - expect callback(err, batch, versionId)
|
||||
* @return {any} - to finish the call
|
||||
*/
|
||||
processMasterUpdate(request, logger, callback) {
|
||||
const { key } = request;
|
||||
const { masterVersionId } = request.options;
|
||||
let value;
|
||||
if (masterVersionId === '') {
|
||||
value = request.value;
|
||||
} else {
|
||||
// if masterVersionId, use it as the version id.
|
||||
value = Version.appendVersionId(request.value, masterVersionId);
|
||||
}
|
||||
return callback(null, [{ key, value }], masterVersionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a version specific putObject request. This will create a batch
|
||||
* of operations for updating the target version, and the master version if
|
||||
|
|
|
@ -45,6 +45,36 @@ describe('MongoClientInterface:putObject', () => {
|
|||
return done();
|
||||
});
|
||||
|
||||
it('Should call putObjectMasterVer with correct params', () => {
|
||||
// Stubbing functions
|
||||
const putObjectMasterVer = sinon.spy();
|
||||
sinon.stub(client, 'getBucketVFormat').callsFake((bucketName, log, cb) => cb(null, 'v0'));
|
||||
sinon.stub(client, 'putObjectMasterVer').callsFake(putObjectMasterVer);
|
||||
// checking if function called with correct params
|
||||
const params = {
|
||||
masterVersionId: '1234',
|
||||
vFormat: 'v0',
|
||||
};
|
||||
client.putObject('example-bucket', 'example-object', {}, params, {}, {});
|
||||
const args = [null, 'example-bucket', 'example-object', {}, params, {}, {}];
|
||||
assert(putObjectMasterVer.calledOnceWith(...args));
|
||||
});
|
||||
|
||||
it('Should call putObjectMasterVer with empty masterVersionId', () => {
|
||||
// Stubbing functions
|
||||
const putObjectMasterVer = sinon.spy();
|
||||
sinon.stub(client, 'getBucketVFormat').callsFake((bucketName, log, cb) => cb(null, 'v0'));
|
||||
sinon.stub(client, 'putObjectMasterVer').callsFake(putObjectMasterVer);
|
||||
// checking if function called with correct params
|
||||
const params = {
|
||||
masterVersionId: '',
|
||||
vFormat: 'v0',
|
||||
};
|
||||
client.putObject('example-bucket', 'example-object', {}, params, {}, {});
|
||||
const args = [null, 'example-bucket', 'example-object', {}, params, {}, {}];
|
||||
assert(putObjectMasterVer.calledOnceWith(...args));
|
||||
});
|
||||
|
||||
it('Should call putObjectVerCase1 with correct params', done => {
|
||||
// Stubbing functions
|
||||
const putObjectVerCase1Spy = sinon.spy();
|
||||
|
@ -302,6 +332,65 @@ describe('MongoClientInterface:putObjectVerCase2', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('MongoClientInterface:putObjectMasterVer', () => {
|
||||
let client;
|
||||
|
||||
beforeAll(done => {
|
||||
client = new MongoClientInterface({});
|
||||
return done();
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
sinon.stub(utils, 'formatMasterKey').callsFake(() => 'example-master-key');
|
||||
return done();
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
sinon.restore();
|
||||
return done();
|
||||
});
|
||||
|
||||
it('should return empty versionId if empty masterVersionId provided', done => {
|
||||
const collection = {
|
||||
update: (filter, update, params, cb) => cb(null),
|
||||
};
|
||||
const params = {
|
||||
masterVersionId: '',
|
||||
};
|
||||
client.putObjectMasterVer(collection, 'example-bucket', 'example-object', {}, params, logger, (err, res) => {
|
||||
assert.deepStrictEqual(err, null);
|
||||
const expectedRes = '{"versionId": ""}';
|
||||
assert.deepStrictEqual(res, expectedRes);
|
||||
return done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the updated object versionId', done => {
|
||||
const collection = {
|
||||
update: (filter, update, params, cb) => cb(null),
|
||||
};
|
||||
const params = {
|
||||
masterVersionId: '1234',
|
||||
};
|
||||
client.putObjectMasterVer(collection, 'example-bucket', 'example-object', {}, params, logger, (err, res) => {
|
||||
assert.deepStrictEqual(err, null);
|
||||
const expectedRes = '{"versionId": "1234"}';
|
||||
assert.deepStrictEqual(res, expectedRes);
|
||||
return done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail when update fails', done => {
|
||||
const collection = {
|
||||
update: (filter, update, params, cb) => cb(errors.InternalError),
|
||||
};
|
||||
client.putObjectMasterVer(collection, 'example-bucket', 'example-object', {}, {}, logger, err => {
|
||||
assert.deepStrictEqual(err, errors.InternalError);
|
||||
return done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('MongoClientInterface:putObjectVerCase3', () => {
|
||||
let client;
|
||||
|
||||
|
|
|
@ -219,4 +219,37 @@ describe('test VSP', () => {
|
|||
}],
|
||||
done);
|
||||
});
|
||||
|
||||
it('should update master when using masterVersionId', done => {
|
||||
async.waterfall([next => {
|
||||
const request = {
|
||||
db: 'foo',
|
||||
key: 'bar',
|
||||
value: '{"qux":"quz"}',
|
||||
options: { versioning: true },
|
||||
};
|
||||
vsp.put(request, logger, next);
|
||||
},
|
||||
(res, next) => {
|
||||
const v1 = Version.from(res).getVersionId();
|
||||
const request = {
|
||||
db: 'foo',
|
||||
key: 'bar',
|
||||
value: '{"qux":"quz2"}',
|
||||
options: { masterVersionId: v1 },
|
||||
};
|
||||
vsp.put(request, logger, next);
|
||||
},
|
||||
(res, next) => {
|
||||
const request = {
|
||||
db: 'foo',
|
||||
key: 'bar',
|
||||
};
|
||||
vsp.get(request, logger, next);
|
||||
},
|
||||
(res, next) => {
|
||||
assert.strictEqual(JSON.parse(res).qux, 'quz2');
|
||||
next();
|
||||
}], done);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue