Skip to content

Commit

Permalink
realtime events for put, patch, and delete moved to api layer for sam…
Browse files Browse the repository at this point in the history
…ples (#298)
  • Loading branch information
shriramshankar authored and annyhe committed Mar 22, 2017
1 parent 5c75891 commit 8033e59
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 59 deletions.
9 changes: 9 additions & 0 deletions api/v1/helpers/nouns/samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
'use strict';

const Sample = require('../../../../db/index').Sample;
const Aspect = require('../../../../db/index').Aspect;
const Subject = require('../../../../db/index').Subject;

const m = 'sample';
const fieldsWithJsonArrayType = ['relatedLinks'];

Expand All @@ -33,4 +36,10 @@ module.exports = {
fieldsWithJsonArrayType,
fieldsWithEnum,
fieldsToExclude,
publishEvents: true,
associatedModels: {
aspect: Aspect,
subject: Subject,
},

}; // exports
8 changes: 8 additions & 0 deletions api/v1/helpers/verbs/doDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
'use strict'; // eslint-disable-line strict

const u = require('./utils');
const publisher = u.publisher;
const event = u.realtimeEvents;
const httpStatus = require('../../constants').httpStatus;
const featureToggles = require('feature-toggles');
const constants = require('../../../../cache/sampleStore').constants;
Expand Down Expand Up @@ -58,6 +60,12 @@ function doDelete(req, res, next, props) {
);
}

// publish the delete event to the redis channel
if (props.publishEvents) {
publisher.publishSample(o, props.associatedModels.subject,
event.sample.del);
}

// when a resource is deleted, delete all its associations too
u.deleteAllAssociations(o, assocNames);
u.logAPI(req, resultObj, o);
Expand Down
9 changes: 9 additions & 0 deletions api/v1/helpers/verbs/doPatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

