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

Commit 2ce82ac

Browse files
authored
Merge pull request #21 from topcoder-platform/Issue_20
Issue 20
2 parents cb41f6f + 43d0127 commit 2ce82ac

File tree

8 files changed

+126
-84
lines changed

8 files changed

+126
-84
lines changed

README.md

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Dependencies
44

5-
- nodejs https://nodejs.org/en/ (v10)
5+
- Nodejs (v10)
66
- Kafka (v2)
77

88
## Configuration
@@ -35,6 +35,7 @@ The following parameters can be set in config files or in env variables:
3535
Also note that there is a `/health` endpoint that checks for the health of the app. This sets up an expressjs server and listens on the environment variable `PORT`. It's not part of the configuration file and needs to be passed as an environment variable
3636

3737
Configuration for the tests is at `config/test.js`, only add such new configurations different from `config/default.js`
38+
3839
- WAIT_TIME: wait time used in test, default is 1000 or one second
3940
- LEADERBOARD_API_URL: Leaderboard API URL used in testing
4041
- SUBMISSION_API_URL: Submission API URL used in testing
@@ -67,7 +68,7 @@ Configuration for the tests is at `config/test.js`, only add such new configurat
6768
- In the console, write some message, one message per line:
6869

6970
```bash
70-
{ "topic":"submission.notification.create", "originator":"submission-api", "timestamp":"2018-08-06T15:46:05.575Z", "mime-type":"application/json", "payload":{ "resource":"reviewSummation", "id": "d24d4180-65aa-42ec-a945-5fd21dec0508", "submissionId": "a34e1158-2c27-4d38-b079-5e5cca1bdcf7", "aggregateScore": 88, "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", "isPassing": true, "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", "createdBy": "admin", "updatedBy": "admin" } }
71+
{"topic":"submission.notification.create","originator":"submission-api","timestamp":"2018-08-06T15:46:05.575Z","mime-type":"application/json","payload":{"resource":"review","id":"49871146-eb0a-4d0e-ab9a-adc94018c5da","submissionId":"6ff0c009-51ee-4c8e-aa0d-159c20503cc2","score":-1,"scoreCardId":30001852,"metadata":{"testType":"provisional","tests":{"pending":0,"failed":1,"total":10}},"created":"2019-11-06T15:02:35.539Z","updated":"2019-11-06T15:02:35.539Z","createdBy":"I3etJtTqlz1XHgCXduBN1us705ufrykl@clients","updatedBy":"I3etJtTqlz1XHgCXduBN1us705ufrykl@clients","status":"completed","reviewerId":"0301619c-3d9e-44c3-85cb-c20311100f7f","typeId":"52c91e85-745f-4e62-b592-9879a2dfe9fd"}}
7172
```
7273

7374
- optionally, use another terminal, go to same directory, start a consumer to view the messages:
@@ -115,78 +116,52 @@ npm start
115116

116117
2. Refer `README.md` in `leaderboard-api` to start leaderboard api, all operations are under `leaderboard-api` project root folder
117118

