189 lines
4.9 KiB
JavaScript
189 lines
4.9 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const DEFAULT_AGHEERA_PUSH_URL = 'https://push-dhl.agheera.com/Telematics/positions';
|
|
const DEFAULT_AGHEERA_PUSH_LOG_PATH = '/var/log/agheera_push.log';
|
|
|
|
let httpClientOverride = null;
|
|
|
|
const getPushUrl = () =>
|
|
String(process.env.AGHEERA_PUSH_URL || DEFAULT_AGHEERA_PUSH_URL).trim();
|
|
|
|
const getApiKey = () =>
|
|
String(process.env.AGHEERA_API_KEY || '').trim();
|
|
|
|
const getPushLogPath = () =>
|
|
String(process.env.AGHEERA_PUSH_LOG_PATH || DEFAULT_AGHEERA_PUSH_LOG_PATH).trim();
|
|
|
|
const appendPushLog = async ({ metadata, url, payload, success, status, responseBody, error }) => {
|
|
if (process.env.AGHEERA_PUSH_LOGS === '0') {
|
|
return;
|
|
}
|
|
|
|
const firstVehicle = Array.isArray(payload?.Vehicles) ? payload.Vehicles[0] : null;
|
|
const entry = {
|
|
timestamp: new Date().toISOString(),
|
|
...(metadata || {}),
|
|
url,
|
|
vehicleId: firstVehicle?.vehicleId ?? null,
|
|
licensePlate: firstVehicle?.licensePlate ?? null,
|
|
latitude: firstVehicle?.latitude ?? null,
|
|
longitude: firstVehicle?.longitude ?? null,
|
|
measurementTime: firstVehicle?.measurementTime ?? null,
|
|
payload,
|
|
success,
|
|
http_status: status ?? null,
|
|
response_body: responseBody || '',
|
|
error: error || null
|
|
};
|
|
|
|
try {
|
|
const logPath = getPushLogPath();
|
|
await fs.promises.mkdir(path.dirname(logPath), { recursive: true });
|
|
await fs.promises.appendFile(logPath, `${JSON.stringify(entry)}
|
|
`);
|
|
} catch (logError) {
|
|
console.error('Failed to append Agheera push log:', { message: logError.message });
|
|
}
|
|
};
|
|
|
|
const formatMeasurementTime = (dateValue) => {
|
|
const date = dateValue instanceof Date ? dateValue : new Date(dateValue);
|
|
return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
};
|
|
|
|
const normalizeNumber = (rawValue) => {
|
|
const numericValue = Number(rawValue);
|
|
return Number.isFinite(numericValue) ? numericValue : null;
|
|
};
|
|
|
|
const getHttpClient = () => {
|
|
if (typeof httpClientOverride === 'function') {
|
|
return httpClientOverride;
|
|
}
|
|
|
|
if (typeof fetch === 'function') {
|
|
return fetch;
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
const buildPositionPayload = ({
|
|
latitude,
|
|
longitude,
|
|
vehicleId,
|
|
licensePlate,
|
|
measurementTime
|
|
}) => ({
|
|
Vehicles: [
|
|
{
|
|
latitude: normalizeNumber(latitude),
|
|
longitude: normalizeNumber(longitude),
|
|
vehicleId: String(vehicleId || '').trim(),
|
|
licensePlate: String(licensePlate || '').trim(),
|
|
measurementTime: formatMeasurementTime(measurementTime)
|
|
}
|
|
]
|
|
});
|
|
|
|
const pushPosition = async ({
|
|
latitude,
|
|
longitude,
|
|
vehicleId,
|
|
licensePlate,
|
|
measurementTime,
|
|
metadata
|
|
}) => {
|
|
const url = getPushUrl();
|
|
const payload = buildPositionPayload({
|
|
latitude,
|
|
longitude,
|
|
vehicleId,
|
|
licensePlate,
|
|
measurementTime
|
|
});
|
|
|
|
const httpClient = getHttpClient();
|
|
if (!httpClient) {
|
|
const message = 'Agheera HTTP client unavailable';
|
|
await appendPushLog({ metadata, url, payload, success: false, error: message });
|
|
throw new Error(message);
|
|
}
|
|
|
|
const apiKey = getApiKey();
|
|
if (!apiKey) {
|
|
const message = 'Agheera API key missing';
|
|
await appendPushLog({ metadata, url, payload, success: false, error: message });
|
|
throw new Error(message);
|
|
}
|
|
|
|
let response;
|
|
try {
|
|
response = await httpClient(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
apiKey,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(payload)
|
|
});
|
|
} catch (error) {
|
|
await appendPushLog({
|
|
metadata,
|
|
url,
|
|
payload,
|
|
success: false,
|
|
error: error.message
|
|
});
|
|
throw error;
|
|
}
|
|
|
|
const responseBody = typeof response?.text === 'function' ? await response.text() : '';
|
|
if (!response?.ok) {
|
|
const error = new Error('Agheera push failed');
|
|
error.status = response?.status || null;
|
|
error.body = responseBody;
|
|
await appendPushLog({
|
|
metadata,
|
|
url,
|
|
payload,
|
|
success: false,
|
|
status: error.status,
|
|
responseBody,
|
|
error: error.message
|
|
});
|
|
throw error;
|
|
}
|
|
|
|
await appendPushLog({
|
|
metadata,
|
|
url,
|
|
payload,
|
|
success: true,
|
|
status: response.status,
|
|
responseBody
|
|
});
|
|
|
|
return {
|
|
status: response.status,
|
|
body: responseBody
|
|
};
|
|
};
|
|
|
|
const __setHttpClientForTests = (httpClient) => {
|
|
httpClientOverride = httpClient;
|
|
};
|
|
|
|
const __resetHttpClientForTests = () => {
|
|
httpClientOverride = null;
|
|
};
|
|
|
|
module.exports = {
|
|
DEFAULT_AGHEERA_PUSH_URL,
|
|
DEFAULT_AGHEERA_PUSH_LOG_PATH,
|
|
pushPosition,
|
|
__setHttpClientForTests,
|
|
__resetHttpClientForTests
|
|
};
|