Exemple #1
0
        private void ProcessGLEReplyMessage(CommandState state, ReplyMessage <RawBsonDocument> replyMessage, ConnectionId connectionId)
        {
            var       reply = replyMessage.Documents[0];
            BsonValue ok;

            if (!reply.TryGetValue("ok", out ok))
            {
                // this is a degenerate case with the server and
                // we don't really know what to do here...
            }
            else if (!ok.ToBoolean())
            {
                if (_failedEvent != null)
                {
                    _failedEvent(new CommandFailedEvent(
                                     state.CommandName,
                                     new MongoCommandException(
                                         connectionId,
                                         string.Format("{0} command failed", state.CommandName),
                                         null,
                                         reply),
                                     state.OperationId,
                                     replyMessage.ResponseTo,
                                     connectionId,
                                     state.Stopwatch.Elapsed));
                }
            }
            else if (_succeededEvent != null)
            {
                var fakeReply = new BsonDocument("ok", 1);

                BsonValue n;
                if (reply.TryGetValue("n", out n))
                {
                    fakeReply["n"] = n;
                }

                BsonValue err;
                if (reply.TryGetValue("err", out err) && err != BsonNull.Value)
                {
                    var code   = reply.GetValue("code", -1);
                    var errmsg = err.ToString();
                    var isWriteConcernError = __writeConcernIndicators.Any(x => errmsg.Contains(x));
                    if (isWriteConcernError)
                    {
                        fakeReply["writeConcernError"] = new BsonDocument
                        {
                            { "code", code },
                            { "errmsg", err }
                        };
                    }
                    else
                    {
                        fakeReply["writeErrors"] = new BsonArray(new[] { new BsonDocument
                                                                         {
                                                                             { "index", 0 },
                                                                             { "code", code },
                                                                             { "errmsg", err }
                                                                         } });
                    }
                }
                else if (state.CommandName == "insert")
                {
                    fakeReply["n"] = state.NumberOfInsertedDocuments;
                }
                else if (state.CommandName == "update")
                {
                    // Unfortunately v2.4 GLE does not include the upserted field when
                    // the upserted _id is non-OID type.  We can detect this by the
                    // updatedExisting field + an n of 1
                    BsonValue upsertedValue;
                    var       upserted = reply.TryGetValue("upserted", out upsertedValue) ||
                                         (n == 1 && !reply.GetValue("updatedExisting", false).ToBoolean());

                    if (upserted)
                    {
                        fakeReply["upserted"] = new BsonArray(new[] { new BsonDocument
                                                                      {
                                                                          { "index", 0 },
                                                                          { "_id", upsertedValue ?? state.UpsertedId ?? BsonUndefined.Value }
                                                                      } });
                    }
                }

                _succeededEvent(new CommandSucceededEvent(
                                    state.CommandName,
                                    fakeReply,
                                    state.OperationId,
                                    replyMessage.ResponseTo,
                                    connectionId,
                                    state.Stopwatch.Elapsed));
            }
        }
Exemple #2
0
        private void ProcessQueryReplyMessage(CommandState state, ReplyMessage <RawBsonDocument> replyMessage, ConnectionId connectionId)
        {
            if (_succeededEvent != null)
            {
                BsonDocument reply;
                if (state.CommandName == "explain")
                {
                    reply = new BsonDocument("ok", 1);
                    reply.Merge(replyMessage.Documents[0]);
                }
                else
                {
                    var batchName = state.CommandName == "find" ? "firstBatch" : "nextBatch";
                    reply = new BsonDocument
                    {
                        { "cursor", new BsonDocument
                          {
                              { "id", replyMessage.CursorId },
                              { "ns", state.QueryNamespace.FullName },
                              { batchName, new BsonArray(replyMessage.Documents) }
                          } },
                        { "ok", 1 }
                    };
                }

                _succeededEvent(new CommandSucceededEvent(
                                    state.CommandName,
                                    reply,
                                    state.OperationId,
                                    replyMessage.ResponseTo,
                                    connectionId,
                                    state.Stopwatch.Elapsed));
            }
        }