const featureToggles = require('feature-toggles');
const u = require('./utils');
const publisher = u.publisher;
const event = u.realtimeEvents;
const httpStatus = require('../../constants').httpStatus;
const constants = require('../../../../cache/sampleStore').constants;
const redisModelSample = require('../../../../cache/models/samples');
Expand Down Expand Up @@ -66,6 +68,13 @@ function doPatch(req, res, next, props) {
.then((retVal) => {
resultObj.dbTime = new Date() - resultObj.reqStartTime;
u.logAPI(req, resultObj, retVal);

// publish the update event to the redis channel
if (props.publishEvents) {
publisher.publishSample(retVal,
props.associatedModels.subject, event.sample.upd);
}

return res.status(httpStatus.OK)
.json(u.responsify(retVal, props, req.method));
})
Expand Down
9 changes: 9 additions & 0 deletions api/v1/helpers/verbs/doPost.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
'use strict'; // eslint-disable-line strict

const u = require('./utils');
const publisher = u.publisher;
const event = u.realtimeEvents;
const httpStatus = require('../../constants').httpStatus;
const constants = require('../../../../cache/sampleStore').constants;
const redisModelSample = require('../../../../cache/models/samples');
Expand Down Expand Up @@ -47,6 +49,13 @@ function doPost(req, res, next, props) {
postPromise.then((o) => {
resultObj.dbTime = new Date() - resultObj.reqStartTime;
u.logAPI(req, resultObj, o);

// publish the update event to the redis channel
if (props.publishEvents) {
publisher.publishSample(o, props.associatedModels.subject,
event.sample.add, props.associatedModels.aspect);
}

return res.status(httpStatus.CREATED)
.json(u.responsify(o, props, req.method));
})
Expand Down
9 changes: 9 additions & 0 deletions api/v1/helpers/verbs/doPut.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

const featureToggles = require('feature-toggles');
const u = require('./utils');
const publisher = u.publisher;
const event = u.realtimeEvents;
const httpStatus = require('../../constants').httpStatus;
const constants = require('../../../../cache/sampleStore').constants;
const redisModelSample = require('../../../../cache/models/samples');
Expand Down Expand Up @@ -75,6 +77,13 @@ function doPut(req, res, next, props) {
putPromise.then((o) => {
resultObj.dbTime = new Date() - resultObj.reqStartTime;
u.logAPI(req, resultObj, o);

// publish the update event to the redis channel
if (props.publishEvents) {
publisher.publishSample(o, props.associatedModels.subject,
event.sample.upd);
}

res.status(httpStatus.OK).json(u.responsify(o, props, req.method));
})
.catch((err) => u.handleError(next, err, props.modelName));
Expand Down
1 change: 1 addition & 0 deletions api/v1/helpers/verbs/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ function checkDuplicateRLinks(rLinkArr) {
// ----------------------------------------------------------------------------

module.exports = {

realtimeEvents,

publisher,
Expand Down
52 changes: 4 additions & 48 deletions db/model/sample.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,10 @@ module.exports = function sample(seq, dataTypes) {
.then((o) => resolve(o))
.catch((err) => {
if (isBulk) {
/* adding isFailed:true to differentiate failed results from
success results in bulk upsert */
/*
* adding isFailed:true to differentiate failed results from
* success results in bulk upsert
*/
resolve({ explanation: err, isFailed: true });
} else {
reject(err);
Expand Down Expand Up @@ -319,52 +321,6 @@ module.exports = function sample(seq, dataTypes) {
);
}, // hooks.beforeCreate

/**
* Publishes the created sample to redis channel *including* the values
* from its aspect association.
*
* @param {Sample} inst - The newly-created instance
*/
afterCreate(inst /* , opts */) {
let samp;
Sample.findOne({
where: {
name: {
$iLike: inst.getDataValue('name'),
},
},
})
.then((found) => {
samp = found;
return common.sampleAspectAndSubjectArePublished(seq, samp);
})
.then((published) => {
if (published) {
// augment the sample instance with the subject instance to enable
// filtering by subjecttags in the realtime socketio module
common.augmentSampleWithSubjectAspectInfo(seq, samp)
.then(() => common.publishChange(samp, eventName.add));
}
});
},

/**
* Publishes the delete to redis subscriber
*
* @param {Sample} inst - The Sample instance which was just deleted
*/
afterDelete(inst /* , opts */) {
return common.sampleAspectAndSubjectArePublished(seq, inst)
.then((published) => {
if (published) {
// augument the sample instance with the subject instance to enable
// filtering by subjecttags in the realtime socketio module
common.augmentSampleWithSubjectAspectInfo(seq, inst)
.then(() => common.publishChange(inst, eventName.del));
}
});
}, // hooks.afterDelete

/**
* Update isDeleted.
* Publishes the deleted sample to redis channel.
Expand Down
35 changes: 26 additions & 9 deletions realtime/redisPublisher.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,32 +92,49 @@ function publishObject(inst, event, changedKeys, ignoreAttributes) {
* a absolutePath field added to it before the sample is published to the redis
* channel.
* @param {Object} sampleInst - The sample instance to be published
* @param {Model} model - The subject model used to get the related subject
* instance
* @param {Model} subjectModel - The subject model to get the related
* subject instance
* @param {String} event - Type of the event that is being published
* @param {Model} aspectModel - The aspect model to get the related
* aspect instance
* @returns {Promise} - which resolves to a sample object
*/
function publishSample(sampleInst, model, event) {
function publishSample(sampleInst, subjectModel, event, aspectModel) {
const eventType = event || getSampleEventType(sampleInst);
const sample = sampleInst.get ? sampleInst.get() : sampleInst;
const subName = sample.name.split('|')[0];
const options = {};
options.where = { absolutePath: subName };
return model.findOne(options)
const nameParts = sample.name.split('|');
const subName = nameParts[0];
const aspName = nameParts[1];
const subOpts = {
where: {
absolutePath: subName,
},
};
const aspOpts = {
where: {
name: aspName,
},
};
const getAspect = aspectModel ? aspectModel.findOne(aspOpts) :
Promise.resolve(sample.aspect);
return getAspect
.then((asp) => {
sample.aspect = asp.get ? asp.get() : asp;
return subjectModel.findOne(subOpts);
})
.then((sub) => {
if (sub) {

/*
*pass the sample instance to the publishObject function only if the
*aspect and subject are published
*/
if (sample.aspect && sample.aspect.isPublished && sub.isPublished) {

// attach subject to the sample
sample.subject = sub.get();

// attach absolutePath field to the sample
sample.absolutePath = subName;

publishObject(sample, eventType);
}
}
Expand Down
26 changes: 24 additions & 2 deletions tests/realtime/redisPublisher.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

/**
* tests/realtime/setupSocketIO.js
* tests/realtime/redisPublisher.js
*/
'use strict';

Expand Down Expand Up @@ -81,6 +81,29 @@ describe('redis Publisher', () => {
})
.catch(done);
});

it('when tried to publish sample without aspect,'+
' aspect should be attached', (done) => {
Sample.findById(sampId)
.then((sam) => {
const sampInst = sam.get();
delete sampInst.aspect;
return publisher.publishSample(sam, Subject, sampleEvent.upd, Aspect);
})
.then((pubObj) => {
expect(pubObj.aspect).to.not.equal(null);
expect(pubObj.aspect.name).to.equal(humidity.name);
expect(pubObj.aspect.tags.length).to.equal(0);
expect(pubObj.subject).to.not.equal(null);
expect(pubObj.subject.name).to.equal(subjectNA.name);
expect(pubObj.subject.tags.length).to.equal(0);
expect(pubObj.absolutePath).to.equal(subjectNA.name);
expect(pubObj.aspect.tags.length).to.equal(0);

done();
})
.catch(done);
});
});

describe('getSampleEventType function tests: ', () => {
Expand Down Expand Up @@ -115,5 +138,4 @@ describe('redis Publisher', () => {
.catch(done);
});
});

});

0 comments on commit 8033e59

Please sign in to comment.