diff --git a/src/adapters/localdb/index.js b/src/adapters/localdb/index.js index be6b2cf..7fd6ead 100644 --- a/src/adapters/localdb/index.js +++ b/src/adapters/localdb/index.js @@ -4,11 +4,13 @@ // Load Mongoose models. import Users from './models/users.js' +import Usage from './models/usage.js' class LocalDB { constructor () { // Encapsulate dependencies this.Users = Users + this.Usage = Usage } } diff --git a/src/adapters/localdb/models/usage.js b/src/adapters/localdb/models/usage.js new file mode 100644 index 0000000..9dec059 --- /dev/null +++ b/src/adapters/localdb/models/usage.js @@ -0,0 +1,15 @@ +/* + Usage data model +*/ + +// Global npm libraries +import mongoose from 'mongoose' + +const Usage = new mongoose.Schema({ + ip: { type: String }, + url: { type: String }, + method: { type: String }, + timestamp: { type: Date } +}) + +export default mongoose.model('usage', Usage) diff --git a/src/use-cases/usage-use-cases.js b/src/use-cases/usage-use-cases.js index ce32f24..d177005 100644 --- a/src/use-cases/usage-use-cases.js +++ b/src/use-cases/usage-use-cases.js @@ -3,6 +3,10 @@ for tracking the usage of REST API and JSON RPC calls. This library is used by admins to keep an eye on how many API calls were made in a 24-hour and 1-hour time period. + + Usage stats are held in memory. But they are periodically backed up to the + Mongo database. On startup, the usage stats are loaded from the database. + This allows the usage stats to be persisted across restarts. */ // This global variable is used to share data between the REST middleware and @@ -24,6 +28,9 @@ class UsageUseCases { this.getRestSummary = this.getRestSummary.bind(this) this.getTopIps = this.getTopIps.bind(this) this.getTopEndpoints = this.getTopEndpoints.bind(this) + this.clearUsage = this.clearUsage.bind(this) + this.saveUsage = this.saveUsage.bind(this) + this.loadUsage = this.loadUsage.bind(this) // State } @@ -108,6 +115,58 @@ class UsageUseCases { throw err } } + + // Clear the usage database data + async clearUsage () { + try { + await this.adapters.Usage.deleteMany({}) + + // Debugging: verify the database is empty + // Delete this code after debugging + const usage = await this.adapters.Usage.find({}) + console.log('usage: ', usage) + } catch (err) { + console.error('Error in usage-use-cases.js/clearUsage()') + throw err + } + } + + // Save the usage data to the database + async saveUsage (inObj = {}) { + try { + for (let i = 0; i < restCalls.length; i++) { + const thisRestCall = restCalls[i] + + // Debugging: delete this code after debugging + if (i === 5) { + console.log('saveUsage() thisRestCall: ', thisRestCall) + } + + const usage = new this.UsageModel(thisRestCall) + await usage.save() + } + } catch (err) { + console.error('Error in usage-use-cases.js/saveUsage()') + throw err + } + } + + // Load usage data from the database + async loadUsage () { + try { + const usage = await this.adapters.Usage.find({}) + // console.log('usage: ', usage) + + if (usage[5]) { + console.log('loadUsage() usage[5]: ', usage[5]) + } + + restCalls = usage + } catch (err) { + console.error('Error in usage-use-cases.js/loadUsage()') + throw err + } + } } // This Koa middleware is called any time there is a REST API. It logs the