-
Notifications
You must be signed in to change notification settings - Fork 114
Expand file tree
/
Copy pathpopulate.js
More file actions
155 lines (133 loc) · 4.8 KB
/
populate.js
File metadata and controls
155 lines (133 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* used to populate or re-populate a MongoDB-compatible document
* database with static fixtures at `cve-services/datadump/pre-population`
*/
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const dataUtils = require('../utils/data')
const dbUtils = require('../utils/db')
const errors = require('../utils/error')
const logger = require('../middleware/logger')
const CveIdRange = require('../model/cve-id-range')
const CveId = require('../model/cve-id')
const Cve = require('../model/cve')
const Org = require('../model/org')
const User = require('../model/user')
const BaseOrg = require('../model/baseorg')
const BaseUser = require('../model/baseuser')
const ReviewObject = require('../model/reviewobject')
const Conversation = require('../model/conversation')
const Audit = require('../model/audit')
const error = new errors.IDRError()
const populateTheseCollections = {
Cve: Cve,
'Cve-Id-Range': CveIdRange,
'Cve-Id': CveId,
User: User,
Org: Org,
BaseOrg: BaseOrg,
BaseUser: BaseUser,
ReviewObject: ReviewObject,
Conversation: Conversation,
Audit: Audit
}
const indexesToCreate = {
Cve: [{ 'cve.cveMetadata.cveId': 1 }, { 'cve.cveMetadata.dateUpdated': 1 }],
'Cve-Id': [{ cve_id: 1 }, { owning_cna: 1, state: 1 }, { reserved: 1 }],
User: [{ UUID: 1 }],
Org: [{ UUID: 1 }, { 'authority.active_roles': 1 }]
}
// Body Parser Middleware
app.use(express.json()) // Allows us to handle raw JSON data
app.use(express.urlencoded({ extended: false })) // Allows us to handle url encoded data
// Make mongoose connection available globally
global.mongoose = mongoose
// Connect to MongoDB database
const dbConnectionStr = dbUtils.getMongoConnectionString()
mongoose.connect(dbConnectionStr, {
useNewUrlParser: true,
useUnifiedTopology: false,
autoIndex: false
})
console.log('About to test connection')
const db = mongoose.connection
db.on('error', () => {
console.error.bind(console, 'Connection Error: Something went wrong!')
logger.error(error.connectionError())
})
db.once('open', async () => {
logger.info('Successfully connected to database!')
let userInput
if (process.argv.length > 2 && process.argv.slice(2)[0] === 'y') {
userInput = process.argv.slice(2)[0]
} else {
// script runner (currently) needs to agree to an action that drops collections
userInput = dataUtils.getUserPopulateInput(Object.keys(populateTheseCollections))
}
// drops and re-populates collections
if (userInput.toLowerCase() === 'y') {
const collections = await db.db.listCollections().toArray()
for (const collection of collections) {
if (!collection.name.startsWith('system.')) {
logger.info(`Dropping ${collection.name} collection !!!`)
await db.dropCollection(collection.name)
}
}
// Org
await dataUtils.populateCollection(
'./datadump/pre-population/orgs.json',
Org, dataUtils.newOrgTransform
)
// User, depends on Org
const hash = await dataUtils.preprocessUserSecrets()
await dataUtils.populateCollection(
'./datadump/pre-population/users.json',
User, dataUtils.newUserTransform, hash
)
const populatePromises = []
// CVE ID Range
populatePromises.push(dataUtils.populateCollection(
'./datadump/pre-population/cve-ids-range.json',
CveIdRange
))
// CVE
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
populatePromises.push(dataUtils.populateCollection(
'./datadump/pre-population/cves.json',
Cve, dataUtils.newCveTransform
))
}
// CVE ID, depends on User and Org
populatePromises.push(dataUtils.populateCollection(
'./datadump/pre-population/cve-ids.json',
CveId, dataUtils.newCveIdTransform
))
// don't close database connection until all remaining populate
// promises are resolved
Promise.all(populatePromises).then(async function () {
logger.info('Successfully populated the database!')
const indexPromises = []
Object.keys(indexesToCreate).forEach(col => {
indexesToCreate[col].forEach(index => {
indexPromises.push(db.collections[col].createIndex(index))
})
})
try {
await Promise.all(indexPromises)
logger.info('Successfully created indexes!')
// Explicitly create collections for models that are not pre-populated but require transactions.
// Implicit collection creation inside Mongo transactions acquires heavy locks and leads to LockTimeout.
await Audit.createCollection()
await ReviewObject.createCollection()
await Conversation.createCollection()
} catch (err) {
logger.error('Error creating indexes:', err)
} finally {
mongoose.connection.close()
}
})
} else {
mongoose.connection.close()
}
})