Skip to content

Commit 984962b

Browse files
author
sachin-maheshwari
authored
Merge pull request #208 from topcoder-platform/feature/shapeup-pure-v5-task
migrate v4 challenge endpoints to v5 challenge endpoints
2 parents 31a8527 + 7aa8f3d commit 984962b

File tree

14 files changed

+572
-186
lines changed

14 files changed

+572
-186
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ To migrate the existing data from DynamoDB to ES, run the following script
171171
npm run db-to-es
172172
```
173173

174+
#### Store v5 challenge id for current records
175+
176+
Submission API started off using the legacy challenge ids. With the v5 upgrade to the challenge api, we now need to make use of the v5 challenge ids. We have thus created a script to update existing `challengeId` attribute on submissions to v5 and store the older challenge ids in the `legacyChallengeId` attribute.
177+
178+
To update the existing challengeId data on submissions in DynamoDB to v5 challengeId, set the following env variables:
179+
180+
```bash
181+
SUBMISSION_TABLE_NAME // Table name of the submission records. Defaults to 'Submission'
182+
UPDATE_V5_CHALLENGE_BATCH_SIZE // Number of records that are updated simultaneously. Defaults to 250
183+
```
184+
185+
186+
and then run the following script
187+
188+
```
189+
npm run update-to-v5-challengeId
190+
```
191+
174192
#### Swagger UI
175193

176194
Swagger UI will be served at `http://localhost:3000/docs`

