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

Commit e2e1b10

Browse files
committed
#444 send message to kafka if token is not valid.
1 parent f0fdfee commit e2e1b10

10 files changed

+285
-123
lines changed

config/default.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module.exports = {
1616
LOG_LEVEL: process.env.LOG_LEVEL || 'debug',
1717
PARTITION: process.env.PARTITION || 0,
1818
TOPIC: process.env.TOPIC || 'tc-x-events',
19+
TOPIC_NOTIFICATION: process.env.TOPIC_NOTIFICATION || 'notifications.action.create',
1920
KAFKA_OPTIONS: {
2021
connectionString: process.env.KAFKA_URL || 'localhost:9092',
2122
groupId: process.env.KAFKA_GROUP_ID || 'topcoder-x-processor',
@@ -25,6 +26,11 @@ module.exports = {
2526
passphrase: 'secret', // NOTE:* This configuration specifies the private key passphrase used while creating it.
2627
}
2728
},
29+
MAIL_NOTICIATION: {
30+
type: 'tcx.mail_notification',
31+
sendgridTemplateId: 'xxxxxx',
32+
subject: 'Topcoder X Alert'
33+
},
2834
NEW_CHALLENGE_TEMPLATE: process.env.NEW_CHALLENGE_TEMPLATE || {
2935
status: 'Draft'
3036
},

index.js

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

66
const config = require('config');
77
const _ = require('lodash');
8-
const kafka = require('./utils/kafka');
8+
const kafkaConsumer = require('./utils/kafka-consumer');
99
const logger = require('./utils/logger');
1010

1111
process.on('uncaughtException', (err) => {
@@ -55,4 +55,4 @@ dumpConfigs(config, 0);
5555
logger.debug('--- End of List of Configurations ---');
5656

5757
// run the server
58-
kafka.run();
58+
kafkaConsumer.run();

services/GithubService.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ async function _authenticate(accessToken) {
5353
});
5454
return octokit.rest;
5555
} catch (err) {
56-
throw errors.convertGitHubError(err, 'Failed to authenticate to Github using access token of copilot.');
56+
throw errors.handleGitHubError(err, 'Failed to authenticate to Github using access token of copilot.');
5757
}
5858
}
5959

@@ -75,7 +75,7 @@ async function _removeAssignees(github, owner, repo, number, assignees) {
7575
assignees
7676
});
7777
} catch (err) {
78-
throw errors.convertGitHubError(err, 'Error occurred during remove assignees from issue.');
78+
throw errors.handleGitHubError(err, 'Error occurred during remove assignees from issue.');
7979
}
8080
}
8181

@@ -93,6 +93,17 @@ async function _getUsernameById(id) {
9393
return user ? user.login : null;
9494
}
9595

