2022-03-09 08:25:58 -08:00
let _ = require ( "underscore" ) ;
let express = require ( 'express' ) ;
let router = express . Router ( ) ;
const { MongoClient } = require ( "mongodb" ) ;
let localAddresses = process . env . LOCAL _ADDRESSES ; //eg: "10.18.,10.17."
// Create an array of local address beginnings. This is matched against the client addresses to determine if they are local. If not provided then all addresses are considered local.
if ( localAddresses ) localAddresses = localAddresses . split ( ',' ) ;
//const uri = "mongodb://test:1qaz2wsx@mongodb.avpanthers.org:27017/";
let uri = process . env . MONGO _URL ; //Read from the nginx sites-available file for this app.
//mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myRs
if ( ! uri ) {
uri = "mongodb://localhost/avusd_data_collection" ;
}
const client = new MongoClient ( uri ) ;
let collection ;
// We are keeping an in-memory set of current/active records for each Chromebook to reduce the number of reads without _id we perform.
// The idea is that each Chromebook pings every 5 minutes when a student is logged in and using the Chromebook.
// We note how long between the first and last use of each chromebook & user, and how many pings were recorded during that time period.
// This gives us an idea of who used it for any given time period, and roughly how much use it got.
// Prepare a database connection for use later.
async function connect ( ) {
try {
await client . connect ( ) ;
const database = client . db ( "avusd_data_collection" ) ;
collection = database . collection ( 'records' ) ;
2022-06-04 08:27:42 -07:00
// console.log("Connected to Mongodb server");
2022-03-09 08:25:58 -08:00
} catch ( e ) {
2022-06-04 08:27:42 -07:00
console . log ( "error: caught ping.js:31 in Data Collection." ) ;
2022-03-09 08:25:58 -08:00
console . log ( e ) ;
}
}
// Create a new record for a Chromebook & user. Set it in the cache (replace any existing one for that serial).
async function createRecord ( record , isInternal ) {
2022-06-04 08:27:42 -07:00
record . startTime = record . endTime = new Date ( ) . getTime ( ) ;
2022-03-09 08:25:58 -08:00
record . count = 1 ;
record . internalCount = isInternal ? 1 : 0 ;
//Write to db.
let queryResult = await collection . insertOne ( record ) ;
//Handle errors.
if ( queryResult . writeConcernError && queryResult . writeConcernError . errmsg ) {
2022-06-04 08:27:42 -07:00
console . log ( "error: caught ping.js:61 in Data Collection." ) ;
2022-03-09 08:25:58 -08:00
console . log ( queryResult . writeConcernError . errmsg + " ::: " + JSON . stringify ( record ) ) ;
}
}
async function updateRecord ( record , isInternal , clientAddress ) {
2022-06-04 08:27:42 -07:00
try {
if ( ! collection ) {
await connect ( ) ;
2022-03-09 08:25:58 -08:00
}
2022-06-04 08:27:42 -07:00
//Read record with given serial.
let existing = await collection . findOne ( { serial : record . serial , closed : { $exists : false } } ) ;
if ( ! existing ) {
2022-03-09 08:25:58 -08:00
await createRecord ( record , isInternal ) ;
}
else {
2022-06-04 08:27:42 -07:00
//If the user has changed, then close the record. Create a new record for the new user.
if ( existing . email !== record . email ) {
await collection . updateOne ( { _id : existing . _id } , { $set : { closed : true } } ) ;
await createRecord ( record , isInternal ) ;
2022-03-09 08:25:58 -08:00
}
2022-06-04 08:27:42 -07:00
else {
await collection . updateOne ( { _id : existing . _id } , { $set : { endTime : new Date ( ) . getTime ( ) } , $inc : { count : 1 , internalCount : isInternal ? 1 : 0 } } ) ;
2022-03-09 08:25:58 -08:00
}
}
2022-06-04 08:27:42 -07:00
} catch ( e ) {
console . log ( e ) ;
2022-03-09 08:25:58 -08:00
}
}
// Handle the client calling Ping.
router . get ( '/' , function ( req , res , next ) {
//Get the parameters.
const params = req . query ;
const email = params . email ;
const assetId = params . assetId ;
const serial = params . serial ;
const deviceId = params . deviceId ;
//DEBUG
// console.log("Email: " + params.email);
// console.log("AssetId: " + params.assetId);
// console.log("Serial: " + params.serial);
// console.log("DeviceId: " + params.deviceId);
2022-06-04 08:27:42 -07:00
// Ignore any calls without a serial.
if ( params . serial ) {
let clientAddress = req . header ( "X-Real-IP" ) ;
if ( ! clientAddress ) clientAddress = req . socket . remoteAddress ;
let isLocal = true ;
// console.log("Found IP: " + clientAddress);
if ( localAddresses ) {
isLocal = false ;
for ( let i = 0 ; ! isLocal && i < localAddresses . length ; i ++ ) {
let next = localAddresses [ i ] ;
isLocal = clientAddress . startsWith ( next ) ;
}
2022-03-09 08:25:58 -08:00
}
2022-06-04 08:27:42 -07:00
//Note: We are not waiting for this to finish. We don't care about the output.
updateRecord ( { serial , assetId , deviceId , email } , isLocal , clientAddress ) ;
}
2022-03-09 08:25:58 -08:00
//Send response. Nothing for the moment.
res . setHeader ( "Access-Control-Allow-Origin" , "*" ) ;
//res.setHeader("Content-Type", "application/json;charset=UTF8");
res . status ( 200 ) ;
res . end ( 'Pong' ) ;
} ) ;
module . exports = router ;