118-
- Start mock app and it will listen on 3001 PORT.
119-
120-
```bash
121-
npm run mock-api
122-
```
123-
124-
- Ensure you have start MongoDB and properly configure `MONGODB_URL`. Run the following commands to clear and insert test data, step up environment variables and start the app(it will listen on 3002 PORT!).
125-
126-
```bash
127-
npm run init-db
128-
npm run test-data
129-
export CHALLENGE_API_URL=http://localhost:3001/challenges
130-
export MEMBER_API_URL=http://localhost:3001/users
131-
export PORT=3002
132-
npm start
133-
```
119+
3. Set the necessary environment variables and then run `npm start` command to start processor app(Under this project's root folder)
134120

135-
3. Run the following command to start processor app(Under this project's root folder)
136-
```bash
137-
export AUTH0_URL=https://topcoder-dev.auth0.com/oauth/token
138-
export AUTH0_AUDIENCE=https://m2m.topcoder-dev.com/
139-
export TOKEN_CACHE_TIME=90
140-
export AUTH0_CLIENT_ID=8QovDh27SrDu1XSs68m21A1NBP8isvOt
141-
export AUTH0_CLIENT_SECRET=3QVxxu20QnagdH-McWhVz0WfsQzA1F8taDdGDI4XphgpEYZPcMTF4lX3aeOIeCzh
142-
export LEADERBOARD_API_URL=http://localhost:3002/v5/leaderboard
143-
export SUBMISSION_API_URL=http://localhost:3001/submissions
144-
npm start
145-
```
121+
4. Attach to the topic `submission.notification.create` using Kafka console producer
146122

147-
3. Attach to the topic `submission.notification.create` using Kafka console producer
123+
```bash
124+
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic submission.notification.create
125+
```
148126

149-
```bash
150-
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic submission.notification.create
151-
```
127+
5. Write the following message to the Console
152128

153-
4. Write the following message to the Console
129+
```bash
130+
{"topic":"submission.notification.create","originator":"submission-api","timestamp":"2018-08-06T15:46:05.575Z","mime-type":"application/json","payload":{"resource":"review","id":"49871146-eb0a-4d0e-ab9a-adc94018c5da","submissionId":"6ff0c009-51ee-4c8e-aa0d-159c20503cc2","score":-1,"scoreCardId":30001852,"metadata":{"testType":"provisional","tests":{"pending":0,"failed":1,"total":10}},"created":"2019-11-06T15:02:35.539Z","updated":"2019-11-06T15:02:35.539Z","createdBy":"I3etJtTqlz1XHgCXduBN1us705ufrykl@clients","updatedBy":"I3etJtTqlz1XHgCXduBN1us705ufrykl@clients","status":"completed","reviewerId":"0301619c-3d9e-44c3-85cb-c20311100f7f","typeId":"52c91e85-745f-4e62-b592-9879a2dfe9fd"}}
131+
```
154132

155-
```bash
156-
{ "topic":"submission.notification.create", "originator":"submission-api", "timestamp":"2018-08-06T15:46:05.575Z", "mime-type":"application/json", "payload":{ "resource":"reviewSummation", "id": "d24d4180-65aa-42ec-a945-5fd21dec0508", "submissionId": "a34e1158-2c27-4d38-b079-5e5cca1bdcf7", "aggregateScore": 90, "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", "isPassing": true, "metadata": { "assertions": { "pending": 0, "failed": 1, "total": 10}, "tests": { "total": 10 } }, "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", "createdBy": "admin", "updatedBy": "admin" } }
157-
```
133+
6. You could see in the console that message will be processed, and find the following message: `Record with Challenge ID # 30051825 and Member ID # 8547899 does not exists in database. Creating the record`. Also check the leaderboard-api console for more information(Console in step 2)
158134

159-
5. You could see in the console that message will be processed, and find the following message: `Record with Challenge ID # 30051825 and Member ID # 8547899 does not exists in database. Creating the record`. Also check the leaderboard-api console for more information(Console in step 2)
135+
7. Attach to the topic `submission.notification.update` using Kafka console producer
160136

161-
6. Attach to the topic `submission.notification.update` using Kafka console producer
137+
```bash
138+
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic submission.notification.update
139+
```
162140

163-
```bash
164-
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic submission.notification.update
165-
```
141+
8. Write the following message to the Console
166142

167-
7. Write the following message to the Console
143+
```bash
144+
{"topic":"submission.notification.update","originator":"submission-api","timestamp":"2018-08-06T15:46:05.575Z","mime-type":"application/json","payload":{"resource":"review","id":"49871146-eb0a-4d0e-ab9a-adc94018c5da","submissionId":"6ff0c009-51ee-4c8e-aa0d-159c20503cc2","score":52,"scoreCardId":30001852,"metadata":{"testType":"provisional","tests":{"pending":0,"failed":2,"total":8}},"created":"2019-11-06T15:02:35.539Z","updated":"2019-11-06T15:02:35.539Z","createdBy":"I3etJtTqlz1XHgCXduBN1us705ufrykl@clients","updatedBy":"I3etJtTqlz1XHgCXduBN1us705ufrykl@clients","status":"completed","reviewerId":"0301619c-3d9e-44c3-85cb-c20311100f7f","typeId":"52c91e85-745f-4e62-b592-9879a2dfe9fd"}}
145+
```
168146

169-
```bash
170-
{ "topic":"submission.notification.update", "originator":"submission-api", "timestamp":"2018-08-06T15:46:05.575Z", "mime-type":"application/json", "payload":{ "resource":"reviewSummation", "id": "d24d4180-65aa-42ec-a945-5fd21dec0508", "submissionId": "a34e1158-2c27-4d38-b079-5e5cca1bdcf7", "aggregateScore": 80, "scoreCardId": "b25a4180-65aa-42ec-a945-5fd21dec0503", "isPassing": true, "metadata": { "assertions": { "pending": 0, "failed": 1, "total": 5}, "tests": { "total": 5 } }, "created": "2018-05-20T07:00:30.123Z", "updated": "2018-06-01T07:36:28.178Z", "createdBy": "admin", "updatedBy": "admin" } }
171-
```
147+
9. You could see in the console that message will be processed, and find the following message: `Record with Challenge ID # 30051825 and Member ID # 8547899 exists in database. Updating the score`. Also check the leaderboard-api console for more information(Console in step 2)
172148

173-
8. You could see in the console that message will be processed, and find the following message: `Record with Challenge ID # 30051825 and Member ID # 8547899 exists in database. Updating the score`. Also check the leaderboard-api console for more information(Console in step 2)
149+
10. Attach to the topic `submission.notification.delete` using Kafka console producer
174150

175-
9. Attach to the topic `submission.notification.delete` using Kafka console producer
151+
```bash
152+
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic submission.notification.delete
153+
```
176154

177-
```bash
178-
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic submission.notification.delete
179-
```
155+
11. Write the following message to the Console. Also check the leaderboard-api console for more information(Console in step 2)
180156

181-
10. Write the following message to the Console. Also check the leaderboard-api console for more information(Console in step 2)
157+
```bash
158+
{ "topic":"submission.notification.delete", "originator":"submission-api", "timestamp":"2018-08-06T15:46:05.575Z", "mime-type":"application/json", "payload":{ "resource":"review", "id": "49871146-eb0a-4d0e-ab9a-adc94018c5da" } }
159+
```
182160
183-
```bash
184-
{ "topic":"submission.notification.delete", "originator":"submission-api", "timestamp":"2018-08-06T15:46:05.575Z", "mime-type":"application/json", "payload":{ "resource":"reviewSummation", "id": "d24d4180-65aa-42ec-a945-5fd21dec0508" } }
185-
```
161+
12. You could see in the console that message will be processed
186162
187-
11. You could see in the console that message will be processed
163+
## Tests
188164
189-
### Tests
190165
Note: you need to stop the processor app before execute test.
191166
192167
- Run the following command to execute unit test and generate coverage report

config/default.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = {
2121

2222
LEADERBOARD_API_URL: process.env.LEADERBOARD_API_URL || 'https://api.topcoder-dev.com/v5/leaderboard',
2323
SUBMISSION_API_URL: process.env.SUBMISSION_API_URL || 'https://api.topcoder-dev.com/v5/submissions',
24+
REVIEW_TYPE_URL: process.env.REVIEW_TYPE_URL || 'https://api.topcoder-dev.com/v5/reviewTypes',
2425

2526
AUTH0_URL: process.env.AUTH0_URL,
2627
AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE,

src/app.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const logger = require('./common/logger')
88
const Kafka = require('no-kafka')
99
const healthcheck = require('topcoder-healthcheck-dropin')
1010
const ProcessorService = require('./services/ProcessorService')
11+
const helper = require('./common/helper')
1112

1213
// start Kafka consumer
1314
logger.info('Start Kafka consumer.')
@@ -19,7 +20,7 @@ if (config.KAFKA_CLIENT_CERT && config.KAFKA_CLIENT_CERT_KEY) {
1920
const consumer = new Kafka.GroupConsumer(options)
2021

2122
// data handler
22-
const dataHandler = (messageSet, topic, partition) => Promise.each(messageSet, (m) => {
23+
const dataHandler = (messageSet, topic, partition) => Promise.each(messageSet, async (m) => {
2324
const message = m.message.value.toString('utf8')
2425
logger.info(`Handle Kafka event message; Topic: ${topic}; Partition: ${partition}; Offset: ${
2526
m.offset}; Message: ${message}.`)
@@ -40,12 +41,19 @@ const dataHandler = (messageSet, topic, partition) => Promise.each(messageSet, (
4041
return
4142
}
4243

43-
if (messageJSON.payload.resource !== 'reviewSummation') {
44-
logger.debug(`Ignoring Non review Summation payloads from topic ${messageJSON.topic}.`)
44+
if (messageJSON.payload.resource !== 'review') {
45+
logger.debug(`Ignoring Non review payloads from topic ${messageJSON.topic}.`)
4546
// ignore the message
4647
return
4748
}
4849

50+
const avScanTypeId = await helper.getreviewTypeId('AV Scan')
51+
52+
if (messageJSON.payload.typeId === avScanTypeId) {
53+
logger.debug(`Ignoring AV Scan reviews from topic ${messageJSON.topic}`)
54+
return false
55+
}
56+
4957
return (async () => {
5058
switch (topic) {
5159
case config.CREATE_DATA_TOPIC:

src/common/helper.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const m2mAuth = require('tc-core-library-js').auth.m2m
99

1010
const m2m = m2mAuth(_.pick(config, ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', 'AUTH0_PROXY_SERVER_URL']))
1111

12+
// Variable to cache reviewTypes from Submission API
13+
const reviewTypes = {}
14+
1215
/*
1316
* Function to get M2M token
1417
* @returns {Promise}
@@ -55,6 +58,25 @@ const reqToAPI = async (reqType, path, reqBody) => {
5558
})
5659
}
5760

61+
/*
62+
* Function to get reviewTypeId from Name
63+
* @param {String} reviewTypeName Name of the reviewType
64+
* @returns {String} reviewTypeId
65+
*/
66+
const getreviewTypeId = async (reviewTypeName) => {
67+
if (!reviewTypes[reviewTypeName]) {
68+
// Get review type id from Submission API
69+
const response = await reqToAPI('GET', `${config.REVIEW_TYPE_URL}?name=${reviewTypeName}`)
70+
if (response.body && response.body.length !== 0) {
71+
reviewTypes[reviewTypeName] = response.body[0].id
72+
} else {
73+
reviewTypes[reviewTypeName] = null
74+
}
75+
}
76+
return reviewTypes[reviewTypeName]
77+
}
78+
5879
module.exports = {
59-
reqToAPI
80+
reqToAPI,
81+
getreviewTypeId
6082
}

src/services/ProcessorService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ upsert.schema = {
4242
* @param {Object} message the Kafka message in JSON format
4343
*/
4444
async function remove (message) {
45-
await helper.reqToAPI('DELETE', `${config.LEADERBOARD_API_URL}/reviewSummation/${message.payload.id}`)
45+
await helper.reqToAPI('DELETE', `${config.LEADERBOARD_API_URL}/review/${message.payload.id}`)
4646
}
4747

4848
remove.schema = {

test/common/prepare.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
const nock = require('nock')
66
const prepare = require('mocha-prepare')
7-
const { submissionAPIResponse } = require('./testData')
7+
const { submissionAPIResponse, reviewTypesResponse } = require('./testData')
88

99
prepare(function (done) {
1010
nock(/\.com/)
@@ -25,8 +25,10 @@ prepare(function (done) {
2525
.reply(200)
2626
.patch('/v5/leaderboard/challenge/30051825/member/22688726')
2727
.reply(200)
28-
.delete('/v5/leaderboard/reviewSummation/d24d4180-65aa-42ec-a945-5fd21dec0510')
28+
.delete('/v5/leaderboard/review/49871146-eb0a-4d0e-ab9a-adc94018c5da')
2929
.reply(204)
30+
.get('/v5/reviewTypes?name=AV%20Scan')
31+
.reply(200, reviewTypesResponse)
3032

3133
done()
3234
}, function (done) {

test/common/testData.js

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,29 @@ const testTopics = {
99
testMessage: {
1010
topic: 'submission.notification.create',
1111
originator: 'submission-api',
12-
timestamp: '2018-02-03T00:00:00',
12+
timestamp: '2018-08-06T15:46:05.575Z',
1313
'mime-type': 'application/json',
1414
payload: {
15-
resource: 'reviewSummation',
16-
id: 'd24d4180-65aa-42ec-a945-5fd21dec0508',
15+
resource: 'review',
16+
id: '49871146-eb0a-4d0e-ab9a-adc94018c5da',
1717
submissionId: 'a34e1158-2c27-4d38-b079-5e5cca1bdcf7',
18-
aggregateScore: 88,
19-
scoreCardId: 'b25a4180-65aa-42ec-a945-5fd21dec0503',
20-
isPassing: true,
21-
created: '2018-01-01T00:00:00',
22-
updated: '2018-01-02T00:00:00',
23-
createdBy: 'admin',
24-
updatedBy: 'user'
18+
score: -1,
19+
scoreCardId: 30001852,
20+
metadata: {
21+
testType: 'provisional',
22+
tests: {
23+
pending: 0,
24+
failed: 1,
25+
total: 10
26+
}
27+
},
28+
created: '2019-11-06T15:02:35.539Z',
29+
updated: '2019-11-06T15:02:35.539Z',
30+
createdBy: 'I3etJtTqlz1XHgCXduBN1us705ufrykl@clients',
31+
updatedBy: 'I3etJtTqlz1XHgCXduBN1us705ufrykl@clients',
32+
status: 'completed',
33+
reviewerId: '0301619c-3d9e-44c3-85cb-c20311100f7f',
34+
typeId: '52c91e85-745f-4e62-b592-9879a2dfe9fd'
2535
}
2636
}
2737
},
@@ -31,14 +41,29 @@ const testTopics = {
3141
testMessage: {
3242
topic: 'submission.notification.update',
3343
originator: 'submission-api',
34-
timestamp: '2018-02-03T00:00:00',
44+
timestamp: '2018-08-06T15:46:05.575Z',
3545
'mime-type': 'application/json',
3646
payload: {
37-
resource: 'reviewSummation',
38-
id: 'd24d4180-65aa-42ec-a945-5fd21dec0509',
47+
resource: 'review',
48+
id: '49871146-eb0a-4d0e-ab9a-adc94018c5da',
3949
submissionId: 'a34e1158-2c27-4d38-b079-5e5cca1bdcf8',
40-
aggregateScore: 93.5,
41-
isPassing: true
50+
score: 52,
51+
scoreCardId: 30001852,
52+
metadata: {
53+
testType: 'provisional',
54+
tests: {
55+
pending: 0,
56+
failed: 2,
57+
total: 10
58+
}
59+
},
60+
created: '2019-11-06T15:02:35.539Z',
61+
updated: '2019-11-06T15:02:35.539Z',
62+
createdBy: 'I3etJtTqlz1XHgCXduBN1us705ufrykl@clients',
63+
updatedBy: 'I3etJtTqlz1XHgCXduBN1us705ufrykl@clients',
64+
status: 'completed',
65+
reviewerId: '0301619c-3d9e-44c3-85cb-c20311100f7f',
66+
typeId: '52c91e85-745f-4e62-b592-9879a2dfe9fd'
4267
}
4368
}
4469
},
@@ -51,8 +76,8 @@ const testTopics = {
5176
timestamp: '2018-02-03T00:00:00',
5277
'mime-type': 'application/json',
5378
payload: {
54-
resource: 'reviewSummation',
55-
id: 'd24d4180-65aa-42ec-a945-5fd21dec0510'
79+
resource: 'review',
80+
id: '49871146-eb0a-4d0e-ab9a-adc94018c5da'
5681
}
5782
}
5883
}
@@ -79,7 +104,7 @@ const submissionAPIResponse = [
79104
'created': '2018-08-22T02:41:07.576Z',
80105
'isFileSubmission': true,
81106
'type': 'challengesubmission',
82-
'url': 'https://topcoder-dev-submissions-dmz.s3.amazonaws.com/a34e1158-2c27-4d38-b079-%3Cspan%20class="x x-first x-last">5e5cca1bdcf7',
107+
'url': 'https://topcoder-dev-submissions-dmz.s3.amazonaws.com/a34e1158-2c27-4d38-b079-%3Cspan%20class="x x-first x-last">5e5cca1bdcf8',
83108
'challengeId': 30051825,
84109
'filename': 'CORE-TopcoderEventBus-190618-1413.pdf.zip',
85110
'createdBy': 'lazybaer',
@@ -91,7 +116,16 @@ const submissionAPIResponse = [
91116
}
92117
]
93118

119+
const reviewTypesResponse = [
120+
{
121+
'name': 'AV Scan',
122+
'id': '6da98d0f-e663-4539-8507-cd6c9e0e56d8',
123+
'isActive': true
124+
}
125+
]
126+
94127
module.exports = {
95128
submissionAPIResponse,
96-
testTopics
129+
testTopics,
130+
reviewTypesResponse
97131
}

test/e2e/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ describe('Topcoder - Leaderboard Processor E2E Test', () => {
224224
await waitJob()
225225

226226
expect(errorLogs.length).to.equal(0)
227-
expect(debugLogs[debugLogs.length - 1]).to.equal(`Ignoring Non review Summation payloads from topic ${message.topic}.`)
227+
expect(debugLogs[debugLogs.length - 1]).to.equal(`Ignoring Non review payloads from topic ${message.topic}.`)
228228
})
229229

230230
for (const op of ['create', 'update', 'delete']) {

0 commit comments

Comments
 (0)