Skip to content

Commit cb621ba

Browse files
committed
Move command extraction logic to utils
1 parent a16ce4b commit cb621ba

File tree

2 files changed

+126
-114
lines changed

2 files changed

+126
-114
lines changed

lib/command_utils.js

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
'use strict';
2+
const Msg = require('./core/connection/msg').Msg;
3+
const KillCursor = require('./core/connection/commands').KillCursor;
4+
const GetMore = require('./core/connection/commands').GetMore;
5+
6+
/** Commands that we want to redact because of the sensitive nature of their contents */
7+
const SENSITIVE_COMMANDS = new Set([
8+
'authenticate',
9+
'saslStart',
10+
'saslContinue',
11+
'getnonce',
12+
'createUser',
13+
'updateUser',
14+
'copydbgetnonce',
15+
'copydbsaslstart',
16+
'copydb'
17+
]);
18+
19+
const HELLO_COMMANDS = new Set(['hello', 'ismaster', 'isMaster']);
20+
21+
const LEGACY_FIND_QUERY_MAP = {
22+
$query: 'filter',
23+
$orderby: 'sort',
24+
$hint: 'hint',
25+
$comment: 'comment',
26+
$maxScan: 'maxScan',
27+
$max: 'max',
28+
$min: 'min',
29+
$returnKey: 'returnKey',
30+
$showDiskLoc: 'showRecordId',
31+
$maxTimeMS: 'maxTimeMS',
32+
$snapshot: 'snapshot'
33+
};
34+
35+
const LEGACY_FIND_OPTIONS_MAP = {
36+
numberToSkip: 'skip',
37+
numberToReturn: 'batchSize',
38+
returnFieldsSelector: 'projection'
39+
};
40+
41+
const OP_QUERY_KEYS = [
42+
'tailable',
43+
'oplogReplay',
44+
'noCursorTimeout',
45+
'awaitData',
46+
'partial',
47+
'exhaust'
48+
];
49+
50+
const collectionName = command => command.ns.split('.')[1];
51+
52+
const shouldRedactCommand = (commandName, cmd) =>
53+
SENSITIVE_COMMANDS.has(commandName) ||
54+
(HELLO_COMMANDS.has(commandName) && !!cmd.speculativeAuthenticate);
55+
56+
/**
57+
* Extract the actual command from the query, possibly upconverting if it's a legacy
58+
* format
59+
*
60+
* @param {Object} command the command
61+
*/
62+
const extractCommand = command => {
63+
let extractedCommand;
64+
if (command instanceof GetMore) {
65+
extractedCommand = {
66+
getMore: command.cursorId,
67+
collection: collectionName(command),
68+
batchSize: command.numberToReturn
69+
};
70+
} else if (command instanceof KillCursor) {
71+
extractedCommand = {
72+
killCursors: collectionName(command),
73+
cursors: command.cursorIds
74+
};
75+
} else if (command instanceof Msg) {
76+
extractedCommand = command.command;
77+
} else if (command.query && command.query.$query) {
78+
let result;
79+
if (command.ns === 'admin.$cmd') {
80+
// upconvert legacy command
81+
result = Object.assign({}, command.query.$query);
82+
} else {
83+
// upconvert legacy find command
84+
result = { find: collectionName(command) };
85+
Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
86+
if (typeof command.query[key] !== 'undefined')
87+
result[LEGACY_FIND_QUERY_MAP[key]] = command.query[key];
88+
});
89+
}
90+
91+
Object.keys(LEGACY_FIND_OPTIONS_MAP).forEach(key => {
92+
if (typeof command[key] !== 'undefined') result[LEGACY_FIND_OPTIONS_MAP[key]] = command[key];
93+
});
94+
95+
OP_QUERY_KEYS.forEach(key => {
96+
if (command[key]) result[key] = command[key];
97+
});
98+
99+
if (typeof command.pre32Limit !== 'undefined') {
100+
result.limit = command.pre32Limit;
101+
}
102+
103+
if (command.query.$explain) {
104+
extractedCommand = { explain: result };
105+
} else {
106+
extractedCommand = result;
107+
}
108+
} else {
109+
extractedCommand = command.query || command;
110+
}
111+
112+
const commandName = Object.keys(extractedCommand)[0];
113+
return {
114+
cmd: extractedCommand,
115+
name: commandName,
116+
shouldRedact: shouldRedactCommand(commandName, extractedCommand)
117+
};
118+
};
119+
120+
module.exports = {
121+
extractCommand
122+
};

lib/core/connection/apm.js

+4-114
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,16 @@
11
'use strict';
2-
const Msg = require('../connection/msg').Msg;
32
const KillCursor = require('../connection/commands').KillCursor;
43
const GetMore = require('../connection/commands').GetMore;
54
const calculateDurationInMs = require('../../utils').calculateDurationInMs;
6-
7-
/** Commands that we want to redact because of the sensitive nature of their contents */
8-
const SENSITIVE_COMMANDS = new Set([
9-
'authenticate',
10-
'saslStart',
11-
'saslContinue',
12-
'getnonce',
13-
'createUser',
14-
'updateUser',
15-
'copydbgetnonce',
16-
'copydbsaslstart',
17-
'copydb'
18-
]);
19-
20-
const HELLO_COMMANDS = new Set(['hello', 'ismaster', 'isMaster']);
5+
const extractCommand = require('../../command_utils').extractCommand;
216

