Skip to content

Commit

Permalink
get endpoints without filters
Browse files Browse the repository at this point in the history
  • Loading branch information
pallavi2209 committed Feb 27, 2017
1 parent 2b3ac69 commit c012a99
Show file tree
Hide file tree
Showing 4 changed files with 353 additions and 5 deletions.
120 changes: 118 additions & 2 deletions api/v1/controllers/samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,39 @@ const doPut = require('../helpers/verbs/doPut');
const u = require('../helpers/verbs/utils');
const httpStatus = require('../constants').httpStatus;
const logAuditAPI = require('../../../utils/loggingUtil').logAuditAPI;
const sampleStore = require('../../../cache/sampleStore');
const redisClient = require('../../../cache/redisCache').client.sampleStore;
const constants = sampleStore.constants;
const ZERO = 0;
const ONE = 1;

/**
* Convert array strings to Json for sample and aspect, then attach aspect to
* sample.
* @param {Object} sampleObj - Sample object from redis
* @param {Object} aspectObj - Aspect object from redis
* @param {String} method - Request method
* @returns {Object} - Sample object with aspect attached
*/
function cleanAddAspectToSample(sampleObj, aspectObj, method) {
let sampleRes = {};
sampleRes = sampleStore.arrayStringsToJson(
sampleObj, constants.fieldsToStringify.sample
);

const aspect = sampleStore.arrayStringsToJson(
aspectObj, constants.fieldsToStringify.aspect
);

sampleRes.aspect = aspect;

// add api links
sampleRes.apiLinks = u.getApiLinks(
sampleRes.name, helper, method
);

return sampleRes;
}

