private void ParseDatabaseOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "readPreference", "writeConcern");

            var database = _collection.Database;

            if (document.Contains("readConcern"))
            {
                var readConcern = ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument);
                database = database.WithReadConcern(readConcern);
            }

            if (document.Contains("readPreference"))
            {
                var readPreference = ReadPreference.FromBsonDocument(document["readPreference"].AsBsonDocument);
                database = database.WithReadPreference(readPreference);
            }

            if (document.Contains("writeConcern"))
            {
                var writeConcern = WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument);
                database = database.WithWriteConcern(writeConcern);
            }

            // update _collection to be associated with the reconfigured database
            _collection = database.GetCollection <BsonDocument>(
                _collection.CollectionNamespace.CollectionName,
                _collection.Settings);
        }
예제 #2
0
        private void AssertValid(ConnectionString connectionString, BsonDocument definition)
        {
            if (!definition["valid"].ToBoolean())
            {
                throw new AssertionException($"The connection string '{definition["uri"]}' should be invalid.");
            }

            BsonValue readConcernValue;

            if (definition.TryGetValue("readConcern", out readConcernValue))
            {
                var readConcern = ReadConcern.FromBsonDocument((BsonDocument)readConcernValue);

                connectionString.ReadConcernLevel.Should().Be(readConcern.Level);
            }

            BsonValue writeConcernValue;

            if (definition.TryGetValue("writeConcern", out writeConcernValue))
            {
                var writeConcern = WriteConcern.FromBsonDocument(MassageWriteConcernDocument((BsonDocument)writeConcernValue));

                connectionString.W.Should().Be(writeConcern.W);
                connectionString.WTimeout.Should().Be(writeConcern.WTimeout);
                connectionString.Journal.Should().Be(writeConcern.Journal);
                connectionString.FSync.Should().Be(writeConcern.FSync);
            }
        }
예제 #3
0
        private TransactionOptions ParseTransactionOptions(BsonDocument document)
        {
            ReadConcern    readConcern    = null;
            ReadPreference readPreference = null;
            WriteConcern   writeConcern   = null;

            foreach (var element in document)
            {
                switch (element.Name)
                {
                case "readConcern":
                    readConcern = ReadConcern.FromBsonDocument(element.Value.AsBsonDocument);
                    break;

                case "readPreference":
                    readPreference = ReadPreference.FromBsonDocument(element.Value.AsBsonDocument);
                    break;

                case "writeConcern":
                    writeConcern = WriteConcern.FromBsonDocument(element.Value.AsBsonDocument);
                    break;

                default:
                    throw new ArgumentException($"Invalid field: {element.Name}.");
                }
            }

            return(new TransactionOptions(readConcern, readPreference, writeConcern));
        }
예제 #4
0
        // private methods
        private TransactionOptions ParseTransactionOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "readPreference", "writeConcern", "maxCommitTimeMS");

            var options = new TransactionOptions();

            if (document.Contains("readConcern"))
            {
                options = options.With(readConcern: ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument));
            }

            if (document.Contains("readPreference"))
            {
                options = options.With(readPreference: ReadPreference.FromBsonDocument(document["readPreference"].AsBsonDocument));
            }

            if (document.Contains("writeConcern"))
            {
                options = options.With(writeConcern: WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument));
            }

            if (document.Contains("maxCommitTimeMS"))
            {
                options = options.With(maxCommitTime: TimeSpan.FromMilliseconds(document["maxCommitTimeMS"].ToInt32()));
            }

            return(options);
        }
        private TransactionOptions ParseTransactionOptions(BsonDocument document)
        {
            ReadConcern    readConcern     = null;
            ReadPreference readPreference  = null;
            WriteConcern   writeConcern    = null;
            TimeSpan?      maxCommitTimeMS = null;

            foreach (var element in document)
            {
                switch (element.Name)
                {
                case "readConcern":
                    readConcern = ReadConcern.FromBsonDocument(element.Value.AsBsonDocument);
                    break;

                case "readPreference":
                    readPreference = ReadPreference.FromBsonDocument(element.Value.AsBsonDocument);
                    break;

                case "writeConcern":
                    writeConcern = WriteConcern.FromBsonDocument(element.Value.AsBsonDocument);
                    break;

                case "maxCommitTimeMS":
                    maxCommitTimeMS = TimeSpan.FromMilliseconds(element.Value.ToInt32());
                    break;

                default:
                    throw new ArgumentException($"Invalid field: {element.Name}.");
                }
            }

            return(new TransactionOptions(readConcern, readPreference, writeConcern, maxCommitTimeMS));
        }
