diff --git a/src/routes/projectMemberInvites/create.js b/src/routes/projectMemberInvites/create.js index 9d19f410..5187b9b9 100644 --- a/src/routes/projectMemberInvites/create.js +++ b/src/routes/projectMemberInvites/create.js @@ -80,7 +80,7 @@ const buildCreateInvitePromises = (req, invite, invites, data, failed) => { if (invite.emails) { // if for some emails there are already existent users, we will invite them by userId, // to avoid sending them registration email - return util.lookupUserEmails(req, invite.emails) + return util.lookupMultipleUserEmails(req, invite.emails, 5) .then((existentUsers) => { // existent user we will invite by userId and email const existentUsersWithNumberId = existentUsers.map((user) => { diff --git a/src/routes/projectMemberInvites/create.spec.js b/src/routes/projectMemberInvites/create.spec.js index 90ff16a7..7b958266 100644 --- a/src/routes/projectMemberInvites/create.spec.js +++ b/src/routes/projectMemberInvites/create.spec.js @@ -147,9 +147,9 @@ describe('Project Member Invite create', () => { server.services.pubsub.publish.restore(); sinon.stub(server.services.pubsub, 'init', () => {}); sinon.stub(server.services.pubsub, 'publish', () => {}); - // by default mock lookupUserEmails return nothing so all the cases are not broken + // by default mock lookupMultipleUserEmails return nothing so all the cases are not broken sandbox.stub(util, 'getUserRoles', () => Promise.resolve([])); - sandbox.stub(util, 'lookupUserEmails', () => Promise.resolve([])); + sandbox.stub(util, 'lookupMultipleUserEmails', () => Promise.resolve([])); sandbox.stub(util, 'getMemberDetailsByUserIds', () => Promise.resolve([{ userId: 40051333, firstName: 'Admin', @@ -366,8 +366,8 @@ describe('Project Member Invite create', () => { }), }); sandbox.stub(util, 'getHttpClient', () => mockHttpClient); - util.lookupUserEmails.restore(); - sandbox.stub(util, 'lookupUserEmails', () => Promise.resolve([{ + util.lookupMultipleUserEmails.restore(); + sandbox.stub(util, 'lookupMultipleUserEmails', () => Promise.resolve([{ id: '12345', email: 'hello@world.com', }])); diff --git a/src/util.js b/src/util.js index 46cd75b2..2f3d1109 100644 --- a/src/util.js +++ b/src/util.js @@ -463,6 +463,68 @@ _.assignIn(util, { }); }, + /** + * Lookup user handles from multiple emails + * @param {Object} req request + * @param {Array} userEmails user emails + * @param {Number} maximumRequests limit number of request on one batch + * @param {Boolean} isPattern flag to indicate that pattern matching is required or not + * @return {Promise} promise + */ + lookupMultipleUserEmails(req, userEmails, maximumRequests, isPattern = false) { + req.log.debug(`identityServiceEndpoint: ${config.get('identityServiceEndpoint')}`); + + const httpClient = util.getHttpClient({ id: req.id, log: req.log }); + // request generator function + const generateRequest = ({ token, email }) => { + let filter = `email=${email}`; + if (isPattern) { + filter += '&like=true'; + } + return httpClient.get(`${config.get('identityServiceEndpoint')}users`, { + headers: { + Authorization: `Bearer ${token}`, + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + params: { + fields: 'handle,id,email', + filter, + }, + // set longer timeout as default 3000 could be not enough for identity service response + timeout: 15000, + }); + }; + // send batch of requests, one batch at one time + const sendBatch = (options) => { + const token = options.token; + const emails = options.emails; + const users = options.users || []; + const batch = options.batch || 0; + const start = batch * maximumRequests; + const end = (batch + 1) * maximumRequests; + const requests = emails.slice(start, end).map(userEmail => + generateRequest({ token, email: userEmail })); + return Promise.all(requests) + .then((responses) => { + const data = responses.reduce((contents, response) => { + const content = _.get(response, 'data.result.content', []); + return _.concat(contents, content); + }, users); + req.log.debug(`UserHandle response batch-${batch}`, data); + if (end < emails.length) { + return sendBatch({ token, users: data, emails, batch: batch + 1 }); + } + return data; + }); + }; + return util.getM2MToken() + .then((m2mToken) => { + req.log.debug(`Bearer ${m2mToken}`); + return sendBatch({ token: m2mToken, emails: userEmails }); + }); + }, + /** * Filter only members of topcoder team * @param {Array} members project members