Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions src/cmap/command_monitoring_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
LEGACY_HELLO_COMMAND,
LEGACY_HELLO_COMMAND_CAMEL_CASE
} from '../constants';
import { calculateDurationInMs, deepCopy } from '../utils';
import { calculateDurationInMs } from '../utils';
import {
DocumentSequence,
OpMsgRequest,
Expand Down Expand Up @@ -254,7 +254,7 @@ const OP_QUERY_KEYS = [
/** Extract the actual command from the query, possibly up-converting if it's a legacy format */
function extractCommand(command: WriteProtocolMessageType): Document {
if (command instanceof OpMsgRequest) {
const cmd = deepCopy(command.command);
const cmd = { ...command.command };
// For OP_MSG with payload type 1 we need to pull the documents
// array out of the document sequence for monitoring.
if (cmd.ops instanceof DocumentSequence) {
Expand All @@ -276,15 +276,15 @@ function extractCommand(command: WriteProtocolMessageType): Document {
result = { find: collectionName(command) };
Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
if (command.query[key] != null) {
result[LEGACY_FIND_QUERY_MAP[key]] = deepCopy(command.query[key]);
result[LEGACY_FIND_QUERY_MAP[key]] = { ...command.query[key] };
}
});
}

Object.keys(LEGACY_FIND_OPTIONS_MAP).forEach(key => {
const legacyKey = key as keyof typeof LEGACY_FIND_OPTIONS_MAP;
if (command[legacyKey] != null) {
result[LEGACY_FIND_OPTIONS_MAP[legacyKey]] = deepCopy(command[legacyKey]);
result[LEGACY_FIND_OPTIONS_MAP[legacyKey]] = command[legacyKey];
}
});

Expand All @@ -304,19 +304,13 @@ function extractCommand(command: WriteProtocolMessageType): Document {
return result;
}

const clonedQuery: Record<string, unknown> = {};
const clonedCommand: Record<string, unknown> = {};
let clonedQuery: Record<string, unknown> = {};
const clonedCommand: Record<string, unknown> = { ...command };
if (command.query) {
for (const k in command.query) {
clonedQuery[k] = deepCopy(command.query[k]);
}
clonedQuery = { ...command.query };
clonedCommand.query = clonedQuery;
}

for (const k in command) {
if (k === 'query') continue;
clonedCommand[k] = deepCopy((command as unknown as Record<string, unknown>)[k]);
}
return command.query ? clonedQuery : clonedCommand;
}

Expand All @@ -326,22 +320,22 @@ function extractReply(command: WriteProtocolMessageType, reply?: Document) {
}

if (command instanceof OpMsgRequest) {
return deepCopy(reply.result ? reply.result : reply);
return reply.result ? reply.result : reply;
}

// is this a legacy find command?
if (command.query && command.query.$query != null) {
return {
ok: 1,
cursor: {
id: deepCopy(reply.cursorId),
id: reply.cursorId,
ns: namespace(command),
firstBatch: deepCopy(reply.documents)
firstBatch: reply.documents
}
};
}

return deepCopy(reply.result ? reply.result : reply);
return reply.result ? reply.result : reply;
}

function extractConnectionDetails(connection: Connection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,35 +617,5 @@ describe('Command Monitoring', function () {
afterEach(function (done) {
client.close(done);
});

// NODE-1502
it('should not allow mutation of internal state from commands returned by event monitoring', function () {
const started = [];
const succeeded = [];
client.on('commandStarted', filterForCommands('insert', started));
client.on('commandSucceeded', filterForCommands('insert', succeeded));
const documentToInsert = { a: { b: 1 } };
const db = client.db(this.configuration.db);
return db
.collection('apm_test')
.insertOne(documentToInsert)
.then(r => {
expect(r).to.have.property('insertedId').that.is.an('object');
expect(started).to.have.lengthOf(1);
// Check if contents of returned document are equal to document inserted (by value)
expect(documentToInsert).to.deep.equal(started[0].command.documents[0]);
// Check if the returned document is a clone of the original. This confirms that the
// reference is not the same.
expect(documentToInsert !== started[0].command.documents[0]).to.equal(true);
expect(documentToInsert.a !== started[0].command.documents[0].a).to.equal(true);

started[0].command.documents[0].a.b = 2;
expect(documentToInsert.a.b).to.equal(1);

expect(started[0].commandName).to.equal('insert');
expect(started[0].command.insert).to.equal('apm_test');
expect(succeeded).to.have.lengthOf(1);
});
});
});
});
Loading