96+
/**
97+
* Get github issue url
98+
* @param {String} repoPath the repo path
99+
* @param {Number} number the issue number
100+
* @returns {String} the url
101+
* @private
102+
*/
103+
function _getIssueUrl(repoPath, number) {
104+
return `https://github.com/${repoPath}/issues/${number}`;
105+
}
106+
96107
/**
97108
* updates the title of github issue
98109
* @param {Object} copilot the copilot
@@ -107,7 +118,7 @@ async function updateIssue(copilot, repoFullName, number, title) {
107118
try {
108119
await github.issues.update({owner, repo, issue_number: number, title});
109120
} catch (err) {
110-
throw errors.convertGitHubError(err, 'Error occurred during updating issue.');
121+
throw errors.handleGitHubError(err, 'Error occurred during updating issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
111122
}
112123
logger.debug(`Github issue title is updated for issue number ${number}`);
113124
}
@@ -139,7 +150,7 @@ async function assignUser(copilot, repoFullName, number, user) {
139150
}
140151
await github.issues.addAssignees({owner, repo, issue_number: number, assignees: [user]});
141152
} catch (err) {
142-
throw errors.convertGitHubError(err, 'Error occurred during assigning issue user.');
153+
throw errors.handleGitHubError(err, 'Error occurred during assigning issue user.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
143154
}
144155
logger.debug(`Github issue with number ${number} is assigned to ${user}`);
145156
}
@@ -184,7 +195,7 @@ async function createComment(copilot, repoFullName, number, body) {
184195
body = helper.prepareAutomatedComment(body, copilot);
185196
await github.issues.createComment({owner, repo, issue_number: number, body});
186197
} catch (err) {
187-
throw errors.convertGitHubError(err, 'Error occurred during creating comment on issue.');
198+
throw errors.handleGitHubError(err, 'Error occurred during creating comment on issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
188199
}
189200
logger.debug(`Github comment is added on issue with message: "${body}"`);
190201
}
@@ -262,7 +273,7 @@ async function markIssueAsPaid(copilot, repoFullName, number, challengeUUID, exi
262273
const body = helper.prepareAutomatedComment(commentMessage, copilot);
263274
await github.issues.createComment({owner, repo, issue_number: number, body});
264275
} catch (err) {
265-
throw errors.convertGitHubError(err, 'Error occurred during updating issue as paid.');
276+
throw errors.handleGitHubError(err, 'Error occurred during updating issue as paid.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
266277
}
267278
logger.debug(`Github issue title is updated for as paid and fix accepted for ${number}`);
268279
}
@@ -291,7 +302,7 @@ async function changeState(copilot, repoFullName, number, state) {
291302
try {
292303
await github.issues.update({owner, repo, issue_number: number, state});
293304
} catch (err) {
294-
throw errors.convertGitHubError(err, 'Error occurred during updating status of issue.');
305+
throw errors.handleGitHubError(err, 'Error occurred during updating status of issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
295306
}
296307
logger.debug(`Github issue state is updated to '${state}' for issue number ${number}`);
297308
}
@@ -317,7 +328,7 @@ async function addLabels(copilot, repoFullName, number, labels) {
317328
try {
318329
await github.issues.update({owner, repo, issue_number: number, labels});
319330
} catch (err) {
320-
throw errors.convertGitHubError(err, 'Error occurred during adding label in issue.');
331+
throw errors.handleGitHubError(err, 'Error occurred during adding label in issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
321332
}
322333
logger.debug(`Github issue is updated with new labels for ${number}`);
323334
}

services/GitlabService.js

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async function _authenticate(accessToken) {
3737
});
3838
return gitlab;
3939
} catch (err) {
40-
throw errors.convertGitLabError(err, 'Failed to during authenticate to Github using access token of copilot.');
40+
throw errors.handleGitLabError(err, 'Failed to during authenticate to Github using access token of copilot.');
4141
}
4242
}
4343

@@ -55,25 +55,37 @@ async function _removeAssignees(gitlab, projectId, issueId, assignees) {
5555
const oldAssignees = _.difference(issue.assignee_ids, assignees);
5656
await gitlab.projects.issues.edit(projectId, issueId, {assignee_ids: oldAssignees});
5757
} catch (err) {
58-
throw errors.convertGitLabError(err, 'Error occurred during remove assignees from issue.');
58+
throw errors.handleGitLabError(err, 'Error occurred during remove assignees from issue.');
5959
}
6060
}
6161

62+
/**
63+
* Get gitlab issue url
64+
* @param {String} repoPath the repo path
65+
* @param {Number} issueId the issue number
66+
* @returns {String} the url
67+
* @private
68+
*/
69+
function _getIssueUrl(repoPath, issueId) {
70+
return `https://gitlab.com/${repoPath}/issues/${issueId}`;
71+
}
72+
6273
/**
6374
* creates the comments on gitlab issue
6475
* @param {Object} copilot the copilot
65-
* @param {Number} projectId the project id
76+
* @param {Object} project the project object
6677
* @param {Number} issueId the issue number
6778
* @param {string} body the comment body text
6879
*/
69-
async function createComment(copilot, projectId, issueId, body) {
80+
async function createComment(copilot, project, issueId, body) {
81+
const projectId = project.id;
7082
Joi.attempt({copilot, projectId, issueId, body}, createComment.schema);
7183
const gitlab = await _authenticate(copilot.accessToken);
7284
try {
7385
body = helper.prepareAutomatedComment(body, copilot);
7486
await gitlab.projects.issues.notes.create(projectId, issueId, {body});
7587
} catch (err) {
76-
throw errors.convertGitLabError(err, 'Error occurred during creating comment on issue.');
88+
throw errors.handleGitLabError(err, 'Error occurred during creating comment on issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
7789
}
7890
logger.debug(`Gitlab comment is added on issue with message: "${body}"`);
7991
}
@@ -88,17 +100,18 @@ createComment.schema = {
88100
/**
89101
* updates the title of gitlab issue
90102
* @param {Object} copilot the copilot
91-
* @param {Number} projectId the project id
103+
* @param {Object} project the project object
92104
* @param {Number} issueId the issue number
93105
* @param {string} title new title
94106
*/
95-
async function updateIssue(copilot, projectId, issueId, title) {
107+
async function updateIssue(copilot, project, issueId, title) {
108+
const projectId = project.id;
96109
Joi.attempt({copilot, projectId, issueId, title}, updateIssue.schema);
97110
const gitlab = await _authenticate(copilot.accessToken);
98111
try {
99112
await gitlab.projects.issues.edit(projectId, issueId, {title});
100113
} catch (err) {
101-
throw errors.convertGitLabError(err, 'Error occurred during updating issue.');
114+
throw errors.handleGitLabError(err, 'Error occurred during updating issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
102115
}
103116
logger.debug(`Gitlab issue title is updated for issue number ${issueId}`);
104117
}
@@ -113,11 +126,12 @@ updateIssue.schema = {
113126
/**
114127
* Assigns the issue to user login
115128
* @param {Object} copilot the copilot
116-
* @param {Number} projectId the project id
129+
* @param {Object} project the project object
117130
* @param {Number} issueId the issue number
118131
* @param {Number} userId the user id of assignee
119132
*/
120-
async function assignUser(copilot, projectId, issueId, userId) {
133+
async function assignUser(copilot, project, issueId, userId) {
134+
const projectId = project.id;
121135
Joi.attempt({copilot, projectId, issueId, userId}, assignUser.schema);
122136
const gitlab = await _authenticate(copilot.accessToken);
123137
try {
@@ -128,7 +142,7 @@ async function assignUser(copilot, projectId, issueId, userId) {
128142
}
129143
await gitlab.projects.issues.edit(projectId, issueId, {assignee_ids: [userId]});
130144
} catch (err) {
131-
throw errors.convertGitLabError(err, 'Error occurred during assigning issue user.');
145+
throw errors.handleGitLabError(err, 'Error occurred during assigning issue user.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
132146
}
133147
logger.debug(`Gitlab issue with number ${issueId} is assigned to ${issueId}`);
134148
}
@@ -143,11 +157,12 @@ assignUser.schema = {
143157
/**
144158
* Removes an assignee from the issue
145159
* @param {Object} copilot the copilot
146-
* @param {Number} projectId the project id
160+
* @param {Object} project the project object
147161
* @param {Number} issueId the issue number
148162
* @param {Number} userId the user id of assignee to remove
149163
*/
150-
async function removeAssign(copilot, projectId, issueId, userId) {
164+
async function removeAssign(copilot, project, issueId, userId) {
165+
const projectId = project.id;
151166
Joi.attempt({copilot, projectId, issueId, userId}, removeAssign.schema);
152167
const gitlab = await _authenticate(copilot.accessToken);
153168
await _removeAssignees(gitlab, projectId, issueId, [userId]);
@@ -195,14 +210,15 @@ getUserIdByLogin.schema = {
195210
/**
196211
* updates the gitlab issue as paid and fix accepted
197212
* @param {Object} copilot the copilot
198-
* @param {Number} projectId the project id
213+
* @param {Object} project the project object
199214
* @param {Number} issueId the issue number
200215
* @param {String} challengeUUID the challenge uuid
201216
* @param {Array} existLabels the issue labels
202217
* @param {String} winner the winner topcoder handle
203218
* @param {Boolean} createCopilotPayments the option to create copilot payments or not
204219
*/
205-
async function markIssueAsPaid(copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params
220+
async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params
221+
const projectId = project.id;
206222
Joi.attempt({copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments}, markIssueAsPaid.schema);
207223
const gitlab = await _authenticate(copilot.accessToken);
208224
const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL)
@@ -222,7 +238,7 @@ async function markIssueAsPaid(copilot, projectId, issueId, challengeUUID, exist
222238
const body = helper.prepareAutomatedComment(commentMessage, copilot);
223239
await gitlab.projects.issues.notes.create(projectId, issueId, {body});
224240
} catch (err) {
225-
throw errors.convertGitLabError(err, 'Error occurred during updating issue as paid.');
241+
throw errors.handleGitLabError(err, 'Error occurred during updating issue as paid.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
226242
}
227243
logger.debug(`Gitlab issue is updated for as paid and fix accepted for ${issueId}`);
228244
}
@@ -240,17 +256,18 @@ markIssueAsPaid.schema = {
240256
/**
241257
* change the state of gitlab issue
242258
* @param {Object} copilot the copilot
243-
* @param {string} projectId the project id
259+
* @param {Object} project the project object
244260
* @param {Number} issueId the issue issue id
245261
* @param {string} state new state
246262
*/
247-
async function changeState(copilot, projectId, issueId, state) {
263+
async function changeState(copilot, project, issueId, state) {
264+
const projectId = project.id;
248265
Joi.attempt({copilot, projectId, issueId, state}, changeState.schema);
249266
const gitlab = await _authenticate(copilot.accessToken);
250267
try {
251268
await gitlab.projects.issues.edit(projectId, issueId, {state_event: state});
252269
} catch (err) {
253-
throw errors.convertGitLabError(err, 'Error occurred during updating status of issue.');
270+
throw errors.handleGitLabError(err, 'Error occurred during updating status of issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
254271
}
255272
logger.debug(`Gitlab issue state is updated to '${state}' for issue number ${issueId}`);
256273
}
@@ -265,17 +282,18 @@ changeState.schema = {
265282
/**
266283
* updates the gitlab issue with new labels
267284
* @param {Object} copilot the copilot
268-
* @param {string} projectId the project id
285+
* @param {Object} project the project object
269286
* @param {Number} issueId the issue issue id
270287
* @param {Number} labels the labels
271288
*/
272-
async function addLabels(copilot, projectId, issueId, labels) {
289+
async function addLabels(copilot, project, issueId, labels) {
290+
const projectId = project.id;
273291
Joi.attempt({copilot, projectId, issueId, labels}, addLabels.schema);
274292
const gitlab = await _authenticate(copilot.accessToken);
275293
try {
276294
await gitlab.projects.issues.edit(projectId, issueId, {labels: _.join(labels, ',')});
277295
} catch (err) {
278-
throw errors.convertGitLabError(err, 'Error occurred during adding label in issue.');
296+
throw errors.handleGitLabError(err, 'Error occurred during adding label in issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
279297
}
280298
logger.debug(`Gitlab issue is updated with new labels for ${issueId}`);
281299
}

utils/errors.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
const _ = require('lodash');
1414
const constants = require('../constants');
15+
const notification = require('./notification');
1516

1617
// the error class wrapper
1718
class ProcessorError extends Error {
@@ -27,12 +28,17 @@ class ProcessorError extends Error {
2728
const errors = {};
2829

2930
/**
30-
* Convert github api error.
31+
* Handle github api error. Return converted error.
3132
* @param {Error} err the github api error
3233
* @param {String} message the error message
34+
* @param {String} copilotHandle the handle name of the copilot
35+
* @param {String} repoPath the link to related github page
3336
* @returns {Error} converted error
3437
*/
35-
errors.convertGitHubError = function convertGitHubError(err, message) {
38+
errors.handleGitHubError = function handleGitHubError(err, message, copilotHandle, repoPath) {
39+
if (err.statusCode === 401 && copilotHandle && repoPath) { // eslint-disable-line no-magic-numbers
40+
notification.sendTokenExpiredAlert(copilotHandle, repoPath, 'Github');
41+
}
3642
let resMsg = `${message}. ${err.message}.`;
3743
const detail = _.get(err, 'response.body.message');
3844
if (detail) {
@@ -47,12 +53,17 @@ errors.convertGitHubError = function convertGitHubError(err, message) {
4753
};
4854

4955
/**
50-
* Convert gitlab api error.
56+
* Handle gitlab api error. Return converted error.
5157
* @param {Error} err the gitlab api error
5258
* @param {String} message the error message
59+
* @param {String} copilotHandle the handle name of the copilot
60+
* @param {String} repoPath the link to related gitlab page
5361
* @returns {Error} converted error
5462
*/
55-
errors.convertGitLabError = function convertGitLabError(err, message) {
63+
errors.handleGitLabError = function handleGitLabError(err, message, copilotHandle, repoPath) {
64+
if (err.statusCode === 401 && copilotHandle && repoPath) { // eslint-disable-line no-magic-numbers
65+
notification.sendTokenExpiredAlert(copilotHandle, repoPath, 'Gitlab');
66+
}
5667
let resMsg = `${message}. ${err.message}.`;
5768
const detail = _.get(err, 'response.body.message');
5869
if (detail) {

0 commit comments

Comments
 (0)