예제 #6
0
        private IMongoCollection <BsonDocument> CreateCollection(BsonDocument entity, Dictionary <string, IMongoDatabase> databases)
        {
            string                  collectionName = null;
            IMongoDatabase          database       = null;
            MongoCollectionSettings settings       = null;

            foreach (var element in entity)
            {
                switch (element.Name)
                {
                case "id":
                    // handled on higher level
                    break;

                case "database":
                    var databaseId = entity["database"].AsString;
                    database = databases[databaseId];
                    break;

                case "collectionName":
                    collectionName = entity["collectionName"].AsString;
                    break;

                case "collectionOptions":
                    settings = new MongoCollectionSettings();
                    foreach (var option in element.Value.AsBsonDocument)
                    {
                        switch (option.Name)
                        {
                        case "readConcern":
                            settings.ReadConcern = ReadConcern.FromBsonDocument(option.Value.AsBsonDocument);
                            break;

                        case "readPreference":
                            settings.ReadPreference = ReadPreference.FromBsonDocument(option.Value.AsBsonDocument);
                            break;

                        case "writeConcern":
                            settings.WriteConcern = WriteConcern.FromBsonDocument(option.Value.AsBsonDocument);
                            break;

                        default:
                            throw new FormatException($"Invalid collection option argument name: '{option.Name}'.");
                        }
                    }
                    break;

                default:
                    throw new FormatException($"Invalid collection argument name: '{element.Name}'.");
                }
            }

            return(database.GetCollection <BsonDocument>(collectionName, settings));
        }
예제 #7
0
        // private methods
        private void SetOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "writeConcern");

            if (document.Contains("readConcern"))
            {
                _options = _options.With(readConcern: ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument));
            }

            if (document.Contains("writeConcern"))
            {
                _options = _options.With(writeConcern: WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument));
            }
        }
예제 #8
0
        // protected methods
        protected override void SetArgument(string name, BsonValue value)
        {
            switch (name)
            {
            case "readPreference":
                SetReadPreference(ReadPreference.FromBsonDocument(value.AsBsonDocument));
                return;

            case "writeConcern":
                SetWriteConcern(WriteConcern.FromBsonDocument(value.AsBsonDocument));
                return;
            }

            base.SetArgument(name, value);
        }
예제 #9
0
        protected override bool TrySetArgument(string name, BsonValue value)
        {
            switch (name)
            {
            case "document":
                _document = (BsonDocument)value;
                return(true);

            case "writeConcern":
                _writeConcern = WriteConcern.FromBsonDocument((BsonDocument)value);
                return(true);
            }

            return(false);
        }
예제 #10
0
        protected override bool TrySetArgument(string name, BsonValue value)
        {
            switch (name)
            {
            case "documents":
                _documents = ((BsonArray)value).OfType <BsonDocument>();
                return(true);

            case "options":
                _options = ParseOptions(value.AsBsonDocument);
                return(true);

            case "writeConcern":
                _writeConcern = WriteConcern.FromBsonDocument((BsonDocument)value);
                return(true);
            }

            return(false);
        }