module.exports = {

Expand All @@ -49,7 +82,62 @@ module.exports = {
* @param {Function} next - The next middleware function in the stack
*/
findSamples(req, res, next) {
doFind(req, res, next, helper);
if (featureToggles.isFeatureEnabled(constants.featureName)) {
const sampleCmds = [];
const aspectCmds = [];
const response = [];

// get all Samples
redisClient.smembersAsync(constants.indexKey.sample)
.then((allSampleKeys) => {
// add to commands to get sample
allSampleKeys.forEach((sampleName) => {
sampleCmds.push(
[constants.commands.hgetall, sampleName.toLowerCase()]
);
});

// get all aspect names
return redisClient.smembersAsync(constants.indexKey.aspect);
})
.then((allAspectKeys) => {
// add to commands to get aspect
allAspectKeys.forEach((aspectName) => {
aspectCmds.push(
[constants.commands.hgetall, aspectName.toLowerCase()]
);
});

// get all samples and aspects
return Promise.all([
redisClient.batch(sampleCmds).execAsync(),
redisClient.batch(aspectCmds).execAsync(),
]);
})
.then((sampleAndAspects) => {
const samples = sampleAndAspects[ZERO];
const aspects = sampleAndAspects[ONE];

samples.forEach((sampleObj) => {
const sampleAspect = aspects.find((aspect) =>
aspect.name === sampleObj.name.split('|')[ONE]
);

const sampleRes = cleanAddAspectToSample(
sampleObj, sampleAspect, res.method
);

// add sample to response
response.push(sampleRes);
});
})
.then(() => {
res.status(httpStatus.OK).json(response);
})
.catch((err) => u.handleError(next, err, helper.modelName));
} else {
doFind(req, res, next, helper);
}
},

/**
Expand All @@ -62,7 +150,35 @@ module.exports = {
* @param {Function} next - The next middleware function in the stack
*/
getSample(req, res, next) {
doGet(req, res, next, helper);
if (featureToggles.isFeatureEnabled(constants.featureName)) {
const sampleName = req.swagger.params.key.value.toLowerCase();
const aspectName = sampleName.split('|')[ONE];
const commands = [];

// get sample
commands.push([
constants.commands.hgetall,
sampleStore.toKey(constants.objectType.sample, sampleName),
]);

// get aspect
commands.push([
constants.commands.hgetall,
sampleStore.toKey(constants.objectType.aspect, aspectName),
]);

redisClient.batch(commands).execAsync()
.then((responses) => {
// clean and attach aspect to sample
const sampleRes = cleanAddAspectToSample(
responses[ZERO], responses[ONE], res.method
);

res.status(httpStatus.OK).json(sampleRes);
});
} else {
doGet(req, res, next, helper);
}
},

/**
Expand Down
31 changes: 28 additions & 3 deletions cache/sampleStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const constants = {
objectType: { aspect: 'aspect', sample: 'sample', subject: 'subject' },
prefix: PFX,
separator: SEP,
commands: {
hgetall: 'hgetall',
hget: 'hget',
smembers: 'smembers',
},
};

/**
Expand All @@ -51,6 +56,23 @@ function toKey(type, name) {
return PFX + SEP + type + SEP + name.toLowerCase();
} // toKey

/**
* Covert array strings to json from redis object
* @param {Object} obj - Object to convert
* @param {Object} arrayFields - List of array fields which were stringified.
* @returns {Object} - Converted object
*/
function arrayStringsToJson(obj, arrayFields) {
Object.keys(obj).forEach((key) => {
// Some array fields might have already been parsed in previous calls
// because of pass-by-reference behaviour of object
if (arrayFields.includes(key) && (!Array.isArray(obj[key]))) {
obj[key] = JSON.parse(obj[key]);
}
});
return obj;
} // arrayStringsToJson

/**
* Clear all the "sampleStore" keys (for subjects, aspects, samples) from
* redis.
Expand Down Expand Up @@ -81,10 +103,12 @@ function eradicate() {
*/
function removeNullsAndStringifyArrays(obj, arrayFields) {
Object.keys(obj).forEach((key) => {
if (arrayFields.includes(key)) {
obj[key] = JSON.stringify(obj[key]);
} else if (obj[key] === null) {
// delete null fields and empty arrays, then stringify array fields
if (obj[key] === null ||
(Array.isArray(obj[key]) && obj[key].length === 0)) {
delete obj[key];
} else if (arrayFields.includes(key)) {
obj[key] = JSON.stringify(obj[key]);
}
});
return obj;
Expand Down Expand Up @@ -249,4 +273,5 @@ module.exports = {
init,
populate,
toKey,
arrayStringsToJson,
};
105 changes: 105 additions & 0 deletions tests/api/v1/redisEnabled/redisTestUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or
* https://opensource.org/licenses/BSD-3-Clause
*/

/**
* tests/api/v1/redisEnabled/redisTestUtil.js
*/
'use strict'; // eslint-disable-line strict
const sampleStore = require('../../../../cache/sampleStore');
const redisClient = require('../../../../cache/redisCache').client.sampleStore;
const tu = require('../../../testUtils');
const Aspect = tu.db.Aspect;
const Subject = tu.db.Subject;
const Sample = tu.db.Sample;
const testStartTime = new Date();

module.exports = {
populateRedis(done) {
let a1;
let a2;
let s1;
let s2;
let s3;
tu.toggleOverride(sampleStore.constants.featureName, true);
Aspect.create({
isPublished: true,
name: `${tu.namePrefix}Aspect1`,
timeout: '30s',
valueType: 'NUMERIC',
criticalRange: [0, 1],
relatedLinks: [
{ name: 'Google', value: 'http://www.google.com' },
{ name: 'Yahoo', value: 'http://www.yahoo.com' },
],
})
.then((created) => (a1 = created))
.then(() => Aspect.create({
isPublished: true,
name: `${tu.namePrefix}Aspect2`,
timeout: '10m',
valueType: 'BOOLEAN',
okRange: [10, 100],
}))
.then((created) => (a2 = created))
.then(() => Subject.create({
isPublished: true,
name: `${tu.namePrefix}Subject1`,
}))
.then((created) => (s1 = created))
.then(() => Subject.create({
isPublished: true,
name: `${tu.namePrefix}Subject2`,
parentId: s1.id,
}))
.then((created) => (s2 = created))
.then(() => Subject.create({
isPublished: true,
name: `${tu.namePrefix}Subject3`,
parentId: s1.id,
}))
.then((created) => (s3 = created))
.then(() => Sample.create({
subjectId: s2.id,
aspectId: a1.id,
value: '0',
relatedLinks: [
{ name: 'Salesforce', value: 'http://www.salesforce.com' },
],
}))
.then(() => Sample.create({
subjectId: s2.id,
aspectId: a2.id,
value: '50',
relatedLinks: [
{ name: 'Salesforce', value: 'http://www.salesforce.com' },
],
}))
.then(() => Sample.create({
subjectId: s3.id,
aspectId: a1.id,
value: '5',
relatedLinks: [
{ name: 'Salesforce', value: 'http://www.salesforce.com' },
],
}))
.then(() => sampleStore.init())
.then(() => done())
.catch(done);
},

forceDelete: (done) => {
tu.forceDelete(tu.db.Sample, testStartTime)
.then(() => tu.forceDelete(tu.db.Aspect, testStartTime))
.then(() => tu.forceDelete(tu.db.Subject, testStartTime))
.then(() => tu.forceDelete(tu.db.Profile, testStartTime))
.then(() => tu.forceDelete(tu.db.User, testStartTime))
.then(() => redisClient.flushallAsync())
.then(() => done())
.catch(done);
},
};
Loading

0 comments on commit c012a99

Please sign in to comment.