219 lines
6.1 KiB
JavaScript
219 lines
6.1 KiB
JavaScript
// Parse and return an LDB Request
|
|
|
|
const ldb = require("ldbs-json");
|
|
const util = require("../utils/ldb.utils");
|
|
const san = require("../utils/sanitizer.utils");
|
|
const db = require("../services/dbAccess.services");
|
|
|
|
import { findStationsByDistancePipeline } from "../utils/ldbPipeline.utils";
|
|
import { logger } from "../utils/logger.utils";
|
|
|
|
import { transform as staffStationTransform } from "../utils/processors/ldb/staffStation";
|
|
|
|
|
|
const ldbKey = process.env.OWL_LDB_KEY;
|
|
const ldbsvKey = process.env.OWL_LDB_SVKEY;
|
|
|
|
async function get(id, staff = false) {
|
|
const cleanId = san.cleanApiEndpointTxt(id);
|
|
const obj = await util.checkCrs(cleanId);
|
|
try {
|
|
const crs = obj[0]["3ALPHA"];
|
|
logger.debug(`ldbService.get: Determined CRS for lookup to be: ${crs}`);
|
|
if (staff) {
|
|
const data = arrDepBoardStaff(crs);
|
|
db.increment("ldbsvws");
|
|
return await data;
|
|
} else {
|
|
const data = arrDepBoard(crs);
|
|
db.increment("ldbws");
|
|
return await data;
|
|
}
|
|
} catch (err) {
|
|
logger.error(err, "ldbService.get: Error, Unable to find CRS");
|
|
return {
|
|
obStatus: "LOC_NOT_FOUND",
|
|
obMsg: "Location is not available",
|
|
};
|
|
}
|
|
}
|
|
|
|
async function arrDepBoard(CRS) {
|
|
logger.trace(`ldbService.arrDepBoard: Trying to fetch board for ${CRS}`);
|
|
try {
|
|
const options = {
|
|
numRows: 10,
|
|
crs: CRS.toUpperCase(),
|
|
};
|
|
const api = new ldb(ldbKey, false);
|
|
let d = await api.call("GetArrDepBoardWithDetails", options, false, false);
|
|
return await util.cleanData(d);
|
|
} catch (err) {
|
|
logger.error(err, "ldbService.arrDepBoard: Lookup Failed");
|
|
return {
|
|
GetStationBoardResult: "not available",
|
|
Reason: `The CRS code ${CRS} is not valid`,
|
|
};
|
|
}
|
|
}
|
|
|
|
async function arrDepBoardStaff(CRS) {
|
|
logger.debug(`ldbService.arrDepBoardStaff: Try to fetch board for ${CRS}`);
|
|
try {
|
|
const options = {
|
|
numRows: 40,
|
|
crs: CRS.toUpperCase(),
|
|
getNonPassengerServices: true,
|
|
time: await getDateTimeString(new Date()),
|
|
timeWindow: 120,
|
|
services: "PBS",
|
|
};
|
|
const api = new ldb(ldbsvKey, true);
|
|
console.time(`Fetch Staff LDB for ${CRS.toUpperCase()}`);
|
|
let result
|
|
try {
|
|
result = await staffApiCallRetry(
|
|
api,
|
|
"GetArrivalDepartureBoardByCRS",
|
|
options,
|
|
5,
|
|
);
|
|
} catch (err) {
|
|
logger.error(err, "Error fetching board data");
|
|
return {obStatus: "Error", obMsg: "Error fetching data from National Rail", data: null}
|
|
}
|
|
console.timeEnd(`Fetch Staff LDB for ${CRS.toUpperCase()}`);
|
|
try {
|
|
const _staffLdb = staffStationTransform(result);
|
|
logger.debug("StaffLDB Transformed");
|
|
logger.trace(_staffLdb, "StaffLDB Transformed");
|
|
return {
|
|
obStatus: "OK",
|
|
obMsg: "OK",
|
|
data: _staffLdb,
|
|
};
|
|
} catch (err) {
|
|
logger.error(err, "Transformation Error");
|
|
}
|
|
return result;
|
|
} catch (err) {
|
|
logger.error(err, "ldbService.arrDepBoardStaff error");
|
|
return {
|
|
GetStationBoardResult: "not available",
|
|
Reason: `The CRS code ${CRS} is not valid`,
|
|
};
|
|
}
|
|
}
|
|
|
|
async function getServiceByRID(rid) {
|
|
logger.debug(`ldbService.getServiceByRID: Finding RID: ${rid}`);
|
|
try {
|
|
const options = {
|
|
rid: String(rid),
|
|
};
|
|
const api = new ldb(ldbsvKey, true);
|
|
return await api.call("GetServiceDetailsByRID", options, false, false);
|
|
} catch (err) {
|
|
logger.error(err, `ldbService.queryService`);
|
|
}
|
|
}
|
|
|
|
async function getServicesByOther(id) {
|
|
logger.debug(`ldbService.getServiceByOther: Finding services: ${id}`);
|
|
try {
|
|
const options = {
|
|
serviceID: id,
|
|
sdd: getDateString(new Date()),
|
|
};
|
|
const api = new ldb(ldbsvKey, true);
|
|
return await api.call("QueryServices", options, false, false);
|
|
} catch (err) {
|
|
logger.error(err, "ldbService.getServiceByOther");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function staffApiCallRetry(api, method, options, retries) {
|
|
for (let i=0; i < retries; i++) {
|
|
try {
|
|
return await api.call(method, options, false, false);
|
|
} catch (err) {
|
|
if (err.code === 'ENOTFOUND') {
|
|
logger.warn(err, "DNS ERR")
|
|
if (i < retries - 1) {
|
|
logger.debug('Retrying API Call')
|
|
await delay(500)
|
|
continue;
|
|
}
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
throw new Error("Max retries exceeded");
|
|
}
|
|
|
|
function delay(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
async function getReasonCodeList() {
|
|
logger.debug("ldbService.getReasonCodeList: Fetching reason code list");
|
|
try {
|
|
const dbFilter = {};
|
|
return await db.query("reasonCodes", dbFilter, false);
|
|
} catch (err) {
|
|
logger.error(err, "ldbService.getReasonCodeList");
|
|
}
|
|
}
|
|
|
|
async function getReasonCode(code) {
|
|
logger.debug(`ldbService.getReasonCode: Fetching reason code ${code}`);
|
|
try {
|
|
const dbFilter = {
|
|
code: code,
|
|
};
|
|
return await db.query("reasonCodes", dbFilter, false);
|
|
} catch (err) {
|
|
logger.error(err, "ldbService.getReasonCode");
|
|
}
|
|
}
|
|
|
|
async function getNearestStations(lat, long) {
|
|
|
|
logger.debug(`ldbService.getNearestStations: Fetching nearest stations`)
|
|
let pipeline = findStationsByDistancePipeline(4, lat, long)
|
|
try {
|
|
return await db.queryAggregate("stations", pipeline)
|
|
} catch (err) {
|
|
logger.error(err, `ldbService.getNearestStations`)
|
|
}
|
|
}
|
|
|
|
async function getDateTimeString(date) {
|
|
const year = date.getFullYear(),
|
|
month = String(date.getMonth() + 1).padStart(2, "0"),
|
|
day = String(date.getDate()).padStart(2, "0"),
|
|
hour = String(date.getHours()).padStart(2, "0"),
|
|
minute = String(date.getMinutes()).padStart(2, "0"),
|
|
second = String(date.getSeconds()).padStart(2, "0");
|
|
const format = `${year}-${month}-${day}T${hour}:${minute}:${second}`;
|
|
return format;
|
|
}
|
|
|
|
async function getDateString(date) {
|
|
const year = date.getFullYear(),
|
|
month = String(date.getMonth() + 1).padStart(2, "0"),
|
|
day = String(date.getDate()).padStart(2, "0");
|
|
const format = `${year}-${month}-${day}`;
|
|
return format;
|
|
}
|
|
|
|
module.exports = {
|
|
get,
|
|
getServiceByRID,
|
|
getServicesByOther,
|
|
getReasonCodeList,
|
|
getReasonCode,
|
|
getNearestStations,
|
|
};
|