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

Commit 7c75639

Browse files
author
James Cori
committed
Merge branch 'develop'
2 parents 5c008a4 + ce865d5 commit 7c75639

File tree

5 files changed

+227
-12
lines changed

5 files changed

+227
-12
lines changed

config/default.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ module.exports = {
7878

7979
COPILOT_PAYMENT_TYPE: process.env.COPILOT_PAYMENT_TYPE || 'copilot',
8080

81+
COPILOT_ROLE_ID: process.env.COPILOT_ROLE_ID || 'cfe12b3f-2a24-4639-9d8b-ec86726f76bd',
82+
8183
// V5 Term UUID
8284
SYNC_V5_TERM_UUID: process.env.SYNC_V5_TERM_UUID || '317cd8f9-d66c-4f2a-8774-63c612d99cd4',
8385
SYNC_V5_WRITE_ENABLED: process.env.SYNC_V5_WRITE_ENABLED === 'true' || false

src/constants.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,20 @@ const challengeStatuses = {
4545
CancelledZeroRegistrations: 'Cancelled - Zero Registrations'
4646
}
4747

48+
const supportedMetadata = {
49+
allowStockArt: 52,
50+
drPoints: 30,
51+
submissionViewable: 53,
52+
submissionLimit: 51,
53+
codeRepo: 85,
54+
environment: 84
55+
}
56+
4857
module.exports = {
4958
prizeSetTypes,
5059
EVENT_ORIGINATOR,
5160
EVENT_MIME_TYPE,
5261
createChallengeStatusesMap,
53-
challengeStatuses
62+
challengeStatuses,
63+
supportedMetadata
5464
}

src/services/ProcessorService.js

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const groupService = require('./groupsService')
1414
const termsService = require('./termsService')
1515
const copilotPaymentService = require('./copilotPaymentService')
1616
const timelineService = require('./timelineService')
17+
const metadataService = require('./metadataService')
1718

1819
/**
1920
* Get group information by V5 UUID
@@ -107,16 +108,27 @@ async function associateChallengeTerms (v5Terms, legacyChallengeId, createdBy, u
107108

108109
/**
109110
* Set the copilot payment on legacy
111+
* @param {String} challengeId the V5 challenge ID
110112
* @param {Number|String} legacyChallengeId the legacy challenge ID
111113
* @param {Array} prizeSets the prizeSets array
112114
* @param {String} createdBy the created by handle
113115
* @param {String} updatedBy the updated by handle
116+
* @param {String} m2mToken the m2m token
114117
*/
115-
async function setCopilotPayment (legacyChallengeId, prizeSets = [], createdBy, updatedBy) {
118+
async function setCopilotPayment (challengeId, legacyChallengeId, prizeSets = [], createdBy, updatedBy, m2mToken) {
116119
try {
117120
const copilotPayment = _.get(_.find(prizeSets, p => p.type === config.COPILOT_PAYMENT_TYPE), 'prizes[0].value', null)
118-
logger.debug(`Setting Copilot Payment: ${copilotPayment} for legacyId ${legacyChallengeId}`)
119-
await copilotPaymentService.setCopilotPayment(legacyChallengeId, copilotPayment, createdBy, updatedBy)
121+
if (copilotPayment) {
122+
logger.debug('Fetching challenge copilot...')
123+
const res = await helper.getRequest(`${config.V5_RESOURCES_API_URL}?challengeId=${challengeId}&roleId=${config.COPILOT_ROLE_ID}`, m2mToken)
124+
const [copilotResource] = res.body
125+
if (!copilotResource) {
126+
logger.warn(`Copilot does not exist for challenge ${challengeId} (legacy: ${legacyChallengeId})`)
127+
return
128+
}
129+
logger.debug(`Setting Copilot Payment: ${copilotPayment} for legacyId ${legacyChallengeId} for copilot ${copilotResource.memberId}`)
130+
await copilotPaymentService.setCopilotPayment(legacyChallengeId, copilotPayment, createdBy, updatedBy)
131+
}
120132
} catch (e) {
121133
logger.error('Failed to set the copilot payment!')
122134
logger.debug(e)
@@ -325,6 +337,21 @@ async function parsePayload (payload, m2mToken, isCreated = true, informixGroupI
325337
data.groupsToBeDeleted = _.map(informixGroupIds, g => _.toString(g))
326338
}
327339

340+
if (payload.metadata && payload.metadata.length > 0) {
341+
const fileTypes = _.find(payload.metadata, meta => meta.name === 'fileTypes')
342+
if (fileTypes) {
343+
if (_.isArray(fileTypes.value)) {
344+
data.fileTypes = fileTypes.value
345+
} else {
346+
try {
347+
data.fileTypes = JSON.parse(fileTypes.value)
348+
} catch (e) {
349+
data.fileTypes = []
350+
}
351+
}
352+
}
353+
}
354+
328355
return data
329356
} catch (err) {
330357
// Debugging
@@ -385,7 +412,7 @@ async function processCreate (message) {
385412
await helper.forceV4ESFeeder(newChallenge.body.result.content.id)
386413
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, newChallenge.body.result.content.id)
387414
// await associateChallengeTerms(saveDraftContestDTO.termsToBeAdded, saveDraftContestDTO.termsToBeRemoved, newChallenge.body.result.content.id)
388-
await setCopilotPayment(newChallenge.body.result.content.id, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'))
415+
await setCopilotPayment(challengeUuid, newChallenge.body.result.content.id, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'), m2mToken)
389416
await helper.patchRequest(`${config.V5_CHALLENGE_API_URL}/${challengeUuid}`, {
390417
legacy: {
391418
...message.payload.legacy,
@@ -466,7 +493,7 @@ async function processUpdate (message) {
466493
return
467494
} else if (!message.payload.legacyId) {
468495
logger.debug('Legacy ID does not exist. Will create...')
469-
return processCreate(message)
496+
await processCreate(message)
470497
}
471498
const m2mToken = await helper.getM2MToken()
472499

@@ -506,12 +533,45 @@ async function processUpdate (message) {
506533
const saveDraftContestDTO = await parsePayload(message.payload, m2mToken, false, v4GroupIds)
507534
// logger.debug('Parsed Payload', saveDraftContestDTO)
508535
try {
509-
await helper.putRequest(`${config.V4_CHALLENGE_API_URL}/${message.payload.legacyId}`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
536+
try {
537+
if (challenge) {
538+
await helper.putRequest(`${config.V4_CHALLENGE_API_URL}/${message.payload.legacyId}`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
539+
}
540+
} catch (e) {
541+
logger.warn('Failed to update the challenge via the V4 API')
542+
logger.error(e)
543+
}
510544
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, message.payload.legacyId)
511-
await associateChallengeTerms(message.payload.terms, message.payload.legacyId, _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'))
512-
await setCopilotPayment(message.payload.legacyId, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'))
513-
514-
if (message.payload.status) {
545+
await associateChallengeTerms(message.payload.terms, message.payload.legacyId, _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
546+
await setCopilotPayment(message.payload.id, message.payload.legacyId, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'), m2mToken)
547+
548+
// Update metadata in IFX
549+
if (message.payload.metadata && message.payload.metadata.length > 0) {
550+
for (const metadataKey of _.keys(constants.supportedMetadata)) {
551+
const entry = _.find(message.payload.metadata, meta => meta.name === metadataKey)
552+
if (entry) {
553+
if (metadataKey === 'submissionLimit') {
554+
// data here is JSON stringified
555+
try {
556+
const parsedEntryValue = JSON.parse(entry.value)
557+
if (parsedEntryValue.limit) {
558+
entry.value = parsedEntryValue.count
559+
} else {
560+
entry.value = null
561+
}
562+
} catch (e) {
563+
entry.value = null
564+
}
565+
}
566+
try {
567+
await metadataService.createOrUpdateMetadata(message.payload.legacyId, constants.supportedMetadata[metadataKey], entry.value, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
568+
} catch (e) {
569+
logger.warn(`Failed to set ${metadataKey} (${constants.supportedMetadata[metadataKey]})`)
570+
}
571+
}
572+
}
573+
}
574+
if (message.payload.status && challenge) {
515575
// logger.info(`The status has changed from ${challenge.currentStatus} to ${message.payload.status}`)
516576
if (message.payload.status === constants.challengeStatuses.Active && challenge.currentStatus !== constants.challengeStatuses.Active) {
517577
logger.info('Activating challenge...')
@@ -532,7 +592,11 @@ async function processUpdate (message) {
532592
}
533593
}
534594
}
535-
await helper.forceV4ESFeeder(message.payload.legacyId)
595+
try {
596+
await helper.forceV4ESFeeder(message.payload.legacyId)
597+
} catch (e) {
598+
logger.warn('Failed to call V4 ES Feeder')
599+
}
536600
} catch (e) {
537601
logger.error('processUpdate Catch', e)
538602
throw e

src/services/copilotPaymentService.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const helper = require('../common/helper')
55

66
const COPILOT_PAYMENT_PROJECT_INFO_ID = 49
77
const COPILOT_PAYMENT_RESOURCE_INFO_ID = 7
8+
const COPILOT_PAYMENT_TYPE_ID = 15
89
const COPILOT_RESOURCE_ROLE_ID = 14
910

1011
const QUERY_GET_COPILOT_RESOURCE_FOR_CHALLENGE = `SELECT limit 1 resource_id as resourceid FROM resource WHERE project_id = %d AND resource_role_id = ${COPILOT_RESOURCE_ROLE_ID}`
@@ -32,6 +33,10 @@ const QUERY_DELETE_COPILOT_PAYMENT = `DELETE FROM project_info WHERE project_inf
3233
const QUERY_UPDATE_COPILOT_RESOURCE_PAYMENT = `UPDATE resource_info SET value = ?, modify_user = ?, modify_date = CURRENT WHERE resource_id = ? AND resource_info_type_id = ${COPILOT_PAYMENT_RESOURCE_INFO_ID}`
3334
// const QUERY_DELETE_COPILOT_RESOURCE_PAYMENT = `DELETE FROM resource_info WHERE resource_id = ? AND resource_info_type_id = ${COPILOT_PAYMENT_RESOURCE_INFO_ID}`
3435

36+
const QUERY_SELECT_PAYMENT_TYPE = `SELECT value FROM resource_info WHERE resource_info_type_id = ${COPILOT_PAYMENT_TYPE_ID} AND resource_id = %d`
37+
const QUERY_INSERT_PAYMENT_TYPE = `INSERT INTO resource_info (resource_id, resource_info_type_id, value, create_user, create_date, modify_user, modify_date) VALUES (?, "${COPILOT_PAYMENT_TYPE_ID}", ?, ?, CURRENT, ?, CURRENT)`
38+
const QUERY_UPDATE_PAYMENT_TYPE = `UPDATE resource_info SET value = ?, modify_user = ?, modify_date = CURRENT WHERE resource_id = ? AND resource_info_type_id = ${COPILOT_PAYMENT_TYPE_ID}`
39+
3540
/**
3641
* Prepare Informix statement
3742
* @param {Object} connection the Informix connection
@@ -58,6 +63,14 @@ async function setCopilotPayment (challengeLegacyId, amount, createdBy, updatedB
5863
const copilotResourceId = await getCopilotResourceId(connection, challengeLegacyId)
5964
const copilotPayment = await getCopilotPayment(connection, challengeLegacyId)
6065
if (amount != null && amount >= 0) {
66+
// Make sure the payment type is set to manual
67+
// TODO: Figure out why data is not saved in IFX even when there are no errors
68+
// const paymentType = await getCopilotPaymentType(connection, copilotResourceId)
69+
// if (!paymentType) {
70+
// await createCopilotPaymentType(connection, copilotResourceId, 'TRUE', updatedBy || createdBy)
71+
// } else if (_.toLower(_.toString(paymentType.value)) !== 'true') {
72+
// await updateCopilotPaymentType(connection, copilotResourceId, 'TRUE', updatedBy || createdBy)
73+
// }
6174
if (copilotPayment) {
6275
logger.debug(`Copilot payment exists, updating: ${challengeLegacyId}`)
6376
return updateCopilotPayment(connection, copilotResourceId, challengeLegacyId, amount, updatedBy)
@@ -78,6 +91,43 @@ async function setCopilotPayment (challengeLegacyId, amount, createdBy, updatedB
7891
}
7992
}
8093

94+
/**
95+
* Gets the copilot payment type for a legacyId
96+
* @param {Object} connection the connection
97+
* @param {Number} resourceId the resource ID
98+
*/
99+
async function getCopilotPaymentType (connection, resourceId) {
100+
const result = await connection.queryAsync(util.format(QUERY_SELECT_PAYMENT_TYPE, resourceId))
101+
logger.debug(`Result: ${JSON.stringify(result, null, 2)}`)
102+
return _.get(result, '[0]', null)
103+
}
104+
105+
/**
106+
* Create the copilot payment type record
107+
* @param {Object} connection the connection
108+
* @param {Number} resourceId the resource ID
109+
* @param {Boolean} value the value
110+
* @param {String} createdBy the create user handle
111+
*/
112+
async function createCopilotPaymentType (connection, resourceId, value, createdBy) {
113+
const query = await prepare(connection, QUERY_INSERT_PAYMENT_TYPE)
114+
logger.debug(`Create Copilot Payment Type Values: ${[resourceId, value, createdBy, createdBy]}`)
115+
await query.executeAsync([resourceId, value, createdBy, createdBy])
116+
}
117+
118+
/**
119+
* Update the copilot payment type record
120+
* @param {Object} connection the connection
121+
* @param {Number} resourceId the resource ID
122+
* @param {Boolean} value the value
123+
* @param {String} createdBy the create user handle
124+
*/
125+
async function updateCopilotPaymentType (connection, resourceId, value, createdBy) {
126+
const query = await prepare(connection, QUERY_UPDATE_PAYMENT_TYPE)
127+
logger.debug(`Update Copilot Payment Type Values: ${[value, createdBy, resourceId]}`)
128+
await query.executeAsync([value, createdBy, resourceId])
129+
}
130+
81131
/**
82132
* Gets the copilot payment for a legacyId
83133
* @param {Object} connection

src/services/metadataService.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* Metadata Service
3+
* Interacts with InformixDB
4+
*/
5+
const util = require('util')
6+
const logger = require('../common/logger')
7+
const helper = require('../common/helper')
8+
9+
const QUERY_GET_ENTRY = 'SELECT value FROM project_info WHERE project_id = %d and project_info_type_id = %d'
10+
const QUERY_CREATE = 'INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) VALUES (?, ?, ?, ?, CURRENT, ?, CURRENT)'
11+
const QUERY_UPDATE = 'UPDATE project_info SET value = ?, modify_user = ?, modify_date = CURRENT WHERE project_info_type_id = ? AND project_id = ?'
12+
const QUERY_DELETE = 'DELETE FROM project_info WHERE project_id = ? and project_info_type_id = ?'
13+
14+
/**
15+
* Prepare Informix statement
16+
* @param {Object} connection the Informix connection
17+
* @param {String} sql the sql
18+
* @return {Object} Informix statement
19+
*/
20+
async function prepare (connection, sql) {
21+
// logger.debug(`Preparing SQL ${sql}`)
22+
const stmt = await connection.prepareAsync(sql)
23+
return Promise.promisifyAll(stmt)
24+
}
25+
26+
/**
27+
* Get project info entry entry
28+
* @param {Number} challengeLegacyId the legacy challenge ID
29+
* @param {Number} typeId the type ID
30+
*/
31+
async function getMetadataEntry (challengeLegacyId, typeId) {
32+
// logger.debug(`Getting Groups for Challenge ${challengeLegacyId}`)
33+
const connection = await helper.getInformixConnection()
34+
let result = null
35+
try {
36+
result = await connection.queryAsync(util.format(QUERY_GET_ENTRY, challengeLegacyId, typeId))
37+
} catch (e) {
38+
logger.error(`Error in 'getMetadataEntry' ${e}`)
39+
throw e
40+
} finally {
41+
await connection.closeAsync()
42+
}
43+
return result
44+
}
45+
46+
/**
47+
* Enable timeline notifications
48+
* @param {Number} challengeLegacyId the legacy challenge ID
49+
* @param {Number} typeId the type ID
50+
* @param {Any} value the value
51+
* @param {String} createdBy the created by
52+
*/
53+
async function createOrUpdateMetadata (challengeLegacyId, typeId, value, createdBy) {
54+
const connection = await helper.getInformixConnection()
55+
let result = null
56+
try {
57+
// await connection.beginTransactionAsync()
58+
const [existing] = await getMetadataEntry(challengeLegacyId, typeId)
59+
if (existing) {
60+
if (value) {
61+
logger.info(`Metadata ${typeId} exists. Will update`)
62+
const query = await prepare(connection, QUERY_UPDATE)
63+
result = await query.executeAsync([value, createdBy, typeId, challengeLegacyId])
64+
} else {
65+
logger.info(`Metadata ${typeId} exists. Will delete`)
66+
const query = await prepare(connection, QUERY_DELETE)
67+
result = await query.executeAsync([challengeLegacyId, typeId])
68+
}
69+
} else {
70+
logger.info(`Metadata ${typeId} does not exist. Will create`)
71+
const query = await prepare(connection, QUERY_CREATE)
72+
result = await query.executeAsync([challengeLegacyId, typeId, value, createdBy, createdBy])
73+
}
74+
// await connection.commitTransactionAsync()
75+
logger.info(`Metadata with typeId ${typeId} has been enabled for challenge ${challengeLegacyId}`)
76+
} catch (e) {
77+
logger.error(`Error in 'createOrUpdateMetadata' ${e}, rolling back transaction`)
78+
await connection.rollbackTransactionAsync()
79+
throw e
80+
} finally {
81+
await connection.closeAsync()
82+
}
83+
return result
84+
}
85+
86+
module.exports = {
87+
getMetadataEntry,
88+
createOrUpdateMetadata
89+
}

0 commit comments

Comments
 (0)