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

#444 send message to kafka if token is not valid. #91

Merged
merged 1 commit into from
May 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/default.js
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ module.exports = {
LOG_LEVEL: process.env.LOG_LEVEL || 'debug',
PARTITION: process.env.PARTITION || 0,
TOPIC: process.env.TOPIC || 'tc-x-events',
TOPIC_NOTIFICATION: process.env.TOPIC_NOTIFICATION || 'notifications.action.create',
KAFKA_OPTIONS: {
connectionString: process.env.KAFKA_URL || 'localhost:9092',
groupId: process.env.KAFKA_GROUP_ID || 'topcoder-x-processor',
@@ -25,6 +26,11 @@ module.exports = {
passphrase: 'secret', // NOTE:* This configuration specifies the private key passphrase used while creating it.
}
},
MAIL_NOTICIATION: {
type: 'tcx.mail_notification',
sendgridTemplateId: 'xxxxxx',
subject: 'Topcoder X Alert'
},
NEW_CHALLENGE_TEMPLATE: process.env.NEW_CHALLENGE_TEMPLATE || {
status: 'Draft'
},
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

const config = require('config');
const _ = require('lodash');
const kafka = require('./utils/kafka');
const kafkaConsumer = require('./utils/kafka-consumer');
const logger = require('./utils/logger');

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

// run the server
kafka.run();
kafkaConsumer.run();
27 changes: 19 additions & 8 deletions services/GithubService.js
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ async function _authenticate(accessToken) {
});
return octokit.rest;
} catch (err) {
throw errors.convertGitHubError(err, 'Failed to authenticate to Github using access token of copilot.');
throw errors.handleGitHubError(err, 'Failed to authenticate to Github using access token of copilot.');
}
}

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

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

/**
* Get github issue url
* @param {String} repoPath the repo path
* @param {Number} number the issue number
* @returns {String} the url
* @private
*/
function _getIssueUrl(repoPath, number) {
return `https://github.com/${repoPath}/issues/${number}`;
}

/**
* updates the title of github issue
* @param {Object} copilot the copilot
@@ -107,7 +118,7 @@ async function updateIssue(copilot, repoFullName, number, title) {
try {
await github.issues.update({owner, repo, issue_number: number, title});
} catch (err) {
throw errors.convertGitHubError(err, 'Error occurred during updating issue.');
throw errors.handleGitHubError(err, 'Error occurred during updating issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
}
logger.debug(`Github issue title is updated for issue number ${number}`);
}
@@ -139,7 +150,7 @@ async function assignUser(copilot, repoFullName, number, user) {
}
await github.issues.addAssignees({owner, repo, issue_number: number, assignees: [user]});
} catch (err) {
throw errors.convertGitHubError(err, 'Error occurred during assigning issue user.');
throw errors.handleGitHubError(err, 'Error occurred during assigning issue user.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
}
logger.debug(`Github issue with number ${number} is assigned to ${user}`);
}
@@ -184,7 +195,7 @@ async function createComment(copilot, repoFullName, number, body) {
body = helper.prepareAutomatedComment(body, copilot);
await github.issues.createComment({owner, repo, issue_number: number, body});
} catch (err) {
throw errors.convertGitHubError(err, 'Error occurred during creating comment on issue.');
throw errors.handleGitHubError(err, 'Error occurred during creating comment on issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
}
logger.debug(`Github comment is added on issue with message: "${body}"`);
}
@@ -262,7 +273,7 @@ async function markIssueAsPaid(copilot, repoFullName, number, challengeUUID, exi
const body = helper.prepareAutomatedComment(commentMessage, copilot);
await github.issues.createComment({owner, repo, issue_number: number, body});
} catch (err) {
throw errors.convertGitHubError(err, 'Error occurred during updating issue as paid.');
throw errors.handleGitHubError(err, 'Error occurred during updating issue as paid.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
}
logger.debug(`Github issue title is updated for as paid and fix accepted for ${number}`);
}
@@ -291,7 +302,7 @@ async function changeState(copilot, repoFullName, number, state) {
try {
await github.issues.update({owner, repo, issue_number: number, state});
} catch (err) {
throw errors.convertGitHubError(err, 'Error occurred during updating status of issue.');
throw errors.handleGitHubError(err, 'Error occurred during updating status of issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
}
logger.debug(`Github issue state is updated to '${state}' for issue number ${number}`);
}
@@ -317,7 +328,7 @@ async function addLabels(copilot, repoFullName, number, labels) {
try {
await github.issues.update({owner, repo, issue_number: number, labels});
} catch (err) {
throw errors.convertGitHubError(err, 'Error occurred during adding label in issue.');
throw errors.handleGitHubError(err, 'Error occurred during adding label in issue.', copilot.topcoderUsername, _getIssueUrl(repoFullName, number));
}
logger.debug(`Github issue is updated with new labels for ${number}`);
}
62 changes: 40 additions & 22 deletions services/GitlabService.js
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ async function _authenticate(accessToken) {
});
return gitlab;
} catch (err) {
throw errors.convertGitLabError(err, 'Failed to during authenticate to Github using access token of copilot.');
throw errors.handleGitLabError(err, 'Failed to during authenticate to Github using access token of copilot.');
}
}

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

/**
* Get gitlab issue url
* @param {String} repoPath the repo path
* @param {Number} issueId the issue number
* @returns {String} the url
* @private
*/
function _getIssueUrl(repoPath, issueId) {
return `https://gitlab.com/${repoPath}/issues/${issueId}`;
}