Exemple #3
0
        private void ProcessReplyMessage(CommandState state, ResponseMessage message, IByteBuffer buffer, ConnectionId connectionId, MessageEncoderSettings encoderSettings)
        {
            state.Stopwatch.Stop();
            bool disposeOfDocuments = false;
            var  replyMessage       = message as ReplyMessage <RawBsonDocument>;

            if (replyMessage == null)
            {
                // ReplyMessage is generic, which means that we can't use it here, so, we need to use a different one...
                using (var stream = new ByteBufferStream(buffer, ownsBuffer: false))
                {
                    var encoderFactory = new BinaryMessageEncoderFactory(stream, encoderSettings);
                    replyMessage = (ReplyMessage <RawBsonDocument>)encoderFactory
                                   .GetReplyMessageEncoder(RawBsonDocumentSerializer.Instance)
                                   .ReadMessage();
                    disposeOfDocuments = true;
                }
            }

            try
            {
                if (replyMessage.CursorNotFound ||
                    replyMessage.QueryFailure ||
                    (state.ExpectedResponseType != ExpectedResponseType.Query && replyMessage.Documents.Count == 0))
                {
                    var queryFailureDocument = replyMessage.QueryFailureDocument;
                    if (__securitySensitiveCommands.Contains(state.CommandName))
                    {
                        queryFailureDocument = new BsonDocument();
                    }
                    if (_failedEvent != null)
                    {
                        _failedEvent(new CommandFailedEvent(
                                         state.CommandName,
                                         new MongoCommandException(
                                             connectionId,
                                             string.Format("{0} command failed", state.CommandName),
                                             null,
                                             queryFailureDocument),
                                         state.OperationId,
                                         replyMessage.ResponseTo,
                                         connectionId,
                                         state.Stopwatch.Elapsed));
                    }
                }
                else
                {
                    switch (state.ExpectedResponseType)
                    {
                    case ExpectedResponseType.Command:
                        ProcessCommandReplyMessage(state, replyMessage, connectionId);
                        break;

                    case ExpectedResponseType.GLE:
                        ProcessGLEReplyMessage(state, replyMessage, connectionId);
                        break;

                    case ExpectedResponseType.Query:
                        ProcessQueryReplyMessage(state, replyMessage, connectionId);
                        break;
                    }
                }
            }
            finally
            {
                if (disposeOfDocuments && replyMessage.Documents != null)
                {
                    replyMessage.Documents.ForEach(d => d.Dispose());
                }
            }
        }
Exemple #4
0
        private void ProcessCommandReplyMessage(CommandState state, ReplyMessage <RawBsonDocument> replyMessage, ConnectionId connectionId)
        {
            BsonDocument reply = replyMessage.Documents[0];
            BsonValue    ok;

            if (!reply.TryGetValue("ok", out ok))
            {
                // this is a degenerate case with the server and
                // we don't really know what to do here...
                return;
            }

            if (__securitySensitiveCommands.Contains(state.CommandName))
            {
                reply = new BsonDocument();
            }

            if (!ok.ToBoolean())
            {
                if (_failedEvent != null)
                {
                    _failedEvent(new CommandFailedEvent(
                                     state.CommandName,
                                     new MongoCommandException(
                                         connectionId,
                                         string.Format("{0} command failed", state.CommandName),
                                         null,
                                         reply),
                                     state.OperationId,
                                     replyMessage.ResponseTo,
                                     connectionId,
                                     state.Stopwatch.Elapsed));
                }
            }
            else if (_succeededEvent != null)
            {
                _succeededEvent(new CommandSucceededEvent(
                                    state.CommandName,
                                    reply,
                                    state.OperationId,
                                    replyMessage.ResponseTo,
                                    connectionId,
                                    state.Stopwatch.Elapsed));
            }
        }
