UNPKG

isatdatapro-microservices

Version:

A library for creating microservices to access Inmarsat's IsatData Pro satellite IoT system

131 lines (127 loc) 5 kB
/** * getForwardStatuses module * @module getForwardStatuses */ 'use strict'; const logger = require('../infra/logging').loggerProxy(__filename); const { getForwardStatuses } = require('isatdatapro-api'); const DatabaseContext = require('../infra/database/repositories'); const { getMailboxes, getMailboxGateway, getHighwatermark, handleApiResponse, handleApiFailure } = require('../infra/database/utilities'); const { ApiCallLog, MessageForward } = require('../infra/database/models'); const event = require('../infra/eventHandler'); /** * Retrieves all outstanding forward message statuses from all Mailboxes. * * Emits events: * * ``ForwardMessageStateChange`` * * ``OtherClientForwardSubmission`` * * ``ApiError`` * * ``ApiOutage`` * * ``ApiRecovery`` */ module.exports = async function() { const thisFunction = {name: logger.getModuleName(__filename)}; logger.debug(`>>>> ${thisFunction.name} entry`); const database = new DatabaseContext(); await database.initialize(); /** * Retrieves Forward message statuses using high water mark * @private * @param {Mailbox} mailbox The mailbox entity to query * @param {object} [filter] Optional filter parameters */ async function getStatuses(mailbox, filter) { const operation = 'getForwardStatuses'; const idpGateway = await getMailboxGateway(database, mailbox); const auth = { accessId: mailbox.accessId, password: mailbox.passwordGet(), }; if (!filter) { filter = await getHighwatermark(database, mailbox.mailboxId, operation); } const callTimeUtc = new Date().toISOString(); let moreToRetrieve; const apiCallLog = new ApiCallLog(operation, idpGateway.name, mailbox.mailboxId, callTimeUtc); await Promise.resolve(getForwardStatuses(auth, filter, idpGateway.url)) .then(async function (result) { const success = await handleApiResponse(database, result.errorId, apiCallLog, idpGateway); if (success) { apiCallLog.nextStartTimeUtc = result.nextStartTimeUtc; if (result.statuses) { logger.debug(`Retrieved ${result.statuses.length} statuses` + ` for mailbox ${mailbox.mailboxId}`); apiCallLog.messageCount = result.statuses.length; for (let s=0; s < result.statuses.length; s++) { const status = result.statuses[s]; let message = new MessageForward(); await message.fromApi(status); message.updateStatus(status); message.mailboxId = mailbox.mailboxId; const filterMessage = { messageId: message.messageId }; const { changeList, created } = await database.upsert(message, filterMessage); if (!created) { logger.debug(`State change list: ${JSON.stringify(changeList)}`); //TODO: may be a smarter way to avoid the second database read const findMessage = await database.find(message.category, filterMessage); if (findMessage.length > 0) { message = findMessage[0]; } if (changeList && 'state' in changeList) { const newState = message.getStateName(); const newStateReason = message.getStateReason(); logger.info(`Message ${message.messageId}` + ` ${newState} ${newStateReason}`); event.forwardMessageStateChange(message.messageId, newState, newStateReason, message.stateTimeUtc, message.mobileId, message.referenceNumber); } } else { // implies that another API client submitted, trigger event that can get the submission logger.warn(`New Forward message ${message.messageId} from` + ` unknown IDP API client on mailbox ${message.mailboxId}`); event.otherClientForwardSubmission(message.messageId, message.mailboxId); } } if (result.more) { moreToRetrieve = { startMessageId: result.nextStartId }; } } else { logger.debug(`No Statuses to retrieve` + ` from Mailbox ${mailbox.mailboxId}`); } } }) .catch(async function (err) { let apiOutage = await handleApiFailure(database, err, idpGateway, operation); if (!apiOutage) { logger.error(err.stack); throw err; } }); await database.upsert(apiCallLog); if (moreToRetrieve) { getStatuses(mailbox, moreToRetrieve); } } try { const mailboxes = await getMailboxes(database); for (let m=0; m < mailboxes.length; m++) { let activeMailbox = mailboxes[m]; await getStatuses(activeMailbox); } } catch (err) { logger.error(err.stack); throw err; } finally { await database.close(); logger.debug(`<<<< ${thisFunction.name} exit`); } }