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
|
* Returns the putObjectVerCase function to use
|
||||||
* depending on params
|
* depending on params
|
||||||
|
@ -873,6 +909,9 @@ class MongoClientInterface {
|
||||||
* @return {Function} suitable putObjectVerCase function
|
* @return {Function} suitable putObjectVerCase function
|
||||||
*/
|
*/
|
||||||
getPutObjectVerStrategy(params) {
|
getPutObjectVerStrategy(params) {
|
||||||
|
if (params.masterVersionId || params.masterVersionId === '') {
|
||||||
|
return this.putObjectMasterVer;
|
||||||
|
}
|
||||||
if (params.versionId === '') {
|
if (params.versionId === '') {
|
||||||
return this.putObjectVerCase2;
|
return this.putObjectVerCase2;
|
||||||
} else if (params.versionId) {
|
} else if (params.versionId) {
|
||||||
|
|
|
@ -251,6 +251,7 @@ class VersioningRequestProcessor {
|
||||||
put(request, logger, callback) {
|
put(request, logger, callback) {
|
||||||
const { db, key, value, options } = request;
|
const { db, key, value, options } = request;
|
||||||
// valid combinations of versioning options:
|
// valid combinations of versioning options:
|
||||||
|
// - masterVersionId: update master version.
|
||||||
// - !versioning && !versionId: normal non-versioning put
|
// - !versioning && !versionId: normal non-versioning put
|
||||||
// - versioning && !versionId: create a new version
|
// - versioning && !versionId: create a new version
|
||||||
// - versionId: update (PUT/DELETE) an existing version, and
|
// - versionId: update (PUT/DELETE) an existing version, and
|
||||||
|
@ -261,6 +262,8 @@ class VersioningRequestProcessor {
|
||||||
(options.versioning || options.versioning === '');
|
(options.versioning || options.versioning === '');
|
||||||
const versionId = options &&
|
const versionId = options &&
|
||||||
(options.versionId || options.versionId === '');
|
(options.versionId || options.versionId === '');
|
||||||
|
const masterVersionId = options &&
|
||||||
|
(options.masterVersionId || options.masterVersionId === '');
|
||||||
|
|
||||||
const versioningCb = (err, array, vid) => {
|
const versioningCb = (err, array, vid) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -270,6 +273,9 @@ class VersioningRequestProcessor {
|
||||||
logger, err => callback(err, `{"versionId":"${vid}"}`));
|
logger, err => callback(err, `{"versionId":"${vid}"}`));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (masterVersionId) {
|
||||||
|
return this.processMasterUpdate(request, logger, versioningCb);
|
||||||
|
}
|
||||||
if (versionId) {
|
if (versionId) {
|
||||||
return this.processVersionSpecificPut(request, logger,
|
return this.processVersionSpecificPut(request, logger,
|
||||||
versioningCb);
|
versioningCb);
|
||||||
|
@ -306,6 +312,30 @@ class VersioningRequestProcessor {
|
||||||
return callback(null, ops, versionId);
|
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
|
* Processes a version specific putObject request. This will create a batch
|
||||||
* of operations for updating the target version, and the master version if
|
* of operations for updating the target version, and the master version if
|
||||||
|
|
|
@ -45,6 +45,36 @@ describe('MongoClientInterface:putObject', () => {
|
||||||
return done();
|
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 => {
|
it('Should call putObjectVerCase1 with correct params', done => {
|
||||||
// Stubbing functions
|
// Stubbing functions
|
||||||
const putObjectVerCase1Spy = sinon.spy();
|
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', () => {
|
describe('MongoClientInterface:putObjectVerCase3', () => {
|
||||||
let client;
|
let client;
|
||||||
|
|
||||||
|
|
|
@ -219,4 +219,37 @@ describe('test VSP', () => {
|
||||||
}],
|
}],
|
||||||
done);
|
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