Exemple #5
0
        private void ProcessInsertMessage(RequestMessage message, Queue <RequestMessage> messageQueue, ConnectionId connectionId, InsertMessageBinaryEncoder <RawBsonDocument> encoder, Stopwatch stopwatch)
        {
            var          commandName          = "insert";
            var          operationId          = EventContext.OperationId;
            var          requestId            = message.RequestId;
            var          expectedResponseType = ExpectedResponseType.None;
            int          numberOfDocuments    = 0;
            int          gleRequestId;
            WriteConcern writeConcern;

            if (TryGetWriteConcernFromGLE(messageQueue, out gleRequestId, out writeConcern))
            {
                requestId            = gleRequestId;
                expectedResponseType = ExpectedResponseType.GLE;
            }

            if (_startedEvent != null)
            {
                // InsertMessage is generic, and we don't know the generic type...
                // Plus, for this we really want BsonDocuments, not whatever the generic type is.
                var decodedMessage = encoder.ReadMessage();

                var documents = decodedMessage.DocumentSource.GetBatchItems();
                numberOfDocuments = documents.Count;
                try
                {
                    var command = new BsonDocument
                    {
                        { commandName, decodedMessage.CollectionNamespace.CollectionName },
                        { "documents", new BsonArray(documents) },
                        { "ordered", !decodedMessage.ContinueOnError }
                    };

                    if (writeConcern == null)
                    {
                        command["writeConcern"] = WriteConcern.Unacknowledged.ToBsonDocument();
                    }
                    else if (!writeConcern.IsServerDefault)
                    {
                        command["writeConcern"] = writeConcern.ToBsonDocument();
                    }

                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        decodedMessage.CollectionNamespace.DatabaseNamespace,
                        operationId,
                        requestId,
                        connectionId);

                    _startedEvent(@event);
                }
                finally
                {
                    foreach (var document in documents)
                    {
                        document.Dispose();
                    }
                }
            }

            if (_shouldTrackState)
            {
                _state.TryAdd(requestId, new CommandState
                {
                    CommandName               = commandName,
                    OperationId               = operationId,
                    Stopwatch                 = stopwatch,
                    ExpectedResponseType      = expectedResponseType,
                    NumberOfInsertedDocuments = numberOfDocuments
                });
            }
        }
Exemple #6
0
        private void ProcessQueryMessage(QueryMessage originalMessage, ConnectionId connectionId, QueryMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var requestId   = originalMessage.RequestId;
            var operationId = EventContext.OperationId;

            var decodedMessage = encoder.ReadMessage(RawBsonDocumentSerializer.Instance);

            try
            {
                var          isCommand = IsCommand(decodedMessage.CollectionNamespace);
                string       commandName;
                BsonDocument command;
                if (isCommand)
                {
                    command = decodedMessage.Query;
                    var firstElement = command.GetElement(0);
                    commandName = firstElement.Name;
                    if (__securitySensitiveCommands.Contains(commandName))
                    {
                        command = new BsonDocument();
                    }
                }
                else
                {
                    commandName = "find";
                    command     = BuildFindCommandFromQuery(decodedMessage);
                    if (decodedMessage.Query.GetValue("$explain", false).ToBoolean())
                    {
                        commandName = "explain";
                        command     = new BsonDocument("explain", command);
                    }
                }

                if (_startedEvent != null)
                {
                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        decodedMessage.CollectionNamespace.DatabaseNamespace,
                        operationId,
                        requestId,
                        connectionId);

                    _startedEvent(@event);
                }

                if (_shouldTrackState)
                {
                    _state.TryAdd(requestId, new CommandState
                    {
                        CommandName          = commandName,
                        OperationId          = operationId,
                        Stopwatch            = stopwatch,
                        QueryNamespace       = decodedMessage.CollectionNamespace,
                        ExpectedResponseType = isCommand ? ExpectedResponseType.Command : ExpectedResponseType.Query
                    });
                }
            }
            finally
            {
                var disposable = decodedMessage.Query as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
                disposable = decodedMessage.Fields as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
Exemple #7
0
 /// <summary>
 /// Returns a new instance of ConnectionDescription with a different connection identifier.
 /// </summary>
 /// <param name="value">The value.</param>
 /// <returns>A connection description.</returns>
 public ConnectionDescription WithConnectionId(ConnectionId value)
 {
     return(_connectionId.StructurallyEquals(value) ? this : new ConnectionDescription(value, _helloResult));
 }
Exemple #8
0
        private void ProcessDeleteMessage(DeleteMessage originalMessage, Queue <RequestMessage> messageQueue, ConnectionId connectionId, DeleteMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var          commandName          = "delete";
            var          operationId          = EventContext.OperationId;
            int          requestId            = originalMessage.RequestId;
            var          expectedResponseType = ExpectedResponseType.None;
            int          gleRequestId;
            WriteConcern writeConcern;

            if (TryGetWriteConcernFromGLE(messageQueue, out gleRequestId, out writeConcern))
            {
                requestId            = gleRequestId;
                expectedResponseType = ExpectedResponseType.GLE;
            }

            if (_startedEvent != null)
            {
                var decodedMessage = encoder.ReadMessage(RawBsonDocumentSerializer.Instance);
                try
                {
                    var entry = new BsonDocument
                    {
                        { "q", decodedMessage.Query },
                        { "limit", decodedMessage.IsMulti ? 0 : 1 }
                    };
                    var command = new BsonDocument
                    {
                        { commandName, decodedMessage.CollectionNamespace.CollectionName },
                        { "deletes", new BsonArray(new [] { entry }) }
                    };

                    if (writeConcern == null)
                    {
                        command["writeConcern"] = WriteConcern.Unacknowledged.ToBsonDocument();
                    }
                    else if (!writeConcern.IsServerDefault)
                    {
                        command["writeConcern"] = writeConcern.ToBsonDocument();
                    }

                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        decodedMessage.CollectionNamespace.DatabaseNamespace,
                        operationId,
                        requestId,
                        connectionId);

                    _startedEvent(@event);
                }
                finally
                {
                    var disposable = decodedMessage.Query as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                }
            }

            if (_shouldTrackState)
            {
                _state.TryAdd(requestId, new CommandState
                {
                    CommandName          = commandName,
                    OperationId          = operationId,
                    Stopwatch            = stopwatch,
                    ExpectedResponseType = expectedResponseType
                });
            }
        }