예제 #11
0
        protected override bool TrySetArgument(string name, BsonValue value)
        {
            switch (name)
            {
            case "documents":
                _documents = ((BsonArray)value).OfType <BsonDocument>();
                return(true);

            case "ordered":
                _options.IsOrdered = value.ToBoolean();
                return(true);

            case "writeConcern":
                _writeConcern = WriteConcern.FromBsonDocument((BsonDocument)value);
                return(true);
            }

            return(false);
        }
        private MongoCollectionSettings ParseCollectionSettings(BsonDocument collectionOptions)
        {
            var settings = new MongoCollectionSettings();

            foreach (var collectionOption in collectionOptions.Elements)
            {
                switch (collectionOption.Name)
                {
                case "writeConcern":
                    settings.WriteConcern = WriteConcern.FromBsonDocument(collectionOption.Value.AsBsonDocument);
                    break;

                default:
                    throw new FormatException($"Unexpected collection option: {collectionOption.Name}.");
                }
            }

            return(settings);
        }
예제 #13
0
        private void ParseCollectionOptions(MongoCollectionSettings settings, BsonDocument collectionOptions)
        {
            foreach (var collectionOption in collectionOptions.Elements)
            {
                switch (collectionOption.Name)
                {
                case "readConcern":
                    settings.ReadConcern = ReadConcern.FromBsonDocument(collectionOption.Value.AsBsonDocument);
                    break;

                case "writeConcern":
                    settings.WriteConcern = WriteConcern.FromBsonDocument(collectionOption.Value.AsBsonDocument);
                    break;

                default:
                    throw new FormatException($"Unexpected collection option: {collectionOption.Name}");
                }
            }
        }
예제 #14
0
        protected override bool TrySetArgument(string name, BsonValue value)
        {
            switch (name)
            {
            case "requests":
                _requests = ParseRequests((BsonArray)value).ToList();
                return(true);

            case "ordered":
                _options.IsOrdered = value.ToBoolean();
                return(true);

            case "writeConcern":
                _writeConcern = WriteConcern.FromBsonDocument((BsonDocument)value);
                return(true);
            }

            return(false);
        }
        // private methods
        private void ParseCollectionOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "readPreference", "writeConcern");

            if (document.Contains("readConcern"))
            {
                var readConcern = ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument);
                _collection = _collection.WithReadConcern(readConcern);
            }

            if (document.Contains("readPreference"))
            {
                var readPreference = ReadPreference.FromBsonDocument(document["readPreference"].AsBsonDocument);
                _collection = _collection.WithReadPreference(readPreference);
            }

            if (document.Contains("writeConcern"))
            {
                var writeConcern = WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument);
                _collection = _collection.WithWriteConcern(writeConcern);
            }
        }
예제 #16
0
        protected override bool TrySetArgument(string name, BsonValue value)
        {
            switch (name)
            {
            case "filter":
                _filter = (BsonDocument)value;
                return(true);

            case "update":
                _update = (BsonDocument)value;
                return(true);

            case "upsert":
                _options.IsUpsert = value.ToBoolean();
                return(true);

            case "writeConcern":
                _writeConcern = WriteConcern.FromBsonDocument((BsonDocument)value);
                return(true);
            }

            return(false);
        }
        // private methods
        private void SetOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "readPreference", "writeConcern");

            var options = new TransactionOptions();

            if (document.Contains("readConcern"))
            {
                options = options.With(readConcern: ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument));
            }

            if (document.Contains("readPreference"))
            {
                options = options.With(readPreference: ReadPreference.FromBsonDocument(document["readPreference"].AsBsonDocument));
            }

            if (document.Contains("writeConcern"))
            {
                options = options.With(writeConcern: WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument));
            }

            _options = options;
        }
        private bool TryGetWriteConcernFromGLE(Queue <RequestMessage> messageQueue, out int requestId, out WriteConcern writeConcern)
        {
            requestId    = -1;
            writeConcern = null;
            if (messageQueue.Count == 0)
            {
                return(false);
            }

            var message = messageQueue.Peek();

            if (message.MessageType != MongoDBMessageType.Query)
            {
                return(false);
            }

            var queryMessage = (QueryMessage)message;

            if (!IsCommand(queryMessage.CollectionNamespace))
            {
                return(false);
            }

            var query        = queryMessage.Query;
            var firstElement = query.GetElement(0);

            if (firstElement.Name != "getLastError")
            {
                return(false);
            }

            messageQueue.Dequeue(); // consume it so that we don't process it later...
            requestId = queryMessage.RequestId;

            writeConcern = WriteConcern.FromBsonDocument(query);
            return(true);
        }
