The 662-line handler (the largest in the file) split into one function per data-source/merge stage: facility+IX-location coordinate resolution (facilities.js), neighbour name-resolution + threat-intel enrichment (enrich-neighbours.js), RIR/country derivation cascade (rir-country.js), visibility/prefix-size computation (routing-info.js), multi-source cross-checks + data-quality scoring (cross-check.js), and a slim orchestrator (index.js) running Phase 0/1 fetch and final result assembly. Verified via node --check, eslint no-undef (2 known bugs remain: compare, webhooks), and smoke-test harness (28/28 match, including a byte-for-byte match on /api/lookup's own large response body -- the strongest possible confirmation this, the most complex handler in the file, was decomposed without changing behavior). server.js: 2917 -> 1734 lines (6838 originally -- 75% reduction so far).
115 lines
5.2 KiB
JavaScript
115 lines
5.2 KiB
JavaScript
const { fetchPeeringDB } = require("../../services/peeringdb");
|
|
const { CITY_COORDS } = require("../../data/city-coords");
|
|
const { IX_CITY_MAP } = require("../../data/ix-city-map");
|
|
|
|
// Batch-fetch facility lat/lon by ID, 25 per request (PeeringDB /fac?id__in= limit),
|
|
// bounded by an overall race timeout. Returns {fac_id: {lat, lon}}.
|
|
async function fetchFacCoordsBatch(facIds, timeoutMs) {
|
|
const coordMap = {};
|
|
if (facIds.length === 0) return coordMap;
|
|
try {
|
|
const chunks = [];
|
|
for (let i = 0; i < facIds.length; i += 25) chunks.push(facIds.slice(i, i + 25));
|
|
const coordResults = await Promise.race([
|
|
Promise.all(chunks.map(chunk =>
|
|
fetchPeeringDB("/fac?id__in=" + chunk.join(",") + "&fields=id,latitude,longitude").catch(() => null)
|
|
)),
|
|
new Promise(r => setTimeout(() => r([]), timeoutMs)),
|
|
]);
|
|
(coordResults || []).forEach(res => {
|
|
(res?.data || []).forEach(f => { if (f.latitude && f.longitude) coordMap[f.id] = { lat: f.latitude, lon: f.longitude }; });
|
|
});
|
|
} catch (e) { /* graceful degradation */ }
|
|
return coordMap;
|
|
}
|
|
|
|
// Resolve facility coordinates for the map, then IX locations via ixfac -> fac
|
|
// coordinates (max 20 IXs), then the name/CITY_COORDS/IX_CITY_MAP geocode
|
|
// fallbacks for IXs PeeringDB has no facility coordinates for.
|
|
async function resolveFacilitiesAndIxLocations(facilitiesRaw, ixConnections) {
|
|
// Batch-fetch facility coordinates for map (max 50 facilities)
|
|
const facIds = facilitiesRaw.map(f => f.fac_id).filter(Boolean).slice(0, 50);
|
|
let facCoordMap = await fetchFacCoordsBatch(facIds, 5000);
|
|
|
|
const facilities = facilitiesRaw.map(f => ({
|
|
...f,
|
|
latitude: facCoordMap[f.fac_id] ? facCoordMap[f.fac_id].lat : null,
|
|
longitude: facCoordMap[f.fac_id] ? facCoordMap[f.fac_id].lon : null,
|
|
}));
|
|
|
|
// Get IX locations for map via ixfac -> fac coordinates (max 20 IXs)
|
|
const uniqueIxIds = [...new Set(ixConnections.map(c => c.ix_id))].filter(Boolean).slice(0, 20);
|
|
let ixLocations = [];
|
|
if (uniqueIxIds.length > 0) {
|
|
try {
|
|
const ixFacData = await Promise.race([
|
|
fetchPeeringDB("/ixfac?ix_id__in=" + uniqueIxIds.join(",")),
|
|
new Promise(r => setTimeout(() => r(null), 5000)),
|
|
]);
|
|
const ixFacs = ixFacData?.data || [];
|
|
// Collect unique fac_ids we don't already have coords for
|
|
const extraFacIds = [...new Set(ixFacs.map(f => f.fac_id).filter(id => id && !facCoordMap[id]))].slice(0, 30);
|
|
if (extraFacIds.length > 0) {
|
|
const extraCoords = await fetchFacCoordsBatch(extraFacIds, 4000);
|
|
facCoordMap = { ...facCoordMap, ...extraCoords };
|
|
}
|
|
// Build IX locations: pick first facility with coords per IX
|
|
const ixNameMap = {};
|
|
ixConnections.forEach(c => { if (c.ix_id && c.ix_name) ixNameMap[c.ix_id] = c.ix_name; });
|
|
const seenIx = {};
|
|
ixFacs.forEach(f => {
|
|
if (seenIx[f.ix_id]) return;
|
|
const coords = facCoordMap[f.fac_id];
|
|
if (coords) {
|
|
seenIx[f.ix_id] = true;
|
|
ixLocations.push({ ix_id: f.ix_id, name: ixNameMap[f.ix_id] || f.name || "", city: f.city || "", country: f.country || "", latitude: coords.lat, longitude: coords.lon });
|
|
}
|
|
});
|
|
} catch (e) { /* graceful degradation */ }
|
|
}
|
|
|
|
applyIxGeocodeFallback(ixLocations, ixConnections);
|
|
|
|
return { facilities, ixLocations };
|
|
}
|
|
|
|
// === IX Location Geocode Fallback ===
|
|
// Some IXPs have no facility coordinates in PeeringDB.
|
|
// Use ix_name city extraction + hard-coded IX→city map as fallback.
|
|
// Mutates ixLocations in place (matches original control flow).
|
|
function applyIxGeocodeFallback(ixLocations, ixConnections) {
|
|
var ixIdsWithCoords = new Set(ixLocations.map(function(l) { return l.ix_id; }));
|
|
ixConnections.forEach(function(conn) {
|
|
if (ixIdsWithCoords.has(conn.ix_id)) return;
|
|
var name = conn.ix_name || "";
|
|
if (name) {
|
|
var words = name.toLowerCase().replace(/[^a-z\s]/g, " ").split(/\s+/).filter(Boolean);
|
|
for (var w = 0; w < words.length; w++) {
|
|
if (CITY_COORDS[words[w]]) {
|
|
ixLocations.push({ ix_id: conn.ix_id, name: name, city: words[w].charAt(0).toUpperCase() + words[w].slice(1), country: "", latitude: CITY_COORDS[words[w]][0], longitude: CITY_COORDS[words[w]][1], source: "name_geocode" });
|
|
ixIdsWithCoords.add(conn.ix_id);
|
|
return;
|
|
}
|
|
if (w < words.length - 1) {
|
|
var tw = words[w] + " " + words[w + 1];
|
|
if (CITY_COORDS[tw]) {
|
|
ixLocations.push({ ix_id: conn.ix_id, name: name, city: tw, country: "", latitude: CITY_COORDS[tw][0], longitude: CITY_COORDS[tw][1], source: "name_geocode" });
|
|
ixIdsWithCoords.add(conn.ix_id);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
// Hard-coded IX ID → city for well-known IXPs whose names don't contain city
|
|
ixConnections.forEach(function(conn) {
|
|
if (ixIdsWithCoords.has(conn.ix_id)) return;
|
|
var city = IX_CITY_MAP[conn.ix_id];
|
|
if (city && CITY_COORDS[city]) {
|
|
ixLocations.push({ ix_id: conn.ix_id, name: conn.ix_name || ("IX " + conn.ix_id), city: city.charAt(0).toUpperCase() + city.slice(1), country: "", latitude: CITY_COORDS[city][0], longitude: CITY_COORDS[city][1], source: "ix_city_map" });
|
|
}
|
|
});
|
|
}
|
|
|
|
module.exports = { resolveFacilitiesAndIxLocations };
|