Exemple #9
0
        private void ProcessCommandResponseMessage(CommandState state, CommandResponseMessage message, IByteBuffer buffer, ConnectionId connectionId, ObjectId?serviceId, MessageEncoderSettings encoderSettings)
        {
            var wrappedMessage = message.WrappedMessage;
            var type0Section   = wrappedMessage.Sections.OfType <Type0CommandMessageSection <RawBsonDocument> >().Single();
            var reply          = (BsonDocument)type0Section.Document;

            BsonValue ok;

            if (!reply.TryGetValue("ok", out ok))
            {
                // this is a degenerate case with the server and
                // we don't really know what to do here...
                return;
            }

            if (state.ShouldRedactReply)
            {
                reply = new BsonDocument();
            }

            if (ok.ToBoolean())
            {
                if (_succeededEvent != null)
                {
                    _succeededEvent(new CommandSucceededEvent(
                                        state.CommandName,
                                        reply,
                                        state.OperationId,
                                        message.ResponseTo,
                                        connectionId,
                                        serviceId,
                                        state.Stopwatch.Elapsed));
                }
            }
            else
            {
                if (_failedEvent != null)
                {
                    _failedEvent(new CommandFailedEvent(
                                     state.CommandName,
                                     new MongoCommandException(
                                         connectionId,
                                         string.Format("{0} command failed", state.CommandName),
                                         null,
                                         reply),
                                     state.OperationId,
                                     message.ResponseTo,
                                     connectionId,
                                     serviceId,
                                     state.Stopwatch.Elapsed));
                }
            }
        }
