123 lines
4.3 KiB
JavaScript
123 lines
4.3 KiB
JavaScript
import _ from "underscore";
|
|
import express from "express";
|
|
import {MongoClient} from "mongodb";
|
|
|
|
let router = express.Router();
|
|
|
|
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');
|
|
// console.log("Connected to Mongodb server");
|
|
} catch(e) {
|
|
console.log("error: caught ping.js:31 in Data Collection.");
|
|
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) {
|
|
record.startTime = record.endTime = new Date().getTime();
|
|
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) {
|
|
console.log("error: caught ping.js:61 in Data Collection.");
|
|
console.log(queryResult.writeConcernError.errmsg + " ::: " + JSON.stringify(record));
|
|
}
|
|
}
|
|
|
|
async function updateRecord(record, isInternal, clientAddress) {
|
|
try {
|
|
if(!collection) {
|
|
await connect();
|
|
}
|
|
|
|
//Read record with given serial.
|
|
let existing = await collection.findOne({serial: record.serial, closed: {$exists: false}});
|
|
|
|
if(!existing) {
|
|
await createRecord(record, isInternal);
|
|
}
|
|
else {
|
|
//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);
|
|
}
|
|
else {
|
|
await collection.updateOne({_id: existing._id}, {$set: {endTime: new Date().getTime()}, $inc: {count: 1, internalCount: isInternal ? 1 : 0}});
|
|
}
|
|
}
|
|
} catch(e) {
|
|
console.log("Error in updateRecord(..):")
|
|
console.log(e);
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
//Note: We are not waiting for this to finish. We don't care about the output.
|
|
updateRecord({serial, assetId, deviceId, email}, isLocal, clientAddress);
|
|
}
|
|
|
|
//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');
|
|
});
|
|
|
|
export default router;
|