Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit ac3f2f4

Browse files
committed
Initial commit.
Config vars were added to dev and prod for terms and resource-roles service. Will review and continue to test.
1 parent 902acc8 commit ac3f2f4

File tree

4 files changed

+162
-10
lines changed

4 files changed

+162
-10
lines changed

config/default.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ module.exports = {
4949
// Topcoder APIs
5050
V5_CHALLENGE_API_URL: process.env.V5_CHALLENGE_API_URL || 'http://localhost:4000/v5/challenges',
5151
V5_RESOURCES_API_URL: process.env.V5_RESOURCES_API_URL || 'http://localhost:4000/v5/resources',
52+
V5_TERMS_API_URL: process.env.V5_TERMS_API_URL || 'http://localhost:4000/v5/terms',
53+
V5_RESOURCE_ROLES_API_URL: process.env.V5_RESOURCE_ROLES_API_URL || 'http://localhost:4000/v5/resource-roles',
54+
5255
V5_CHALLENGE_TYPE_API_URL: process.env.V5_CHALLENGE_TYPE_API_URL || 'http://localhost:4000/v5/challenge-types',
5356
V4_CHALLENGE_TYPE_API_URL: process.env.V4_CHALLENGE_TYPE_API_URL || 'http://localhost:4000/v4/challenge-types',
5457
V4_CHALLENGE_API_URL: process.env.V4_CHALLENGE_API_URL || 'http://localhost:4000/v4/challenges',

src/app.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ const dataHandler = (messageSet, topic, partition) => Promise.each(messageSet, a
6363

6464
try {
6565
if (topic === config.CREATE_CHALLENGE_TOPIC) {
66-
await ProcessorService.processCreate(messageJSON)
66+
// create shut off. Only works with challenges of status draft, which happens on update
67+
// await ProcessorService.processCreate(messageJSON)
6768
} else {
6869
await ProcessorService.processUpdate(messageJSON)
6970
}

src/services/ProcessorService.js

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ const logger = require('../common/logger')
1111
const helper = require('../common/helper')
1212
const constants = require('../constants')
1313
const groupService = require('./groupsService')
14+
const termsService = require('./termsService')
1415
const copilotPaymentService = require('./copilotPaymentService')
15-
// TODO: Remove this
16-
// const showdown = require('showdown')
17-
// const converter = new showdown.Converter()
1816

1917
/**
2018
* Get group information by V5 UUID
@@ -26,18 +24,53 @@ async function getGroup (v5GroupId, m2mToken) {
2624
return response.body
2725
}
2826

27+
/**
28+
* Get terms information by V5 UUID
29+
* @param {String} v5TermsId the v5 terms UUID
30+
* @param {String} m2mToken token for accessing the API
31+
*/
32+
async function getV5Terms (v5TermsId, m2mToken) {
33+
const response = await helper.getRequest(`${config.V5_TERMS_API_URL}/${v5TermsId}`, m2mToken)
34+
return response.body
35+
}
36+
37+
/**
38+
* Get resource role information by V5 UUID
39+
* @param {String} v5RoleId the v5 role UUID
40+
* @param {String} m2mToken token for accessing the API
41+
*/
42+
async function getV5Role (v5RoleId, m2mToken) {
43+
const response = await helper.getRequest(`${config.V5_RESOURCE_ROLES_API_URL}?id=${v5RoleId}`, m2mToken)
44+
return response.body[0]
45+
}
46+
2947
/**
3048
* Associate challenge groups
3149
* @param {Array<String>} toBeAdded the array of groups to be added
3250
* @param {Array<String>} toBeDeleted the array of groups to be deleted
33-
* @param {String|Number} challengeId the legacy challenge ID
51+
* @param {String|Number} legacyChallengeId the legacy challenge ID
3452
*/
35-
async function associateChallengeGroups (toBeAdded = [], toBeDeleted = [], challengeId) {
53+
async function associateChallengeGroups (toBeAdded = [], toBeDeleted = [], legacyChallengeId) {
3654
for (const group of toBeAdded) {
37-
await groupService.addGroupToChallenge(challengeId, group)
55+
await groupService.addGroupToChallenge(legacyChallengeId, group)
3856
}
3957
for (const group of toBeDeleted) {
40-
await groupService.removeGroupFromChallenge(challengeId, group)
58+
await groupService.removeGroupFromChallenge(legacyChallengeId, group)
59+
}
60+
}
61+
62+
/**
63+
* Associate challenge terms
64+
* @param {Array<Object{termsId, roleId}>} toBeAdded the array of terms to be added
65+
* @param {Array<Object{termsId, roleId}>} toBeDeleted the array of terms to be deleted
66+
* @param {String|Number} legacyChallengeId the legacy challenge ID
67+
*/
68+
async function associateChallengeTerms (toBeAdded = [], toBeDeleted = [], legacyChallengeId) {
69+
for (const terms of toBeAdded) {
70+
await termsService.addTermsToChallenge(legacyChallengeId, terms.termsId, terms.roleId)
71+
}
72+
for (const terms of toBeDeleted) {
73+
await termsService.removeTermsFromChallenge(legacyChallengeId, terms.termsId, terms.roleId)
4174
}
4275
}
4376

@@ -140,9 +173,10 @@ async function getLegacyTrackInformation (trackId, typeId, tags, m2mToken) {
140173
* @param {String} m2mToken the m2m token
141174
* @param {Boolean} isCreated flag indicate the DTO is used in creating challenge
142175
* @param {Array} informixGroupIds IDs from Informix associated with the group
176+
* @param {Array<Object>} informixTermsIds IDs from Informix [{termsId, roleId}]
143177
* @returns the DTO for saving a draft contest.(refer SaveDraftContestDTO in ap-challenge-microservice)
144178
*/
145-
async function parsePayload (payload, m2mToken, isCreated = true, informixGroupIds) {
179+
async function parsePayload (payload, m2mToken, isCreated = true, informixGroupIds, informixTermsArray) {
146180
try {
147181
let projectId
148182
if (_.get(payload, 'legacy.directProjectId')) {
@@ -259,6 +293,36 @@ async function parsePayload (payload, m2mToken, isCreated = true, informixGroupI
259293
} else if (informixGroupIds && informixGroupIds.length > 0) {
260294
data.groupsToBeDeleted = _.map(informixGroupIds, g => _.toString(g))
261295
}
296+
297+
if (payload.terms && _.get(payload, 'terms.length', 0) > 0) {
298+
const oldTerms = informixGroupIds
299+
const newTerms = []
300+
301+
for (const v5TermsObject of payload.terms) {
302+
try {
303+
const termsInfo = await getV5Terms(v5TermsObject.id, m2mToken)
304+
if (!_.isEmpty(_.get(termsInfo, 'legacyId'))) {
305+
const roleInfo = await getV5Role(v5TermsObject.roleId, m2mToken)
306+
if (!_.isEmpty(_.get(roleInfo, 'legacyId'))) {
307+
newTerms.push({ id: _.get(termsInfo, 'legacyId'), roleId: _.get(roleInfo, 'legacyId') })
308+
}
309+
}
310+
} catch (e) {
311+
logger.warn(`Failed to load details for terms ${v5TermsObject}`)
312+
}
313+
}
314+
data.termsToBeAdded = _.difference(newTerms, oldTerms)
315+
data.termsToBeDeleted = _.difference(oldTerms, newTerms)
316+
if (data.termsToBeAdded.length > 0) {
317+
logger.debug(`parsePayload :: Adding Terms ${JSON.stringify(data.termsToBeAdded)}`)
318+
}
319+
if (data.termsToBeDeleted.length > 0) {
320+
logger.debug(`parsePayload :: Deleting Terms ${JSON.stringify(data.termsToBeDeleted)}`)
321+
}
322+
} else if (informixTermsArray && informixTermsArray.length > 0) {
323+
data.termsToBeDeleted = _.map(informixTermsArray, o => ({ id: o.id, roleId: o.roleId }))
324+
}
325+
262326
return data
263327
} catch (err) {
264328
// Debugging
@@ -312,6 +376,7 @@ async function processCreate (message) {
312376
const newChallenge = await helper.postRequest(`${config.V4_CHALLENGE_API_URL}`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
313377
await helper.forceV4ESFeeder(newChallenge.body.result.content.id)
314378
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, newChallenge.body.result.content.id)
379+
await associateChallengeTerms(saveDraftContestDTO.termsToBeAdded, saveDraftContestDTO.termsToBeRemoved, newChallenge.body.result.content.id)
315380
await setCopilotPayment(newChallenge.body.result.content.id, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'))
316381
await helper.patchRequest(`${config.V5_CHALLENGE_API_URL}/${challengeUuid}`, {
317382
legacy: {
@@ -427,12 +492,14 @@ async function processUpdate (message) {
427492

428493
const v4GroupIds = await groupService.getGroupsForChallenge(message.payload.legacyId)
429494
logger.info(`GroupIDs Found in Informix: ${JSON.stringify(v4GroupIds)}`)
495+
const v4TermsIds = await termsService.getTermsForChallenge(message.payload.legacyId)
430496

431-
const saveDraftContestDTO = await parsePayload(message.payload, m2mToken, false, v4GroupIds)
497+
const saveDraftContestDTO = await parsePayload(message.payload, m2mToken, false, v4GroupIds, v4TermsIds)
432498
// logger.debug('Parsed Payload', saveDraftContestDTO)
433499
try {
434500
await helper.putRequest(`${config.V4_CHALLENGE_API_URL}/${message.payload.legacyId}`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
435501
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, message.payload.legacyId)
502+
await associateChallengeTerms(saveDraftContestDTO.termsToBeAdded, saveDraftContestDTO.termsToBeRemoved, message.payload.legacyId)
436503
await setCopilotPayment(message.payload.legacyId, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'))
437504

438505
if (message.payload.status) {

src/services/termsService.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
const logger = require('../common/logger')
2+
const _ = require('lodash')
3+
const util = require('util')
4+
const helper = require('../common/helper')
5+
6+
const QUERY_GET_CHALLENGE_TERMS = 'SELECT resource_role_id as roleId, terms_of_use_id as id FROM project_role_terms_of_use_xref WHERE project_id = %d'
7+
const QUERY_INSERT_CHALLENGE_TERMS = `INSERT INTO project_role_terms_of_use_xref
8+
(project_id, resource_role_id, terms_of_use_id, create_date, modify_date, sort_order, group_ind)
9+
VALUES (?, ?, ?, CURRENT, CURRENT, 1, 0)`
10+
const QUERY_DELETE_CHALLENGE_TERMS = 'DELETE FROM project_role_terms_of_use_xref WHERE project_id = ? AND resource_role_id = ? AND terms_of_use_id = ?'
11+
12+
/**
13+
* Prepare Informix statement
14+
* @param {Object} connection the Informix connection
15+
* @param {String} sql the sql
16+
* @return {Object} Informix statement
17+
*/
18+
async function prepare (connection, sql) {
19+
// logger.debug(`Preparing SQL ${sql}`)
20+
const stmt = await connection.prepareAsync(sql)
21+
return Promise.promisifyAll(stmt)
22+
}
23+
24+
async function getTermsForChallenge (challengeLegacyId) {
25+
// logger.debug(`Getting Groups for Challenge ${challengeLegacyId}`)
26+
const connection = await helper.getInformixConnection()
27+
let result = null
28+
try {
29+
result = await connection.queryAsync(util.format(QUERY_GET_CHALLENGE_TERMS, challengeLegacyId))
30+
} catch (e) {
31+
logger.error(`Error in 'getTermsForChallenge' ${e}`)
32+
throw e
33+
} finally {
34+
await connection.closeAsync()
35+
}
36+
return _.map(result, r => ({ termsId: r.terms_of_use_id, roleId: r.resource_role_id }))
37+
}
38+
39+
async function addTermsToChallenge (challengeLegacyId, legacyTermsId, legacyResourceRoleId) {
40+
const connection = await helper.getInformixConnection()
41+
let result = null
42+
try {
43+
// await connection.beginTransactionAsync()
44+
const query = await prepare(connection, QUERY_INSERT_CHALLENGE_TERMS)
45+
result = await query.executeAsync([challengeLegacyId, legacyResourceRoleId, legacyTermsId])
46+
// await connection.commitTransactionAsync()
47+
} catch (e) {
48+
logger.error(`Error in 'addTermsToChallenge' ${e}, rolling back transaction`)
49+
await connection.rollbackTransactionAsync()
50+
throw e
51+
} finally {
52+
logger.info(`Terms ${legacyTermsId} added to challenge ${challengeLegacyId}`)
53+
await connection.closeAsync()
54+
}
55+
return result
56+
}
57+
58+
async function removeTermsFromChallenge (challengeLegacyId, legacyTermsId, legacyResourceRoleId) {
59+
const connection = await helper.getInformixConnection()
60+
let result = null
61+
try {
62+
// await connection.beginTransactionAsync()
63+
const query = await prepare(connection, QUERY_DELETE_CHALLENGE_TERMS)
64+
result = await query.executeAsync([challengeLegacyId, legacyResourceRoleId, legacyTermsId])
65+
// await connection.commitTransactionAsync()
66+
} catch (e) {
67+
logger.error(`Error in 'removeTermsFromChallenge' ${e}, rolling back transaction`)
68+
await connection.rollbackTransactionAsync()
69+
throw e
70+
} finally {
71+
logger.info(`Terms ${legacyTermsId} removed from challenge ${challengeLegacyId}`)
72+
await connection.closeAsync()
73+
}
74+
return result
75+
}
76+
77+
module.exports = {
78+
getTermsForChallenge,
79+
addTermsToChallenge,
80+
removeTermsFromChallenge
81+
}

0 commit comments

Comments
 (0)