Exemple #10
0
        private void ProcessUpdateMessage(UpdateMessage originalMessage, Queue <RequestMessage> messageQueue, ConnectionId connectionId, UpdateMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var          commandName          = "update";
            int          requestId            = originalMessage.RequestId;
            var          operationId          = EventContext.OperationId;
            var          expectedResponseType = ExpectedResponseType.None;
            BsonValue    upsertedId           = null;
            int          gleRequestId;
            WriteConcern writeConcern;

            if (TryGetWriteConcernFromGLE(messageQueue, out gleRequestId, out writeConcern))
            {
                requestId            = gleRequestId;
                expectedResponseType = ExpectedResponseType.GLE;
            }

            if (_startedEvent != null)
            {
                var decodedMessage = encoder.ReadMessage(RawBsonDocumentSerializer.Instance);
                try
                {
                    if (_shouldTrackState)
                    {
                        // GLE result on older versions of the server didn't return
                        // the upserted id when it wasn't an object id, so we'll
                        // attempt to get it from the messages.
                        if (!decodedMessage.Update.TryGetValue("_id", out upsertedId))
                        {
                            decodedMessage.Query.TryGetValue("_id", out upsertedId);
                        }
                    }

                    var entry = new BsonDocument
                    {
                        { "q", decodedMessage.Query },
                        { "u", decodedMessage.Update },
                        { "upsert", decodedMessage.IsUpsert },
                        { "multi", decodedMessage.IsMulti }
                    };
                    var command = new BsonDocument
                    {
                        { commandName, decodedMessage.CollectionNamespace.CollectionName },
                        { "updates", new BsonArray(new [] { entry }) }
                    };

                    if (writeConcern == null)
                    {
                        command["writeConcern"] = WriteConcern.Unacknowledged.ToBsonDocument();
                    }
                    else if (!writeConcern.IsServerDefault)
                    {
                        command["writeConcern"] = writeConcern.ToBsonDocument();
                    }

                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        decodedMessage.CollectionNamespace.DatabaseNamespace,
                        operationId,
                        requestId,
                        connectionId);

                    _startedEvent(@event);
                }
                finally
                {
                    var disposable = decodedMessage.Query as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                    disposable = decodedMessage.Update as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                }
            }

            if (_shouldTrackState)
            {
                _state.TryAdd(requestId, new CommandState
                {
                    CommandName          = commandName,
                    OperationId          = operationId,
                    Stopwatch            = Stopwatch.StartNew(),
                    ExpectedResponseType = expectedResponseType,
                    UpsertedId           = upsertedId
                });
            }
        }
Exemple #11
0
        private void ProcessCommandRequestMessage(CommandRequestMessage originalMessage, Queue <RequestMessage> messageQueue, ConnectionId connectionId, ObjectId?serviceId, CommandMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var requestId   = originalMessage.RequestId;
            var operationId = EventContext.OperationId;

            var decodedMessage = encoder.ReadMessage();

            using (new CommandMessageDisposer(decodedMessage))
            {
                var type0Section  = decodedMessage.Sections.OfType <Type0CommandMessageSection>().Single();
                var command       = (BsonDocument)type0Section.Document;
                var type1Sections = decodedMessage.Sections.OfType <Type1CommandMessageSection>().ToList();
                if (type1Sections.Count > 0)
                {
                    command = new BsonDocument(command); // materialize the top level of the command RawBsonDocument
                    foreach (var type1Section in type1Sections)
                    {
                        var name  = type1Section.Identifier;
                        var items = new BsonArray(type1Section.Documents.GetBatchItems().Cast <RawBsonDocument>());
                        command[name] = items;
                    }
                }
                var commandName         = command.GetElement(0).Name;
                var databaseName        = command["$db"].AsString;
                var databaseNamespace   = new DatabaseNamespace(databaseName);
                var shouldRedactCommand = ShouldRedactCommand(command);
                if (shouldRedactCommand)
                {
                    command = new BsonDocument();
                }

                if (_startedEvent != null)
                {
                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        databaseNamespace,
                        operationId,
                        requestId,
                        connectionId,
                        serviceId);

                    _startedEvent(@event);
                }

                if (_shouldTrackState)
                {
                    _state.TryAdd(requestId, new CommandState
                    {
                        CommandName          = commandName,
                        OperationId          = operationId,
                        Stopwatch            = stopwatch,
                        QueryNamespace       = new CollectionNamespace(databaseNamespace, "$cmd"),
                        ExpectedResponseType = decodedMessage.MoreToCome ? ExpectedResponseType.None : ExpectedResponseType.Command,
                        ShouldRedactReply    = shouldRedactCommand
                    });
                }
            }
        }
        public void LocalValue_should_be_what_was_specified_in_the_constructor()
        {
            var subject = new ConnectionId(__serverId, 10);

            subject.LocalValue.Should().Be(10);
        }
