Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit f969bee

Browse files
authored
fix(apm): fix upconversion for OP_QUERY in apm
Properly upconverts query-wrapped commands in OP_QUERY to the proper apm format Fixes NODE-1655
1 parent bf0315d commit f969bee

File tree

2 files changed

+169
-6
lines changed

2 files changed

+169
-6
lines changed

lib/connection/apm.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,18 @@ const extractCommand = command => {
7676
}
7777

7878
if (command.query && command.query.$query) {
79-
// upconvert legacy find command
80-
const result = { find: collectionName(command) };
81-
Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
82-
if (typeof command.query[key] !== 'undefined')
83-
result[LEGACY_FIND_QUERY_MAP[key]] = command.query[key];
84-
});
79+
let result;
80+
if (command.ns === 'admin.$cmd') {
81+
// upconvert legacy command
82+
result = Object.assign({}, command.query.$query);
83+
} else {
84+
// upconvert legacy find command
85+
result = { find: collectionName(command) };
86+
Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
87+
if (typeof command.query[key] !== 'undefined')
88+
result[LEGACY_FIND_QUERY_MAP[key]] = command.query[key];
89+
});
90+
}
8591

8692
Object.keys(LEGACY_FIND_OPTIONS_MAP).forEach(key => {
8793
if (typeof command.options[key] !== 'undefined')

test/tests/unit/apm_tests.js

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
'use strict';
2+
3+
const Pool = require('../../../lib/connection/pool');
4+
const BSON = require('bson');
5+
const apm = require('../../../lib/connection/apm');
6+
const expect = require('chai').expect;
7+
8+
const commands = require('../../../lib/connection/commands');
9+
const Query = commands.Query;
10+
const KillCursor = commands.KillCursor;
11+
const GetMore = commands.GetMore;
12+
13+
const bson = new BSON();
14+
const pool = new Pool({}, { bson });
15+
16+
describe('APM tests', function() {
17+
describe('CommandStartedEvent', function() {
18+
// Only run on single topology since these are unit tests
19+
const metadata = { requires: { topology: ['single'] } };
20+
21+
it('should wrap a basic query option', metadata, function() {
22+
const db = 'test1';
23+
const coll = 'testingQuery';
24+
const query = new Query(
25+
bson,
26+
`${db}.${coll}`,
27+
{
28+
testCmd: 1,
29+
fizz: 'buzz',
30+
star: 'trek'
31+
},
32+
{}
33+
);
34+
35+
const startEvent = new apm.CommandStartedEvent(pool, query);
36+
37+
expect(startEvent).to.have.property('commandName', 'testCmd');
38+
expect(startEvent).to.have.property('databaseName', db);
39+
expect(startEvent).to.have.property('requestId', query.requestId);
40+
expect(startEvent)
41+
.to.have.property('connectionId')
42+
.that.is.a('string');
43+
expect(startEvent)
44+
.to.have.property('command')
45+
.that.deep.equals(query.query);
46+
});
47+
48+
it('should wrap a basic killCursor command', metadata, function() {
49+
const db = 'test2';
50+
const coll = 'testingKillCursors';
51+
const killCursor = new KillCursor(bson, `${db}.${coll}`, [12, 42, 57]);
52+
53+
const startEvent = new apm.CommandStartedEvent(pool, killCursor);
54+
55+
expect(startEvent).to.have.property('commandName', 'killCursors');
56+
expect(startEvent).to.have.property('databaseName', db);
57+
expect(startEvent).to.have.property('requestId', killCursor.requestId);
58+
expect(startEvent)
59+
.to.have.property('connectionId')
60+
.that.is.a('string');
61+
expect(startEvent)
62+
.to.have.property('command')
63+
.that.deep.equals({
64+
killCursors: coll,
65+
cursors: killCursor.cursorIds
66+
});
67+
});
68+
69+
it('should wrap a basic GetMore command', metadata, function() {
70+
const db = 'test3';
71+
const coll = 'testingGetMore';
72+
const numberToReturn = 321;
73+
const getMore = new GetMore(bson, `${db}.${coll}`, 5525, { numberToReturn });
74+
75+
const startEvent = new apm.CommandStartedEvent(pool, getMore);
76+
77+
expect(startEvent).to.have.property('commandName', 'getMore');
78+
expect(startEvent).to.have.property('databaseName', db);
79+
expect(startEvent).to.have.property('requestId', getMore.requestId);
80+
expect(startEvent)
81+
.to.have.property('connectionId')
82+
.that.is.a('string');
83+
expect(startEvent)
84+
.to.have.property('command')
85+
.that.deep.equals({
86+
getMore: getMore.cursorId,
87+
collection: coll,
88+
batchSize: numberToReturn
89+
});
90+
});
91+
92+
it(
93+
'should upconvert a Query wrapping a command into the corresponding command',
94+
metadata,
95+
function() {
96+
const db = 'admin';
97+
const coll = '$cmd';
98+
const query = new Query(
99+
bson,
100+
`${db}.${coll}`,
101+
{
102+
$query: {
103+
testCmd: 1,
104+
fizz: 'buzz',
105+
star: 'trek'
106+
}
107+
},
108+
{}
109+
);
110+
111+
const startEvent = new apm.CommandStartedEvent(pool, query);
112+
113+
expect(startEvent).to.have.property('commandName', 'testCmd');
114+
expect(startEvent).to.have.property('databaseName', db);
115+
expect(startEvent).to.have.property('requestId', query.requestId);
116+
expect(startEvent)
117+
.to.have.property('connectionId')
118+
.that.is.a('string');
119+
expect(startEvent)
120+
.to.have.property('command')
121+
.that.deep.equals(query.query.$query);
122+
}
123+
);
124+
125+
it('should upconvert a Query wrapping a query into a find command', metadata, function() {
126+
const db = 'test5';
127+
const coll = 'testingFindCommand';
128+
const query = new Query(
129+
bson,
130+
`${db}.${coll}`,
131+
{
132+
$query: {
133+
testCmd: 1,
134+
fizz: 'buzz',
135+
star: 'trek'
136+
}
137+
},
138+
{}
139+
);
140+
141+
const startEvent = new apm.CommandStartedEvent(pool, query);
142+
143+
expect(startEvent).to.have.property('commandName', 'find');
144+
expect(startEvent).to.have.property('databaseName', db);
145+
expect(startEvent).to.have.property('requestId', query.requestId);
146+
expect(startEvent)
147+
.to.have.property('connectionId')
148+
.that.is.a('string');
149+
expect(startEvent)
150+
.to.have.property('command')
151+
.that.deep.equals({
152+
find: coll,
153+
filter: query.query.$query
154+
});
155+
});
156+
});
157+
});

0 commit comments

Comments
 (0)