예제 #19
0
        public UnifiedWithTransactionOperation Build(string targetSessionId, BsonDocument arguments)
        {
            var session = _entityMap.GetSession(targetSessionId);

            BsonArray          operations = null;
            TransactionOptions options    = null;

            foreach (var argument in arguments)
            {
                switch (argument.Name)
                {
                case "callback":
                    operations = argument.Value.AsBsonArray;
                    break;

                case "readConcern":
                    options = options ?? new TransactionOptions();
                    options = options.With(readConcern: ReadConcern.FromBsonDocument(argument.Value.AsBsonDocument));
                    break;

                case "readPreference":
                    options = options ?? new TransactionOptions();
                    options = options.With(readPreference: ReadPreference.FromBsonDocument(argument.Value.AsBsonDocument));
                    break;

                case "writeConcern":
                    options = options ?? new TransactionOptions();
                    options = options.With(writeConcern: WriteConcern.FromBsonDocument(argument.Value.AsBsonDocument));
                    break;

                default:
                    throw new FormatException($"Invalid WithTransactionOperation argument name: '{argument.Name}'.");
                }
            }

            return(new UnifiedWithTransactionOperation(session, operations, options));
        }
예제 #20
0
        private void ValidateWriteConcern(BsonDocument definition)
        {
            Exception    parseException = null;
            WriteConcern writeConcern   = null;

            try
            {
                writeConcern = WriteConcern.FromBsonDocument(MassageWriteConcernDocument((BsonDocument)definition["writeConcern"]));
            }
            catch (Exception ex)
            {
                parseException = ex;
            }

            if (parseException == null)
            {
                if (!(bool)definition["valid"])
                {
                    throw new AssertionException($"Should be invalid: {definition["writeConcern"]}.");
                }

                var expectedDocument = (BsonDocument)definition["writeConcernDocument"];
                var document         = writeConcern.ToBsonDocument();
                document.Should().Be(expectedDocument);

                writeConcern.IsServerDefault.Should().Be((bool)definition["isServerDefault"]);
                writeConcern.IsAcknowledged.Should().Be((bool)definition["isAcknowledged"]);
            }
            else
            {
                if ((bool)definition["valid"])
                {
                    throw new AssertionException($"Should be valid: {definition["writeConcern"]}.");
                }
            }
        }