227
// helper methods
238
const namespace = command => command.ns;
249
const databaseName = command => command.ns.split('.')[0];
25-
const collectionName = command => command.ns.split('.')[1];
2610
const generateConnectionId = pool =>
2711
pool.options ? `${pool.options.host}:${pool.options.port}` : pool.address;
28-
const shouldRedactCommand = (commandName, cmd) =>
29-
SENSITIVE_COMMANDS.has(commandName) ||
30-
(HELLO_COMMANDS.has(commandName) && !!cmd.speculativeAuthenticate);
3112
const isLegacyPool = pool => pool.s && pool.queue;
3213

33-
const LEGACY_FIND_QUERY_MAP = {
34-
$query: 'filter',
35-
$orderby: 'sort',
36-
$hint: 'hint',
37-
$comment: 'comment',
38-
$maxScan: 'maxScan',
39-
$max: 'max',
40-
$min: 'min',
41-
$returnKey: 'returnKey',
42-
$showDiskLoc: 'showRecordId',
43-
$maxTimeMS: 'maxTimeMS',
44-
$snapshot: 'snapshot'
45-
};
46-
47-
const LEGACY_FIND_OPTIONS_MAP = {
48-
numberToSkip: 'skip',
49-
numberToReturn: 'batchSize',
50-
returnFieldsSelector: 'projection'
51-
};
52-
53-
const OP_QUERY_KEYS = [
54-
'tailable',
55-
'oplogReplay',
56-
'noCursorTimeout',
57-
'awaitData',
58-
'partial',
59-
'exhaust'
60-
];
61-
62-
/**
63-
* Extract the actual command from the query, possibly upconverting if it's a legacy
64-
* format
65-
*
66-
* @param {Object} command the command
67-
*/
68-
const extractCommand = command => {
69-
let extractedCommand;
70-
if (command instanceof GetMore) {
71-
extractedCommand = {
72-
getMore: command.cursorId,
73-
collection: collectionName(command),
74-
batchSize: command.numberToReturn
75-
};
76-
} else if (command instanceof KillCursor) {
77-
extractedCommand = {
78-
killCursors: collectionName(command),
79-
cursors: command.cursorIds
80-
};
81-
} else if (command instanceof Msg) {
82-
extractedCommand = command.command;
83-
} else if (command.query && command.query.$query) {
84-
let result;
85-
if (command.ns === 'admin.$cmd') {
86-
// upconvert legacy command
87-
result = Object.assign({}, command.query.$query);
88-
} else {
89-
// upconvert legacy find command
90-
result = { find: collectionName(command) };
91-
Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
92-
if (typeof command.query[key] !== 'undefined')
93-
result[LEGACY_FIND_QUERY_MAP[key]] = command.query[key];
94-
});
95-
}
96-
97-
Object.keys(LEGACY_FIND_OPTIONS_MAP).forEach(key => {
98-
if (typeof command[key] !== 'undefined') result[LEGACY_FIND_OPTIONS_MAP[key]] = command[key];
99-
});
100-
101-
OP_QUERY_KEYS.forEach(key => {
102-
if (command[key]) result[key] = command[key];
103-
});
104-
105-
if (typeof command.pre32Limit !== 'undefined') {
106-
result.limit = command.pre32Limit;
107-
}
108-
109-
if (command.query.$explain) {
110-
extractedCommand = { explain: result };
111-
} else {
112-
extractedCommand = result;
113-
}
114-
} else {
115-
extractedCommand = command.query || command;
116-
}
117-
118-
return { cmd: extractedCommand, name: Object.keys(extractedCommand)[0] };
119-
};
120-
12114
const extractReply = (command, reply) => {
12215
if (command instanceof GetMore) {
12316
return {
@@ -178,15 +71,14 @@ class CommandStartedEvent {
17871
*/
17972
constructor(pool, command) {
18073
const extractedCommand = extractCommand(command);
181-
const cmd = extractedCommand.cmd;
18274
const commandName = extractedCommand.name;
18375
const connectionDetails = extractConnectionDetails(pool);
18476

18577
Object.assign(this, connectionDetails, {
18678
requestId: command.requestId,
18779
databaseName: databaseName(command),
18880
commandName,
189-
command: shouldRedactCommand(commandName, cmd) ? {} : cmd
81+
command: extractedCommand.shouldRedact ? {} : extractedCommand.cmd
19082
});
19183
}
19284
}
@@ -203,15 +95,14 @@ class CommandSucceededEvent {
20395
*/
20496
constructor(pool, command, reply, started) {
20597
const extractedCommand = extractCommand(command);
206-
const cmd = extractedCommand.cmd;
20798
const commandName = extractedCommand.name;
20899
const connectionDetails = extractConnectionDetails(pool);
209100

210101
Object.assign(this, connectionDetails, {
211102
requestId: command.requestId,
212103
commandName,
213104
duration: calculateDurationInMs(started),
214-
reply: shouldRedactCommand(commandName, cmd) ? {} : extractReply(command, reply)
105+
reply: extractedCommand.shouldRedact ? {} : extractReply(command, reply)
215106
});
216107
}
217108
}
@@ -228,15 +119,14 @@ class CommandFailedEvent {
228119
*/
229120
constructor(pool, command, error, started) {
230121
const extractedCommand = extractCommand(command);
231-
const cmd = extractedCommand.cmd;
232122
const commandName = extractedCommand.name;
233123
const connectionDetails = extractConnectionDetails(pool);
234124

235125
Object.assign(this, connectionDetails, {
236126
requestId: command.requestId,
237127
commandName,
238128
duration: calculateDurationInMs(started),
239-
failure: shouldRedactCommand(commandName, cmd) ? {} : error
129+
failure: extractedCommand.shouldRedact ? {} : error
240130
});
241131
}
242132
}

0 commit comments

Comments
 (0)