config/default.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ module.exports = {
2121
BUSAPI_URL: process.env.BUSAPI_URL || 'https://api.topcoder-dev.com/v5',
2222
KAFKA_ERROR_TOPIC: process.env.KAFKA_ERROR_TOPIC || 'error.notification',
2323
KAFKA_AGGREGATE_TOPIC: process.env.KAFKA_AGGREGATE_TOPIC || 'submission.notification.aggregate',
24-
CHALLENGEAPI_URL: process.env.CHALLENGEAPI_URL || 'https://api.topcoder-dev.com/v4/challenges',
2524
CHALLENGEAPI_V5_URL: process.env.CHALLENGEAPI_V5_URL || 'https://api.topcoder-dev.com/v5/challenges',
25+
RESOURCEAPI_V5_BASE_URL: process.env.RESOURCEAPI_V5_BASE_URL || 'https://api.topcoder-dev.com/v5',
2626
AUTH0_URL: process.env.AUTH0_URL, // Auth0 credentials for Submission Service
2727
AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE || 'https://www.topcoder.com',
2828
TOKEN_CACHE_TIME: process.env.TOKEN_CACHE_TIME,
@@ -37,5 +37,7 @@ module.exports = {
3737
PAGE_SIZE: process.env.PAGE_SIZE || 20,
3838
MAX_PAGE_SIZE: parseInt(process.env.MAX_PAGE_SIZE) || 100,
3939
ES_BATCH_SIZE: process.env.ES_BATCH_SIZE || 250,
40+
UPDATE_V5_CHALLENGE_BATCH_SIZE: process.env.UPDATE_V5_CHALLENGE_BATCH_SIZE || 250,
41+
SUBMISSION_TABLE_NAME: process.env.SUBMISSION_TABLE_NAME || 'Submission',
4042
AUTH0_PROXY_SERVER_URL: process.env.AUTH0_PROXY_SERVER_URL
4143
}

config/test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
LOG_LEVEL: 'info',
88
WEB_SERVER_PORT: 3010,
99
AUTH_SECRET: 'mysecret',
10-
VALID_ISSUERS: '["https://api.topcoder.com"]',
10+
VALID_ISSUERS: process.env.VALID_ISSUERS ? process.env.VALID_ISSUERS.replace(/\\"/g, '') : '["https://api.topcoder.com","https://topcoder-dev.auth0.com/"]',
1111
API_VERSION: process.env.API_VERSION || '/api/v5',
1212
aws: {
1313
AWS_REGION: process.env.AWS_REGION || 'us-east-1', // AWS Region to be used by the application
@@ -16,14 +16,14 @@ module.exports = {
1616
S3_BUCKET: process.env.S3_BUCKET_TEST || 'tc-testing-submissions' // S3 Bucket to which submissions need to be uploaded
1717
},
1818
BUSAPI_EVENTS_URL: 'https://api.topcoder-dev.com/v5/bus/events',
19-
CHALLENGEAPI_URL: 'https://api.topcoder-dev.com/v4/challenges',
19+
BUSAPI_URL: 'https://api.topcoder-dev.com/v5',
20+
CHALLENGEAPI_V5_URL: 'https://api.topcoder-dev.com/v5/challenges',
2021
esConfig: {
2122
ES_INDEX: process.env.ES_INDEX_TEST || 'submission-test',
2223
ES_TYPE: process.env.ES_TYPE_TEST || '_doc' // ES 6.x accepts only 1 Type per index and it's mandatory to define it
2324
},
2425
AUTH0_URL: process.env.AUTH0_URL, // Auth0 credentials for Submission Service
25-
AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE || 'https://www.topcoder.com',
26-
TOKEN_CACHE_TIME: process.env.TOKEN_CACHE_TIME,
26+
AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE,
2727
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID,
2828
AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET,
2929
USER_TOKEN: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJUb3Bjb2RlciBVc2VyIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLmNvbSIsImhhbmRsZSI6IlNoYXJhdGhrdW1hcjkyIiwiZXhwIjo1NTUzMDE5OTI1OSwidXNlcklkIjoiNDA0OTMwNTAiLCJpYXQiOjE1MzAxOTg2NTksImVtYWlsIjoiU2hhcmF0aGt1bWFyOTJAdG9wY29kZXIuY29tIiwianRpIjoiYzNhYzYwOGEtNTZiZS00NWQwLThmNmEtMzFmZTk0Yjk1NjFjIn0.2gtNJwhcv7MYc-muX3Nv-B0RdWbhMRl7-xrwFUsLazM',

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"delete-index": "node scripts/deleteIndex.js",
1515
"init-es": "node scripts/loadES.js",
1616
"db-to-es": "node scripts/migrateFromDBToES.js",
17+
"update-to-v5-challengeId": "node scripts/updateToV5ChallengeId.js",
1718
"test": "mocha test/unit/*.test.js --require test/unit/prepare.js --exit",
1819
"e2e": "mocha test/e2e/*.test.js --require test/e2e/prepare.js --exit",
1920
"cov": "nyc --reporter=html --reporter=text mocha test/unit/*.test.js --require test/unit/prepare.js --exit",

scripts/createIndex.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ co(function * createIndex () {
1818
properties: {
1919
resource: { type: 'keyword' },
2020
challengeId: { type: 'keyword' },
21+
legacyChallengeId: { type: 'keyword' },
2122
memberId: { type: 'keyword' },
2223
type: { type: 'keyword' },
2324
isFileSubmission: { type: 'boolean' },

scripts/updateToV5ChallengeId.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* Store v5 challenge id for current records
3+
*/
4+
5+
const _ = require('lodash')
6+
const co = require('co')
7+
const config = require('config')
8+
const logger = require('../src/common/logger')
9+
const dbhelper = require('../src/common/dbhelper')
10+
const helper = require('../src/common/helper')
11+
12+
/**
13+
* Update Submission's challenge id to v5
14+
* @param {Object} submission The submission record
15+
* @returns {Promise}
16+
*/
17+
function * updateRecord (submission) {
18+
const v5challengeId = yield helper.getV5ChallengeId(submission.challengeId)
19+
const record = {
20+
TableName: 'Submission',
21+
Key: {
22+
id: submission.id
23+
},
24+
UpdateExpression: `set challengeId = :c, legacyChallengeId = :l`,
25+
ExpressionAttributeValues: {
26+
':c': v5challengeId,
27+
':l': submission.challengeId
28+
}
29+
}
30+
if (!v5challengeId) {
31+
logger.warn(`the challengeId: ${submission.challengeId} is not having a v5 challengeId`)
32+
33+
return
34+
} else if (v5challengeId === submission.challengeId) {
35+
logger.info(`the challengeId: ${submission.challengeId} is already a v5 challengeId`)
36+
}
37+
38+
yield dbhelper.updateRecord(record)
39+
}
40+
41+
/*
42+
* Update all submission's challenge id to v5
43+
* @returns {Promise}
44+
*/
45+
function * updateRecords () {
46+
const tableName = config.SUBMISSION_TABLE_NAME
47+
let promises = []
48+
const params = {
49+
TableName: tableName
50+
}
51+
// Process until all the records from DB is fetched
52+
while (true) {
53+
const records = yield dbhelper.scanRecords(params)
54+
const totalRecords = records.Items.length
55+
logger.debug(`Number of ${tableName}s fetched from DB - ${totalRecords}. More fetch iterations may follow (pagination in progress)`)
56+
for (let i = 0; i < totalRecords; i++) {
57+
const record = records.Items[i]
58+
promises.push(updateRecord(record))
59+
}
60+
// Continue fetching the remaining records from Database
61+
if (typeof records.LastEvaluatedKey !== 'undefined') {
62+
params.ExclusiveStartKey = records.LastEvaluatedKey
63+
} else {
64+
break // If there are no more records to process, exit the loop
65+
}
66+
}
67+
logger.debug(`All records fetched. Proceeding to update them in batches of ${config.UPDATE_V5_CHALLENGE_BATCH_SIZE}`)
68+
const paraRecords = _.chunk(promises, config.UPDATE_V5_CHALLENGE_BATCH_SIZE)
69+
for (const rs of paraRecords) {
70+
yield rs
71+
}
72+
}
73+
74+
co(function * () {
75+
yield updateRecords()
76+
}).catch((err) => {
77+
logger.logFullError(err)
78+
})

0 commit comments

Comments
 (0)