예제 #21
0
        private IClientSessionHandle CreateSession(BsonDocument entity, Dictionary <string, DisposableMongoClient> clients)
        {
            IMongoClient         client  = null;
            ClientSessionOptions options = null;

            foreach (var element in entity)
            {
                switch (element.Name)
                {
                case "id":
                    // handled on higher level
                    break;

                case "client":
                    var clientId = element.Value.AsString;
                    client = clients[clientId];
                    break;

                case "sessionOptions":
                    options = new ClientSessionOptions();
                    foreach (var option in element.Value.AsBsonDocument)
                    {
                        switch (option.Name)
                        {
                        case "snapshot":
                            options.Snapshot = option.Value.ToBoolean();
                            break;

                        case "causalConsistency":
                            options.CausalConsistency = option.Value.ToBoolean();
                            break;

                        case "defaultTransactionOptions":
                            ReadConcern    readConcern    = null;
                            ReadPreference readPreference = null;
                            WriteConcern   writeConcern   = null;
                            foreach (var transactionOption in option.Value.AsBsonDocument)
                            {
                                switch (transactionOption.Name)
                                {
                                case "readConcern":
                                    readConcern = ReadConcern.FromBsonDocument(transactionOption.Value.AsBsonDocument);
                                    break;

                                case "readPreference":
                                    readPreference = ReadPreference.FromBsonDocument(transactionOption.Value.AsBsonDocument);
                                    break;

                                case "writeConcern":
                                    writeConcern = WriteConcern.FromBsonDocument(transactionOption.Value.AsBsonDocument);
                                    break;

                                default:
                                    throw new FormatException($"Invalid session transaction option: '{transactionOption.Name}'.");
                                }
                            }
                            options.DefaultTransactionOptions = new TransactionOptions(readConcern, readPreference, writeConcern);
                            break;

                        default:
                            throw new FormatException($"Invalid session option argument name: '{option.Name}'.");
                        }
                    }
                    break;

                default:
                    throw new FormatException($"Invalid session argument name: '{element.Name}'.");
                }
            }

            var session = client.StartSession(options);

            return(session);
        }
        private Type0CommandMessageSection <BsonDocument> CreateType0Section(ConnectionDescription connectionDescription)
        {
            var extraElements = new List <BsonElement>();

            AddIfNotAlreadyAdded("$db", _databaseNamespace.DatabaseName);

            if (connectionDescription.IsMasterResult.ServerType != ServerType.Standalone &&
                _readPreference != null &&
                _readPreference != ReadPreference.Primary)
            {
                var readPreferenceDocument = QueryHelper.CreateReadPreferenceDocument(_readPreference);
                AddIfNotAlreadyAdded("$readPreference", readPreferenceDocument);
            }

            if (_session.Id != null)
            {
                if (IsSessionAcknowledged())
                {
                    AddIfNotAlreadyAdded("lsid", _session.Id);
                }
                else
                {
                    if (_session.IsImplicit)
                    {
                        // do not set sessionId if session is implicit and write is unacknowledged
                    }
                    else
                    {
                        throw new InvalidOperationException("Explicit session must not be used with unacknowledged writes.");
                    }
                }
            }

            if (_session.ClusterTime != null)
            {
                AddIfNotAlreadyAdded("$clusterTime", _session.ClusterTime);
            }
#pragma warning disable 618
            Action <BsonWriterSettings> writerSettingsConfigurator = null;
            if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
            {
                writerSettingsConfigurator = s => s.GuidRepresentation = GuidRepresentation.Unspecified;
            }
#pragma warning restore 618

            _session.AboutToSendCommand();
            if (_session.IsInTransaction)
            {
                var transaction = _session.CurrentTransaction;
                AddIfNotAlreadyAdded("txnNumber", transaction.TransactionNumber);
                if (transaction.State == CoreTransactionState.Starting)
                {
                    AddIfNotAlreadyAdded("startTransaction", true);
                    var readConcern = ReadConcernHelper.GetReadConcernForFirstCommandInTransaction(_session, connectionDescription);
                    if (readConcern != null)
                    {
                        AddIfNotAlreadyAdded("readConcern", readConcern);
                    }
                }
                AddIfNotAlreadyAdded("autocommit", false);
            }

            var elementAppendingSerializer = new ElementAppendingSerializer <BsonDocument>(BsonDocumentSerializer.Instance, extraElements, writerSettingsConfigurator);
            return(new Type0CommandMessageSection <BsonDocument>(_command, elementAppendingSerializer));

            void AddIfNotAlreadyAdded(string key, BsonValue value)
            {
                if (!_command.Contains(key))
                {
                    extraElements.Add(new BsonElement(key, value));
                }
            }

            bool IsSessionAcknowledged()
            {
                if (_command.TryGetValue("writeConcern", out var writeConcernDocument))
                {
                    var writeConcern = WriteConcern.FromBsonDocument(writeConcernDocument.AsBsonDocument);
                    return(writeConcern.IsAcknowledged);
                }
                else
                {
                    return(true);
                }
            }
        }