Exemple #13
0
 /// <summary>
 /// Returns a new instance of ConnectionDescription with a different connection identifier.
 /// </summary>
 /// <param name="value">The value.</param>
 /// <returns>A connection description.</returns>
 public ConnectionDescription WithConnectionId(ConnectionId value)
 {
     return(_connectionId.StructurallyEquals(value) ? this : new ConnectionDescription(value, _isMasterResult, _buildInfoResult));
 }
Exemple #14
0
        public async Task <ConnectionDescription> InitializeConnectionAsync(IConnection connection, ConnectionId connectionId, TimeSpan timeout, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(connection, "connection");
            Ensure.IsNotNull(connectionId, "connectionId");
            Ensure.IsInfiniteOrGreaterThanOrEqualToZero(timeout, "timeout");

            var slidingTimeout = new SlidingTimeout(timeout);

            var isMasterCommand  = new BsonDocument("isMaster", 1);
            var isMasterProtocol = new CommandWireProtocol(DatabaseNamespace.Admin, isMasterCommand, true, null);
            var isMasterResult   = new IsMasterResult(await isMasterProtocol.ExecuteAsync(connection, slidingTimeout, cancellationToken).ConfigureAwait(false));

            // authentication is currently broken on arbiters
            if (!isMasterResult.IsArbiter)
            {
                foreach (var authenticator in connection.Settings.Authenticators)
                {
                    await authenticator.AuthenticateAsync(connection, slidingTimeout, cancellationToken).ConfigureAwait(false);
                }
            }

            var buildInfoCommand  = new BsonDocument("buildInfo", 1);
            var buildInfoProtocol = new CommandWireProtocol(DatabaseNamespace.Admin, buildInfoCommand, true, null);
            var buildInfoResult   = new BuildInfoResult(await buildInfoProtocol.ExecuteAsync(connection, slidingTimeout, cancellationToken).ConfigureAwait(false));

            var getLastErrorCommand  = new BsonDocument("getLastError", 1);
            var getLastErrorProtocol = new CommandWireProtocol(DatabaseNamespace.Admin, getLastErrorCommand, true, null);
            var getLastErrorResult   = await getLastErrorProtocol.ExecuteAsync(connection, slidingTimeout, cancellationToken).ConfigureAwait(false);

            BsonValue connectionIdBsonValue;

            if (getLastErrorResult.TryGetValue("connectionId", out connectionIdBsonValue))
            {
                connectionId = connectionId.WithServerValue(connectionIdBsonValue.ToInt32());
            }

            return(new ConnectionDescription(connectionId, isMasterResult, buildInfoResult));
        }
        private void ProcessCommandRequestMessage(CommandRequestMessage originalMessage, Queue <RequestMessage> messageQueue, ConnectionId connectionId, CommandMessageBinaryEncoder encoder, Stopwatch stopwatch)
        {
            var requestId   = originalMessage.RequestId;
            var operationId = EventContext.OperationId;

            var decodedMessage = encoder.ReadMessage();

            using (new CommandMessageDisposer(decodedMessage))
            {
                var type0Section      = decodedMessage.Sections.OfType <Type0CommandMessageSection>().Single();
                var command           = (BsonDocument)type0Section.Document;
                var commandName       = command.GetElement(0).Name;
                var databaseName      = command["$db"].AsString;
                var databaseNamespace = new DatabaseNamespace(databaseName);
                if (__securitySensitiveCommands.Contains(commandName))
                {
                    command = new BsonDocument();
                }

                if (_startedEvent != null)
                {
                    var @event = new CommandStartedEvent(
                        commandName,
                        command,
                        databaseNamespace,
                        operationId,
                        requestId,
                        connectionId);

                    _startedEvent(@event);
                }

                if (_shouldTrackState)
                {
                    _state.TryAdd(requestId, new CommandState
                    {
                        CommandName          = commandName,
                        OperationId          = operationId,
                        Stopwatch            = stopwatch,
                        QueryNamespace       = new CollectionNamespace(databaseNamespace, "$cmd"),
                        ExpectedResponseType = ExpectedResponseType.Command
                    });
                }
            }
        }