/**
* creates the comments on gitlab issue
* @param {Object} copilot the copilot
* @param {Number} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue number
* @param {string} body the comment body text
*/
async function createComment(copilot, projectId, issueId, body) {
async function createComment(copilot, project, issueId, body) {
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, body}, createComment.schema);
const gitlab = await _authenticate(copilot.accessToken);
try {
body = helper.prepareAutomatedComment(body, copilot);
await gitlab.projects.issues.notes.create(projectId, issueId, {body});
} catch (err) {
throw errors.convertGitLabError(err, 'Error occurred during creating comment on issue.');
throw errors.handleGitLabError(err, 'Error occurred during creating comment on issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
}
logger.debug(`Gitlab comment is added on issue with message: "${body}"`);
}
@@ -88,17 +100,18 @@ createComment.schema = {
/**
* updates the title of gitlab issue
* @param {Object} copilot the copilot
* @param {Number} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue number
* @param {string} title new title
*/
async function updateIssue(copilot, projectId, issueId, title) {
async function updateIssue(copilot, project, issueId, title) {
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, title}, updateIssue.schema);
const gitlab = await _authenticate(copilot.accessToken);
try {
await gitlab.projects.issues.edit(projectId, issueId, {title});
} catch (err) {
throw errors.convertGitLabError(err, 'Error occurred during updating issue.');
throw errors.handleGitLabError(err, 'Error occurred during updating issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
}
logger.debug(`Gitlab issue title is updated for issue number ${issueId}`);
}
@@ -113,11 +126,12 @@ updateIssue.schema = {
/**
* Assigns the issue to user login
* @param {Object} copilot the copilot
* @param {Number} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue number
* @param {Number} userId the user id of assignee
*/
async function assignUser(copilot, projectId, issueId, userId) {
async function assignUser(copilot, project, issueId, userId) {
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, userId}, assignUser.schema);
const gitlab = await _authenticate(copilot.accessToken);
try {
@@ -128,7 +142,7 @@ async function assignUser(copilot, projectId, issueId, userId) {
}
await gitlab.projects.issues.edit(projectId, issueId, {assignee_ids: [userId]});
} catch (err) {
throw errors.convertGitLabError(err, 'Error occurred during assigning issue user.');
throw errors.handleGitLabError(err, 'Error occurred during assigning issue user.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
}
logger.debug(`Gitlab issue with number ${issueId} is assigned to ${issueId}`);
}
@@ -143,11 +157,12 @@ assignUser.schema = {
/**
* Removes an assignee from the issue
* @param {Object} copilot the copilot
* @param {Number} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue number
* @param {Number} userId the user id of assignee to remove
*/
async function removeAssign(copilot, projectId, issueId, userId) {
async function removeAssign(copilot, project, issueId, userId) {
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, userId}, removeAssign.schema);
const gitlab = await _authenticate(copilot.accessToken);
await _removeAssignees(gitlab, projectId, issueId, [userId]);
@@ -195,14 +210,15 @@ getUserIdByLogin.schema = {
/**
* updates the gitlab issue as paid and fix accepted
* @param {Object} copilot the copilot
* @param {Number} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue number
* @param {String} challengeUUID the challenge uuid
* @param {Array} existLabels the issue labels
* @param {String} winner the winner topcoder handle
* @param {Boolean} createCopilotPayments the option to create copilot payments or not
*/
async function markIssueAsPaid(copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params
async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments}, markIssueAsPaid.schema);
const gitlab = await _authenticate(copilot.accessToken);
const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL)
@@ -222,7 +238,7 @@ async function markIssueAsPaid(copilot, projectId, issueId, challengeUUID, exist
const body = helper.prepareAutomatedComment(commentMessage, copilot);
await gitlab.projects.issues.notes.create(projectId, issueId, {body});
} catch (err) {
throw errors.convertGitLabError(err, 'Error occurred during updating issue as paid.');
throw errors.handleGitLabError(err, 'Error occurred during updating issue as paid.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
}
logger.debug(`Gitlab issue is updated for as paid and fix accepted for ${issueId}`);
}
@@ -240,17 +256,18 @@ markIssueAsPaid.schema = {
/**
* change the state of gitlab issue
* @param {Object} copilot the copilot
* @param {string} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue issue id
* @param {string} state new state
*/
async function changeState(copilot, projectId, issueId, state) {
async function changeState(copilot, project, issueId, state) {
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, state}, changeState.schema);
const gitlab = await _authenticate(copilot.accessToken);
try {
await gitlab.projects.issues.edit(projectId, issueId, {state_event: state});
} catch (err) {
throw errors.convertGitLabError(err, 'Error occurred during updating status of issue.');
throw errors.handleGitLabError(err, 'Error occurred during updating status of issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
}
logger.debug(`Gitlab issue state is updated to '${state}' for issue number ${issueId}`);
}
@@ -265,17 +282,18 @@ changeState.schema = {
/**
* updates the gitlab issue with new labels
* @param {Object} copilot the copilot
* @param {string} projectId the project id
* @param {Object} project the project object
* @param {Number} issueId the issue issue id
* @param {Number} labels the labels
*/
async function addLabels(copilot, projectId, issueId, labels) {
async function addLabels(copilot, project, issueId, labels) {
const projectId = project.id;
Joi.attempt({copilot, projectId, issueId, labels}, addLabels.schema);
const gitlab = await _authenticate(copilot.accessToken);
try {
await gitlab.projects.issues.edit(projectId, issueId, {labels: _.join(labels, ',')});
} catch (err) {
throw errors.convertGitLabError(err, 'Error occurred during adding label in issue.');
throw errors.handleGitLabError(err, 'Error occurred during adding label in issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId));
}
logger.debug(`Gitlab issue is updated with new labels for ${issueId}`);
}
19 changes: 15 additions & 4 deletions utils/errors.js
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@

const _ = require('lodash');
const constants = require('../constants');
const notification = require('./notification');

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

/**
* Convert github api error.
* Handle github api error. Return converted error.
* @param {Error} err the github api error
* @param {String} message the error message
* @param {String} copilotHandle the handle name of the copilot
* @param {String} repoPath the link to related github page
* @returns {Error} converted error
*/
errors.convertGitHubError = function convertGitHubError(err, message) {
errors.handleGitHubError = function handleGitHubError(err, message, copilotHandle, repoPath) {
if (err.statusCode === 401 && copilotHandle && repoPath) { // eslint-disable-line no-magic-numbers
notification.sendTokenExpiredAlert(copilotHandle, repoPath, 'Github');
}
let resMsg = `${message}. ${err.message}.`;
const detail = _.get(err, 'response.body.message');
if (detail) {
@@ -47,12 +53,17 @@ errors.convertGitHubError = function convertGitHubError(err, message) {
};

/**
* Convert gitlab api error.
* Handle gitlab api error. Return converted error.
* @param {Error} err the gitlab api error
* @param {String} message the error message
* @param {String} copilotHandle the handle name of the copilot
* @param {String} repoPath the link to related gitlab page
* @returns {Error} converted error
*/
errors.convertGitLabError = function convertGitLabError(err, message) {
errors.handleGitLabError = function handleGitLabError(err, message, copilotHandle, repoPath) {
if (err.statusCode === 401 && copilotHandle && repoPath) { // eslint-disable-line no-magic-numbers
notification.sendTokenExpiredAlert(copilotHandle, repoPath, 'Gitlab');
}
let resMsg = `${message}. ${err.message}.`;
const detail = _.get(err, 'response.body.message');
if (detail) {
Loading