Exemple #1
0
        public static List <TDocument> DeserializeBatch <TDocument>(RawBsonArray batch, IBsonSerializer <TDocument> documentSerializer, MessageEncoderSettings messageEncoderSettings)
        {
            var documents = new List <TDocument>();

            var readerSettings = new BsonBinaryReaderSettings();

            if (messageEncoderSettings != null)
            {
                readerSettings.Encoding           = messageEncoderSettings.GetOrDefault(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict);
                readerSettings.GuidRepresentation = messageEncoderSettings.GetOrDefault(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy);
            }
            ;

            using (var stream = new ByteBufferStream(batch.Slice, ownsBuffer: false))
                using (var reader = new BsonBinaryReader(stream, readerSettings))
                {
                    // BSON requires that the top level object be a document, but an array looks close enough to a document that we can pretend it is one
                    reader.ReadStartDocument();
                    while (reader.ReadBsonType() != 0)
                    {
                        reader.SkipName(); // skip over the index pseudo names
                        var context  = BsonDeserializationContext.CreateRoot(reader);
                        var document = documentSerializer.Deserialize <TDocument>(context);
                        documents.Add(document);
                    }
                    reader.ReadEndDocument();
                }

            return(documents);
        }
Exemple #2
0
        private TResult ProcessCommandResult(ConnectionId connectionId, RawBsonDocument rawBsonDocument)
        {
            var binaryReaderSettings = new BsonBinaryReaderSettings
            {
                Encoding           = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict),
                GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy)
            };

            BsonValue writeConcernError;

            if (rawBsonDocument.TryGetValue("writeConcernError", out writeConcernError))
            {
                var message            = writeConcernError["errmsg"].AsString;
                var response           = rawBsonDocument.Materialize(binaryReaderSettings);
                var writeConcernResult = new WriteConcernResult(response);
                throw new MongoWriteConcernException(connectionId, message, writeConcernResult);
            }

            using (var stream = new ByteBufferStream(rawBsonDocument.Slice, ownsBuffer: false))
                using (var reader = new BsonBinaryReader(stream, binaryReaderSettings))
                {
                    var context = BsonDeserializationContext.CreateRoot(reader);
                    return(_resultSerializer.Deserialize(context));
                }
        }
        // methods
        /// <summary>
        /// Creates a binary reader for this encoder.
        /// </summary>
        /// <returns>A binary reader.</returns>
        public BsonBinaryReader CreateBinaryReader()
        {
            var readerSettings = new BsonBinaryReaderSettings();

            if (_encoderSettings != null)
            {
                readerSettings.Encoding = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.ReadEncoding, readerSettings.Encoding);
                readerSettings.FixOldBinarySubTypeOnInput    = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.FixOldBinarySubTypeOnInput, readerSettings.FixOldBinarySubTypeOnInput);
                readerSettings.FixOldDateTimeMaxValueOnInput = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.FixOldBinarySubTypeOnOutput, readerSettings.FixOldDateTimeMaxValueOnInput);
                readerSettings.GuidRepresentation            = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.GuidRepresentation, readerSettings.GuidRepresentation);
                readerSettings.MaxDocumentSize = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.MaxDocumentSize, readerSettings.MaxDocumentSize);
            }
            return(new BsonBinaryReader(_stream, readerSettings));
        }
        private TResult ProcessCommandResult(ConnectionId connectionId, RawBsonDocument rawBsonDocument)
        {
            var binaryReaderSettings = new BsonBinaryReaderSettings
            {
                Encoding           = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict),
                GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy)
            };

            using (var stream = new ByteBufferStream(rawBsonDocument.Slice, ownsBuffer: false))
                using (var reader = new BsonBinaryReader(stream, binaryReaderSettings))
                {
                    var context = BsonDeserializationContext.CreateRoot(reader);
                    return(_resultSerializer.Deserialize(context));
                }
        }
        private int _previousRequestId;   // RequestId from the previous response

        // constructors
        public CommandUsingCommandMessageWireProtocol(
            ICoreSession session,
            ReadPreference readPreference,
            DatabaseNamespace databaseNamespace,
            BsonDocument command,
            IEnumerable <Type1CommandMessageSection> commandPayloads,
            IElementNameValidator commandValidator,
            BsonDocument additionalOptions,
            CommandResponseHandling responseHandling,
            IBsonSerializer <TCommandResult> resultSerializer,
            MessageEncoderSettings messageEncoderSettings,
            Action <IMessageEncoderPostProcessor> postWriteAction,
            ServerApi serverApi)
        {
            if (responseHandling != CommandResponseHandling.Return &&
                responseHandling != CommandResponseHandling.NoResponseExpected &&
                responseHandling != CommandResponseHandling.ExhaustAllowed)
            {
                throw new ArgumentException("CommandResponseHandling must be Return, NoneExpected or ExhaustAllowed.", nameof(responseHandling));
            }

            _session                = Ensure.IsNotNull(session, nameof(session));
            _readPreference         = readPreference;
            _databaseNamespace      = Ensure.IsNotNull(databaseNamespace, nameof(databaseNamespace));
            _command                = Ensure.IsNotNull(command, nameof(command));
            _commandPayloads        = commandPayloads?.ToList(); // can be null
            _commandValidator       = Ensure.IsNotNull(commandValidator, nameof(commandValidator));
            _additionalOptions      = additionalOptions;         // can be null
            _responseHandling       = responseHandling;
            _resultSerializer       = Ensure.IsNotNull(resultSerializer, nameof(resultSerializer));
            _messageEncoderSettings = messageEncoderSettings;
            _postWriteAction        = postWriteAction; // can be null
            _serverApi              = serverApi;       // can be null

            if (messageEncoderSettings != null)
            {
                _documentFieldDecryptor = messageEncoderSettings.GetOrDefault <IBinaryDocumentFieldDecryptor>(MessageEncoderSettingsName.BinaryDocumentFieldDecryptor, null);
                _documentFieldEncryptor = messageEncoderSettings.GetOrDefault <IBinaryCommandFieldEncryptor>(MessageEncoderSettingsName.BinaryDocumentFieldEncryptor, null);
            }
        }
        // methods
        /// <summary>
        /// Creates a JsonReader for this encoder.
        /// </summary>
        /// <returns>A JsonReader.</returns>
        public JsonReader CreateJsonReader()
        {
            if (_textReader == null)
            {
                throw new InvalidOperationException("No TextReader was provided.");
            }

            var readerSettings = new JsonReaderSettings();

            if (_encoderSettings != null)
            {
                readerSettings.GuidRepresentation = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy);
            }
            return(new JsonReader(_textReader, readerSettings));
        }
        // methods
        /// <summary>
        /// Creates a JsonReader for this encoder.
        /// </summary>
        /// <returns>A JsonReader.</returns>
        public JsonReader CreateJsonReader()
        {
            if (_textReader == null)
            {
                throw new InvalidOperationException("No TextReader was provided.");
            }

            var readerSettings = new JsonReaderSettings();

            if (_encoderSettings != null)
            {
#pragma warning disable 618
                if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
                {
                    readerSettings.GuidRepresentation = _encoderSettings.GetOrDefault(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy);
                }
#pragma warning restore 618
            }
            return(new JsonReader(_textReader, readerSettings));
        }
        private TCommandResult ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage)
        {
            using (new CommandMessageDisposer(responseMessage))
            {
                var rawDocument = responseMessage.Sections.OfType <Type0CommandMessageSection <RawBsonDocument> >().Single().Document;

                var binaryReaderSettings = new BsonBinaryReaderSettings();
                if (_messageEncoderSettings != null)
                {
                    binaryReaderSettings.Encoding           = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict);
                    binaryReaderSettings.GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy);
                }
                ;

                BsonValue clusterTime;
                if (rawDocument.TryGetValue("$clusterTime", out clusterTime))
                {
                    // note: we are assuming that _session is an instance of ClusterClockAdvancingClusterTime
                    // and that calling _session.AdvanceClusterTime will have the side effect of advancing the cluster's ClusterTime also
                    var materializedClusterTime = ((RawBsonDocument)clusterTime).Materialize(binaryReaderSettings);
                    _session.AdvanceClusterTime(materializedClusterTime);
                }

                BsonValue operationTime;
                if (rawDocument.TryGetValue("operationTime", out operationTime))
                {
                    _session.AdvanceOperationTime(operationTime.AsBsonTimestamp);
                }

                if (!rawDocument.GetValue("ok", false).ToBoolean())
                {
                    var materializedDocument = rawDocument.Materialize(binaryReaderSettings);

                    var commandName = _command.GetElement(0).Name;
                    if (commandName == "$query")
                    {
                        commandName = _command["$query"].AsBsonDocument.GetElement(0).Name;
                    }

                    var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, materializedDocument, "errmsg");
                    if (notPrimaryOrNodeIsRecoveringException != null)
                    {
                        throw notPrimaryOrNodeIsRecoveringException;
                    }

                    var mappedException = ExceptionMapper.Map(connectionId, materializedDocument);
                    if (mappedException != null)
                    {
                        throw mappedException;
                    }

                    string    message;
                    BsonValue errmsgBsonValue;
                    if (materializedDocument.TryGetValue("errmsg", out errmsgBsonValue) && errmsgBsonValue.IsString)
                    {
                        var errmsg = errmsgBsonValue.ToString();
                        message = string.Format("Command {0} failed: {1}.", commandName, errmsg);
                    }
                    else
                    {
                        message = string.Format("Command {0} failed.", commandName);
                    }

                    throw new MongoCommandException(connectionId, message, _command, materializedDocument);
                }

                using (var stream = new ByteBufferStream(rawDocument.Slice, ownsBuffer: false))
                {
                    using (var reader = new BsonBinaryReader(stream, binaryReaderSettings))
                    {
                        var context = BsonDeserializationContext.CreateRoot(reader);
                        return(_resultSerializer.Deserialize(context));
                    }
                }
            }
        }
        private TCommandResult ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage)
        {
            using (new CommandMessageDisposer(responseMessage))
            {
                var rawDocument = responseMessage.Sections.OfType <Type0CommandMessageSection <RawBsonDocument> >().Single().Document;

                var binaryReaderSettings = new BsonBinaryReaderSettings();
                if (_messageEncoderSettings != null)
                {
                    binaryReaderSettings.Encoding = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict);
#pragma warning disable 618
                    if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
                    {
                        binaryReaderSettings.GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy);
                    }
#pragma warning restore 618
                }
                ;

                BsonValue clusterTime;
                if (rawDocument.TryGetValue("$clusterTime", out clusterTime))
                {
                    // note: we are assuming that _session is an instance of ClusterClockAdvancingClusterTime
                    // and that calling _session.AdvanceClusterTime will have the side effect of advancing the cluster's ClusterTime also
                    var materializedClusterTime = ((RawBsonDocument)clusterTime).Materialize(binaryReaderSettings);
                    _session.AdvanceClusterTime(materializedClusterTime);
                }

                BsonValue operationTime;
                if (rawDocument.TryGetValue("operationTime", out operationTime))
                {
                    _session.AdvanceOperationTime(operationTime.AsBsonTimestamp);
                }

                if (rawDocument.GetValue("ok", false).ToBoolean())
                {
                    if (rawDocument.TryGetValue("recoveryToken", out var rawRecoveryToken))
                    {
                        var recoveryToken = ((RawBsonDocument)rawRecoveryToken).Materialize(binaryReaderSettings);
                        _session.CurrentTransaction.RecoveryToken = recoveryToken;
                    }
                }
                else
                {
                    var materializedDocument = rawDocument.Materialize(binaryReaderSettings);

                    var commandName = _command.GetElement(0).Name;
                    if (commandName == "$query")
                    {
                        commandName = _command["$query"].AsBsonDocument.GetElement(0).Name;
                    }

                    var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, _command, materializedDocument, "errmsg");
                    if (notPrimaryOrNodeIsRecoveringException != null)
                    {
                        throw notPrimaryOrNodeIsRecoveringException;
                    }

                    var mappedException = ExceptionMapper.Map(connectionId, materializedDocument);
                    if (mappedException != null)
                    {
                        throw mappedException;
                    }

                    string    message;
                    BsonValue errmsgBsonValue;
                    if (materializedDocument.TryGetValue("errmsg", out errmsgBsonValue) && errmsgBsonValue.IsString)
                    {
                        var errmsg = errmsgBsonValue.ToString();
                        message = string.Format("Command {0} failed: {1}.", commandName, errmsg);
                    }
                    else
                    {
                        message = string.Format("Command {0} failed.", commandName);
                    }

                    var exception = new MongoCommandException(connectionId, message, _command, materializedDocument);

                    // https://jira.mongodb.org/browse/CSHARP-2678
                    if (IsRetryableWriteExceptionAndDeploymentDoesNotSupportRetryableWrites(exception))
                    {
                        throw WrapNotSupportedRetryableWriteException(exception);
                    }
                    else
                    {
                        throw exception;
                    }
                }

                if (rawDocument.Contains("writeConcernError"))
                {
                    var materializedDocument = rawDocument.Materialize(binaryReaderSettings);
                    var writeConcernError    = materializedDocument["writeConcernError"].AsBsonDocument;
                    var message            = writeConcernError.AsBsonDocument.GetValue("errmsg", null)?.AsString;
                    var writeConcernResult = new WriteConcernResult(materializedDocument);
                    throw new MongoWriteConcernException(connectionId, message, writeConcernResult);
                }

                using (var stream = new ByteBufferStream(rawDocument.Slice, ownsBuffer: false))
                {
                    using (var reader = new BsonBinaryReader(stream, binaryReaderSettings))
                    {
                        var context = BsonDeserializationContext.CreateRoot(reader);
                        return(_resultSerializer.Deserialize(context));
                    }
                }
            }
        }