// methods internal override BsonDocument CreateCommand(ICoreSessionHandle session, ConnectionDescription connectionDescription, long?transactionNumber) { var maxWireVersion = connectionDescription.MaxWireVersion; if (Feature.HintForFindAndModifyFeature.DriverMustThrowIfNotSupported(maxWireVersion) || (WriteConcern != null && !WriteConcern.IsAcknowledged)) { if (_hint != null) { throw new NotSupportedException($"Server version {WireVersion.GetServerVersionForErrorMessage(maxWireVersion)} does not support hints."); } } var writeConcern = WriteConcernHelper.GetEffectiveWriteConcern(session, WriteConcern); return(new BsonDocument { { "findAndModify", CollectionNamespace.CollectionName }, { "query", _filter }, { "update", _update }, { "new", true, _returnDocument == ReturnDocument.After }, { "sort", _sort, _sort != null }, { "fields", _projection, _projection != null }, { "upsert", true, _isUpsert }, { "maxTimeMS", () => MaxTimeHelper.ToMaxTimeMS(_maxTime.Value), _maxTime.HasValue }, { "writeConcern", writeConcern, writeConcern != null }, { "bypassDocumentValidation", () => _bypassDocumentValidation.Value, _bypassDocumentValidation.HasValue }, { "collation", () => Collation.ToBsonDocument(), Collation != null }, { "comment", Comment, Comment != null }, { "hint", _hint, _hint != null }, { "arrayFilters", () => new BsonArray(_arrayFilters), _arrayFilters != null }, { "txnNumber", () => transactionNumber, transactionNumber.HasValue }, { "let", _let, _let != null } }); }
public void ToServerVersion_with_semanticVersion_should_get_correct_serverVersion(int wireVersion, int?expectedMajorVersion, int?expectedMinorVersion) { var serverVersion = WireVersion.ToServerVersion(wireVersion); if (expectedMajorVersion.HasValue && expectedMinorVersion.HasValue) { serverVersion.Should().Be(new SemanticVersion(expectedMajorVersion.Value, expectedMinorVersion.Value, 0)); } else { serverVersion.Should().BeNull(); } }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ConnectionDescription"/> class. /// </summary> /// <param name="connectionId">The connection identifier.</param> /// <param name="helloResult">The hello result.</param> public ConnectionDescription(ConnectionId connectionId, HelloResult helloResult) { _connectionId = Ensure.IsNotNull(connectionId, nameof(connectionId)); _helloResult = Ensure.IsNotNull(helloResult, nameof(helloResult)); _compressors = Ensure.IsNotNull(_helloResult.Compressions, "compressions"); _maxBatchCount = helloResult.MaxBatchCount; _maxDocumentSize = helloResult.MaxDocumentSize; _maxMessageSize = helloResult.MaxMessageSize; _maxWireVersion = helloResult.MaxWireVersion; _minWireVersion = helloResult.MinWireVersion; _serviceId = helloResult.ServiceId; _serverVersion = WireVersion.ToServerVersion(_maxWireVersion); }
private ServerDescription CreateServerDescription( ServerId serverId = null, EndPoint endPoint = null, ServerState state = ServerState.Disconnected, ServerType type = ServerType.Unknown, int?maxWireVersion = null) { endPoint = endPoint ?? new DnsEndPoint("localhost", 27017); serverId = serverId ?? new ServerId(new ClusterId(1), endPoint); maxWireVersion = maxWireVersion ?? WireVersion.Server40; var approximateServerVersion = WireVersion.ToServerVersion(maxWireVersion.Value); return(new ServerDescription(serverId, endPoint, state: state, type: type, version: approximateServerVersion, wireVersionRange: new Optional <Range <int> >(new Range <int>(0, maxWireVersion.Value)))); }
public void ToServerVersion_should_throw_if_wireVersion_less_than_0() { var exception = Record.Exception(() => WireVersion.ToServerVersion(-1)); exception.Should().BeOfType <ArgumentOutOfRangeException>().Subject.ParamName.Should().Be("wireVersion"); }
public void GetServerVersionForErrorMessage_should_return_expected_serverVersion_message(int wireVersion, string message) { WireVersion.GetServerVersionForErrorMessage(wireVersion).Should().Be(message); }
private ICluster CreateMockReplicaSetCluster() { var clusterId = new ClusterId(1); var endPoint = new DnsEndPoint("localhost", 27017); var serverId = new ServerId(clusterId, endPoint); var maxWireVersion = Feature.Transactions.FirstSupportedWireVersion; var servers = new[] { new ServerDescription(serverId, endPoint, state: ServerState.Connected, type: ServerType.ReplicaSetPrimary, version: WireVersion.ToServerVersion(maxWireVersion), wireVersionRange: new Range <int>(0, maxWireVersion)) }; #pragma warning disable CS0618 // Type or member is obsolete var clusterDescription = new ClusterDescription(clusterId, ClusterConnectionMode.Automatic, ClusterType.ReplicaSet, servers); #pragma warning restore CS0618 // Type or member is obsolete var mockCluster = new Mock <ICluster>(); mockCluster.SetupGet(m => m.Description).Returns(clusterDescription); return(mockCluster.Object); }
private void Heartbeat(CancellationToken cancellationToken) { CommandWireProtocol <BsonDocument> helloProtocol = null; bool processAnother = true; while (processAnother && !cancellationToken.IsCancellationRequested) { HelloResult heartbeatHelloResult = null; Exception heartbeatException = null; var previousDescription = _currentDescription; try { IConnection connection; lock (_lock) { connection = _connection; } if (connection == null) { var initializedConnection = InitializeConnection(cancellationToken); lock (_lock) { if (_state.Value == State.Disposed) { try { initializedConnection.Dispose(); } catch { } throw new OperationCanceledException("The ServerMonitor has been disposed."); } _connection = initializedConnection; heartbeatHelloResult = _connection.Description.HelloResult; } } else { // If MoreToCome is true, that means we are streaming hello or legacy hello results and must // continue using the existing helloProtocol object. // Otherwise helloProtocol has either not been initialized or we may need to switch between // heartbeat commands based on the last heartbeat response. if (helloProtocol == null || helloProtocol.MoreToCome == false) { helloProtocol = InitializeHelloProtocol(connection, previousDescription?.HelloOk ?? false); } heartbeatHelloResult = GetHelloResult(connection, helloProtocol, cancellationToken); } } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { return; } catch (Exception ex) { IConnection toDispose = null; lock (_lock) { helloProtocol = null; heartbeatException = ex; _roundTripTimeMonitor.Reset(); toDispose = _connection; _connection = null; } toDispose?.Dispose(); } lock (_lock) { if (cancellationToken.IsCancellationRequested) { return; } } ServerDescription newDescription; if (heartbeatHelloResult != null) { var averageRoundTripTime = _roundTripTimeMonitor.Average; var averageRoundTripTimeRounded = TimeSpan.FromMilliseconds(Math.Round(averageRoundTripTime.TotalMilliseconds)); newDescription = _baseDescription.With( averageRoundTripTime: averageRoundTripTimeRounded, canonicalEndPoint: heartbeatHelloResult.Me, electionId: heartbeatHelloResult.ElectionId, helloOk: heartbeatHelloResult.HelloOk, lastWriteTimestamp: heartbeatHelloResult.LastWriteTimestamp, logicalSessionTimeout: heartbeatHelloResult.LogicalSessionTimeout, maxBatchCount: heartbeatHelloResult.MaxBatchCount, maxDocumentSize: heartbeatHelloResult.MaxDocumentSize, maxMessageSize: heartbeatHelloResult.MaxMessageSize, replicaSetConfig: heartbeatHelloResult.GetReplicaSetConfig(), state: ServerState.Connected, tags: heartbeatHelloResult.Tags, topologyVersion: heartbeatHelloResult.TopologyVersion, type: heartbeatHelloResult.ServerType, version: WireVersion.ToServerVersion(heartbeatHelloResult.MaxWireVersion), wireVersionRange: new Range <int>(heartbeatHelloResult.MinWireVersion, heartbeatHelloResult.MaxWireVersion)); } else { newDescription = _baseDescription.With(lastUpdateTimestamp: DateTime.UtcNow); } if (heartbeatException != null) { var topologyVersion = default(Optional <TopologyVersion>); if (heartbeatException is MongoCommandException heartbeatCommandException) { topologyVersion = TopologyVersion.FromMongoCommandException(heartbeatCommandException); } newDescription = newDescription.With(heartbeatException: heartbeatException, topologyVersion: topologyVersion); } newDescription = newDescription.With(reasonChanged: "Heartbeat", lastHeartbeatTimestamp: DateTime.UtcNow); lock (_lock) { cancellationToken.ThrowIfCancellationRequested(); SetDescription(newDescription); } processAnother = // serverSupportsStreaming (newDescription.Type != ServerType.Unknown && heartbeatHelloResult != null && heartbeatHelloResult.TopologyVersion != null) || // connectionIsStreaming (helloProtocol != null && helloProtocol.MoreToCome) || // transitionedWithNetworkError (IsNetworkError(heartbeatException) && previousDescription.Type != ServerType.Unknown); } bool IsNetworkError(Exception ex) { return(ex is MongoConnectionException mongoConnectionException && mongoConnectionException.IsNetworkException); } }