Skip to content

Feature/general purpose notifications usage #108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ module.exports = {

KAFKA_CONSUMER_RULESETS: {
// key is Kafka topic name, value is array of ruleset which have key as handler function name defined in src/processors/index.js
'challenge.notification.events' : [{handleChallenge : {type:'UPDATE_DRAFT_CHALLENGE', roles: ["Submitter" /** Competitor */, "Copilot", "Reviewer"]}}],
'challenge.notification.events': [{ handleChallenge: { type: 'UPDATE_DRAFT_CHALLENGE', roles: ["Submitter" /** Competitor */, "Copilot", "Reviewer"] } }],
'notifications.autopilot.events': [{ handleAutoPilot: { phaseTypeName: 'Checkpoint Screening', state: 'START', roles: ["Copilot", "Reviewer"] } }],
'submission.notification.create': [{ handleSubmission: { resource: 'submission', roles: ["Copilot", "Reviewer"], selfOnly: true /** Submitter only */ } }],
//'notifications.community.challenge.created': ['handleChallengeCreated'],
//'notifications.community.challenge.phasewarning': ['handleChallengePhaseWarning'],
},
Expand Down
27 changes: 16 additions & 11 deletions src/common/tcApiHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,25 +260,30 @@ function* getUsersInfoFromChallenge(challengeId) {

/**
* Filter associated challenge's user based on criteria
* @param {Array} usersInfo user object array
* @param {Array} filterCriteria on roles
* @param {Array} usersInfo user object array
* @param {Array} filterOnRoles on roles
* @param {Array} filterOnUsers on user's ids
*
* @returns {Array} of user object
*/
function filterChallengeUsers(usersInfo, filterCriteria = []) {
let users = []
let totaleRoles = []
function filterChallengeUsers(usersInfo, filterOnRoles = [], filterOnUsers = []) {
const users = [] // filtered users
const rolesAvailable = [] // available roles in challenge api response
_.map(usersInfo, (user) => {
let userId = _.get(user, 'properties.External Reference ID')
let role = _.get(user, 'role')
totaleRoles[role] = 1
if (filterCriteria.length > 0 && _.indexOf(filterCriteria, role) >= 0) {
const userId = parseInt(_.get(user, 'properties.External Reference ID'))
const role = _.get(user, 'role')

_.indexOf(rolesAvailable, role) == -1 ? rolesAvailable.push(role) : ''

if (filterOnRoles.length > 0 && _.indexOf(filterOnRoles, role) >= 0) {
users.push({ userId: userId })
} else if (filterCriteria.length == 0) {
} else if (filterOnUsers.length > 0 && _.indexOf(filterOnUsers, userId) >= 0) {
users.push({ userId: userId }) /** Submitter only case */
} else if (filterOnRoles.length == 0 && filterOnUsers.length == 0) {
users.push({ userId: userId })
}
})
logger.info(`Total roles availables in this challenge are: ${_.keys(totaleRoles).join(',')}`)
logger.info(`Total roles available in this challenge are: ${rolesAvailable.join(',')}`)
return users
}

Expand Down
21 changes: 21 additions & 0 deletions src/processors/challenge/AutoPilotHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Challenge Autopilot general handler.
*/
const co = require('co');
const service = require('../../services/AutoPilotService');

/**
* Handle Kafka JSON message of autopilot.
*
* @param {Object} message the Kafka JSON message
* @param {Object} ruleSets
*
* @return {Promise} promise resolved to notifications
*/
const handle = (message, ruleSets) => co(function* () {
return yield service.handle(message, ruleSets);
});

module.exports = {
handle,
};
21 changes: 21 additions & 0 deletions src/processors/challenge/SubmissionHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Challenge submission general handler.
*/
const co = require('co');
const service = require('../../services/SubmissionService');

/**
* Handle Kafka JSON message of autopilot.
*
* @param {Object} message the Kafka JSON message
* @param {Object} ruleSets
*
* @return {Promise} promise resolved to notifications
*/
const handle = (message, ruleSets) => co(function* () {
return yield service.handle(message, ruleSets);
});

module.exports = {
handle,
};
4 changes: 4 additions & 0 deletions src/processors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
const ChallengeCreatedHandler = require('./challenge/ChallengeCreatedHandler');
const ChallengePhaseWarningHandler = require('./challenge/ChallengePhaseWarningHandler');
const ChallengeHandler = require('./challenge/ChallengeHandler');
const AutoPilotHandler = require('./challenge/AutoPilotHandler')
const SubmissionHandler = require('./challenge/SubmissionHandler')

// Exports
module.exports = {
handleChallengeCreated: ChallengeCreatedHandler.handle,
handleChallengePhaseWarning: ChallengePhaseWarningHandler.handle,
handleChallenge: ChallengeHandler.handle,
handleAutoPilot: AutoPilotHandler.handle,
handleSubmission: SubmissionHandler.handle,
};
53 changes: 53 additions & 0 deletions src/services/AutoPilotService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Autopilot general handler service.
*/

'use strict';

const joi = require('joi');
const _ = require('lodash')
const logger = require('../common/logger');
const tcApiHelper = require('../common/tcApiHelper');

/**
* Handle autopilot message
* @param {Object} message the Kafka message
* @param {Object} ruleSets
* @returns {Array} the notifications
*/
function* handle(message, ruleSets) {

if ((message.payload.phaseTypeName === _.get(ruleSets, "phaseTypeName"))
&& (message.payload.state === _.get(ruleSets, "state"))) {
const challengeId = message.payload.projectId
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
const filerOnRoles = _.get(ruleSets, "roles")
const users = tcApiHelper.filterChallengeUsers(usersInfo, filerOnRoles)
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filerOnRoles)} `)
// notify users of message
return yield tcApiHelper.notifyUsersOfMessage(users, message);
}
return {}
}

handle.schema = {
message: joi.object().keys({
topic: joi.string().required(),
originator: joi.string().required(),
timestamp: joi.date().required(),
'mime-type': joi.string().required(),
payload: joi.object().keys({
phaseTypeName: joi.string().required(),
state: joi.string().required(),
projectId: joi.number().integer().min(1)
}).unknown(true).required(),
}).required(),
ruleSets: joi.object()
}

// Exports
module.exports = {
handle,
}

logger.buildService(module.exports);
6 changes: 3 additions & 3 deletions src/services/ChallengeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ function* handle(message, ruleSets) {
if (message.payload.type === _.get(ruleSets, "type")) {
const challengeId = message.payload.data.id
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
const filerOnRoles = _.get(ruleSets, "roles")
const users = tcApiHelper.filterChallengeUsers(usersInfo, filerOnRoles)
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filerOnRoles)} `)
const filterOnRoles = _.get(ruleSets, "roles")
const users = tcApiHelper.filterChallengeUsers(usersInfo, filterOnRoles)
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filterOnRoles)} `)
// notify users of message
return yield tcApiHelper.notifyUsersOfMessage(users, message);
}
Expand Down
56 changes: 56 additions & 0 deletions src/services/SubmissionService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Submission general handler service.
*/

'use strict';

const joi = require('joi');
const _ = require('lodash')
const logger = require('../common/logger');
const tcApiHelper = require('../common/tcApiHelper');

/**
* Handle submission message
* @param {Object} message the Kafka message
* @param {Object} ruleSets
* @returns {Array} the notifications
*/
function* handle(message, ruleSets) {

if (message.payload.resource === _.get(ruleSets, "resource")) {
const challengeId = message.payload.challengeId
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)

const filterOnUsers = []
if (_.get(ruleSets, 'selfOnly')) {
const memberId = _.get(message.payload, "memberId")
filterOnUsers.push(memberId)
}
const filterOnRoles = _.get(ruleSets, "roles")
const users = tcApiHelper.filterChallengeUsers(usersInfo, filterOnRoles, filterOnUsers)
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filterOnRoles)} `)
// notify users of message
return yield tcApiHelper.notifyUsersOfMessage(users, message);
}
return {}
}

handle.schema = {
message: joi.object().keys({
topic: joi.string().required(),
originator: joi.string().required(),
timestamp: joi.date().required(),
'mime-type': joi.string().required(),
payload: joi.object().keys({
resource: joi.string().required()
}).unknown(true).required(),
}).required(),
ruleSets: joi.object()
}

// Exports
module.exports = {
handle,
}

logger.buildService(module.exports);