Пример #1
0
        public void GetChannel_should_update_topology_and_clear_connection_pool_on_network_error_or_timeout(
            [Values("TimedOutSocketException", "NetworkUnreachableSocketException")] string errorType,
            [Values(false, true)] bool async)
        {
            var serverId           = new ServerId(_clusterId, _endPoint);
            var connectionId       = new ConnectionId(serverId);
            var innerMostException = CoreExceptionHelper.CreateException(errorType);

            var openConnectionException = new MongoConnectionException(connectionId, "Oops", new IOException("Cry", innerMostException));
            var mockConnection          = new Mock <IConnectionHandle>();

            mockConnection.Setup(c => c.Open(It.IsAny <CancellationToken>())).Throws(openConnectionException);
            mockConnection.Setup(c => c.OpenAsync(It.IsAny <CancellationToken>())).ThrowsAsync(openConnectionException);

            var connectionFactory = new Mock <IConnectionFactory>();

            connectionFactory.Setup(cf => cf.CreateConnection(serverId, _endPoint)).Returns(mockConnection.Object);

            var mockExceptionHandler   = new Mock <IConnectionExceptionHandler>();
            var connectionPoolSettings = new ConnectionPoolSettings();
            var connectionPool         = new ExclusiveConnectionPool(serverId, _endPoint, connectionPoolSettings, connectionFactory.Object, new EventAggregator(), mockExceptionHandler.Object);

            var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>();

            mockConnectionPoolFactory
            .Setup(f => f.CreateConnectionPool(It.IsAny <ServerId>(), _endPoint, It.IsAny <IConnectionExceptionHandler>()))
            .Returns(connectionPool);
            var mockMonitorServerDescription = new ServerDescription(serverId, _endPoint);
            var mockServerMonitor            = new Mock <IServerMonitor>();

            mockServerMonitor.SetupGet(m => m.Description).Returns(mockMonitorServerDescription);
            mockServerMonitor.SetupGet(m => m.Lock).Returns(new object());
            var mockServerMonitorFactory = new Mock <IServerMonitorFactory>();

            mockServerMonitorFactory.Setup(f => f.Create(It.IsAny <ServerId>(), _endPoint)).Returns(mockServerMonitor.Object);

            var subject = new DefaultServer(_clusterId, _clusterClock, _clusterConnectionMode, _connectionModeSwitch, _directConnection, _settings, _endPoint, mockConnectionPoolFactory.Object, mockServerMonitorFactory.Object, _capturedEvents, _serverApi);

            connectionPool._connectionExceptionHandler(subject);
            subject.Initialize();
            connectionPool.SetReady();

            IChannelHandle channel = null;
            Exception      exception;

            if (async)
            {
                exception = Record.Exception(() => channel = subject.GetChannelAsync(CancellationToken.None).GetAwaiter().GetResult());
            }
            else
            {
                exception = Record.Exception(() => channel = subject.GetChannel(CancellationToken.None));
            }

            channel.Should().BeNull();
            exception.Should().Be(openConnectionException);
            subject.Description.Type.Should().Be(ServerType.Unknown);
            subject.Description.ReasonChanged.Should().Contain("ChannelException during handshake");
        }
Пример #2
0
 public static bool ShouldInvalidateServer(this DefaultServer server,
                                           IConnection connection,
                                           Exception exception,
                                           ServerDescription description,
                                           out TopologyVersion responseTopologyVersion)
 {
     return((bool)Reflector.Invoke(server, nameof(ShouldInvalidateServer), connection, exception, description, out responseTopologyVersion));
 }
Пример #3
0
        public void Equals_should_return_true_when_all_fields_are_equal()
        {
            ServerDescription subject            = new ServerDescription(__serverId, __endPoint);
            ServerDescription serverDescription2 = new ServerDescription(__serverId, __endPoint);

            subject.Equals(serverDescription2).Should().BeTrue();
            subject.Equals((object)serverDescription2).Should().BeTrue();
            subject.GetHashCode().Should().Be(serverDescription2.GetHashCode());
        }
Пример #4
0
        private bool ShouldInvalidateServer(
            IConnection connection,
            Exception exception,
            ServerDescription description,
            out TopologyVersion invalidatingResponseTopologyVersion)
        {
            if (exception is MongoConnectionException mongoConnectionException &&
                mongoConnectionException.ContainsTimeoutException)
            {
                invalidatingResponseTopologyVersion = null;
                return(false);
            }

            if (__invalidatingExceptions.Contains(exception.GetType()))
            {
                invalidatingResponseTopologyVersion = null;
                return(true);
            }

            var exceptionsToCheck = new[]
            {
                exception as MongoCommandException,
                (exception as MongoWriteConcernException)?.MappedWriteConcernResultException
            }
            .OfType <MongoCommandException>();

            foreach (MongoCommandException commandException in exceptionsToCheck)
            {
                if (IsStateChangeException(commandException))
                {
                    return(!IsStaleStateChangeError(commandException.Result, out invalidatingResponseTopologyVersion));
                }
            }

            invalidatingResponseTopologyVersion = null;
            return(false);

            bool IsStaleStateChangeError(BsonDocument response, out TopologyVersion nonStaleResponseTopologyVersion)
            {
                if (ConnectionPool.Generation > connection.Generation)
                {
                    // stale generation number
                    nonStaleResponseTopologyVersion = null;
                    return(true);
                }

                var responseTopologyVersion = TopologyVersion.FromMongoCommandResponse(response);
                // We use FresherThanOrEqualTo instead of FresherThan because a state change should come with a new
                // topology version.
                // We cannot use StalerThan(responseTopologyVersion, description.TopologyVersion) because due to how
                // TopologyVersions comparisons are defined, FresherThanOrEqualTo(x, y) does not imply StalerThan(y, x)
                bool isStale = TopologyVersion.IsFresherThanOrEqualTo(description.TopologyVersion, responseTopologyVersion);

                nonStaleResponseTopologyVersion = isStale ? null : responseTopologyVersion;
                return(isStale);
            }
        }
Пример #5
0
        public void A_description_changed_event_with_a_heartbeat_exception_should_clear_the_connection_pool()
        {
            _subject.Initialize();
            var description = new ServerDescription(_subject.ServerId, _subject.EndPoint)
                              .With(heartbeatException: new Exception("ughhh"));

            _serverMonitor.DescriptionChanged += Raise.EventWith(new ServerDescriptionChangedEventArgs(description, description));

            _connectionPool.Received().Clear();
        }
Пример #6
0
        public void A_description_changed_event_with_a_heartbeat_exception_should_clear_the_connection_pool()
        {
            _subject.Initialize();
            var description = new ServerDescription(_subject.ServerId, _subject.EndPoint)
                              .With(heartbeatException: new Exception("ughhh"));

            _mockServerMonitor.Raise(m => m.DescriptionChanged += null, new ServerDescriptionChangedEventArgs(description, description));

            _mockConnectionPool.Verify(p => p.Clear(), Times.Once);
        }
        public void MaxWireVersion_should_be_the_same_as_wireVersionRange_max()
        {
            var clusterId        = new ClusterId(1);
            var endPoint         = new DnsEndPoint("localhost", 27017);
            var serverId         = new ServerId(clusterId, endPoint);
            var wireVersionRange = new Range <int>(0, 14);

            var subject = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange, type: ServerType.Standalone);

            subject.MaxWireVersion.Should().Be(wireVersionRange.Max);
        }
Пример #8
0
        private void SetDescriptionIfChanged(ServerDescription newDescription)
        {
            var oldDescription = Interlocked.CompareExchange(ref _currentDescription, null, null);

            if (oldDescription.Equals(newDescription))
            {
                return;
            }

            SetDescription(oldDescription, newDescription);
        }
Пример #9
0
        private void OnDescriptionChanged(ServerDescription oldDescription, ServerDescription newDescription)
        {
            var handler = DescriptionChanged;

            if (handler != null)
            {
                var args = new ServerDescriptionChangedEventArgs(oldDescription, newDescription);
                try { handler(this, args); }
                catch { } // ignore exceptions
            }
        }
Пример #10
0
        public void IsCompatibleWithDriver_should_return_expected_result(int[] minMaxWireVersions, bool expectedResult)
        {
            var clusterId        = new ClusterId(1);
            var endPoint         = new DnsEndPoint("localhost", 27017);
            var serverId         = new ServerId(clusterId, endPoint);
            var wireVersionRange = minMaxWireVersions == null ? null : new Range <int>(minMaxWireVersions[0], minMaxWireVersions[1]);
            var subject          = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange);

            var result = subject.IsCompatibleWithDriver;

            result.Should().Be(expectedResult);
        }
Пример #11
0
        public void WithHeartbeat_should_return_new_instance_when_a_field_is_not_equal(string notEqualField)
        {
            var averageRoundTripTime = TimeSpan.FromSeconds(1);
            var replicaSetConfig     = new ReplicaSetConfig(
                new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) },
                "name",
                new DnsEndPoint("localhost", 27017),
                1);
            var state            = ServerState.Connected;
            var tags             = new TagSet(new[] { new Tag("x", "a") });
            var type             = ServerType.ReplicaSetPrimary;
            var version          = new SemanticVersion(2, 6, 3);
            var wireVersionRange = new Range <int>(2, 3);

            var subject = new ServerDescription(
                __serverId,
                __endPoint,
                state: state,
                type: type,
                averageRoundTripTime: averageRoundTripTime,
                replicaSetConfig: replicaSetConfig,
                tags: tags,
                version: version,
                wireVersionRange: wireVersionRange);

            switch (notEqualField)
            {
            case "AverageRoundTripTime": averageRoundTripTime = averageRoundTripTime.Add(TimeSpan.FromSeconds(1)); break;

            case "ReplicaSetConfig": replicaSetConfig = new ReplicaSetConfig(replicaSetConfig.Members, "newname", replicaSetConfig.Primary, replicaSetConfig.Version); break;

            case "Tags": tags = new TagSet(new[] { new Tag("x", "b") }); break;

            case "Type": type = ServerType.ReplicaSetSecondary; break;

            case "Version": version = new SemanticVersion(version.Major, version.Minor, version.Patch + 1); break;

            case "WireVersionRange": wireVersionRange = new Range <int>(0, 0); break;
            }

            var serverDescription2 = subject.With(
                averageRoundTripTime: averageRoundTripTime,
                replicaSetConfig: replicaSetConfig,
                state: ServerState.Connected,
                tags: tags,
                type: type,
                version: version,
                wireVersionRange: wireVersionRange);

            subject.Equals(serverDescription2).Should().BeFalse();
            subject.Equals((object)serverDescription2).Should().BeFalse();
            subject.GetHashCode().Should().NotBe(serverDescription2.GetHashCode());
        }
        // constructors
        public ClusterableServer(ServerSettings settings, ClusterId clusterId, EndPoint endPoint, IConnectionPoolFactory connectionPoolFactory, IConnectionFactory hearbeatConnectionFactory, IServerListener listener)
        {
            _settings = Ensure.IsNotNull(settings, "settings");;
            Ensure.IsNotNull(clusterId, "clusterId");
            _endPoint = Ensure.IsNotNull(endPoint, "endPoint");
            _connectionPoolFactory      = Ensure.IsNotNull(connectionPoolFactory, "connectionPoolFactory");
            _heartbeatConnectionFactory = Ensure.IsNotNull(hearbeatConnectionFactory, "hearbeatConnectionFactory");
            _listener = listener;

            _serverId        = new ServerId(clusterId, endPoint);
            _baseDescription = _currentDescription = new ServerDescription(_serverId, endPoint);
            _connectionPool  = connectionPoolFactory.CreateConnectionPool(_serverId, endPoint);
            _state           = new InterlockedInt32(State.Initial);
        }
Пример #13
0
 // static constructor
 static ServerDescriptionTests()
 {
     __clusterId = new ClusterId();
     __endPoint  = new DnsEndPoint("localhost", 27017);
     __serverId  = new ServerId(__clusterId, __endPoint);
     __subject   = new ServerDescription(
         __serverId,
         __endPoint,
         state: ServerState.Connected,
         type: ServerType.Standalone,
         averageRoundTripTime: TimeSpan.FromSeconds(1),
         version: new SemanticVersion(2, 6, 3),
         wireVersionRange:  new Range <int>(0, 2));
 }
Пример #14
0
        public static bool ShouldInvalidateServer(this Server server,
                                                  IConnectionHandle connection,
                                                  Exception exception,
                                                  ServerDescription description,
                                                  out TopologyVersion responseTopologyVersion)
        {
            var methodInfo        = typeof(Server).GetMethod(nameof(ShouldInvalidateServer), BindingFlags.NonPublic | BindingFlags.Instance);
            var parameters        = new object[] { connection, exception, description, null };
            int outParameterIndex = Array.IndexOf(parameters, null);
            var shouldInvalidate  = (bool)methodInfo.Invoke(server, parameters);

            responseTopologyVersion = (TopologyVersion)parameters[outParameterIndex];
            return(shouldInvalidate);
        }
Пример #15
0
        public void Constructor_with_serverId_and_endPoint_only_should_return_disconnected_instance()
        {
            var subject = new ServerDescription(__serverId, __endPoint);

            subject.AverageRoundTripTime.Should().Be(TimeSpan.Zero);
            subject.EndPoint.Should().Be(__endPoint);
            subject.ReplicaSetConfig.Should().BeNull();
            subject.ServerId.Should().Be(__serverId);
            subject.State.Should().Be(ServerState.Disconnected);
            subject.Tags.Should().BeNull();
            subject.Type.Should().Be(ServerType.Unknown);
            subject.Version.Should().BeNull();
            subject.WireVersionRange.Should().BeNull();
        }
Пример #16
0
        public ServerMonitor(ServerId serverId, EndPoint endPoint, IConnectionFactory connectionFactory, TimeSpan heartbeatInterval, TimeSpan timeout, IEventSubscriber eventSubscriber)
        {
            _serverId          = Ensure.IsNotNull(serverId, nameof(serverId));
            _endPoint          = Ensure.IsNotNull(endPoint, nameof(endPoint));
            _connectionFactory = Ensure.IsNotNull(connectionFactory, nameof(connectionFactory));
            Ensure.IsNotNull(eventSubscriber, nameof(eventSubscriber));

            _baseDescription   = _currentDescription = new ServerDescription(_serverId, endPoint, heartbeatInterval: heartbeatInterval);
            _heartbeatInterval = heartbeatInterval;
            _timeout           = timeout;
            _state             = new InterlockedInt32(State.Initial);
            eventSubscriber.TryGetEventHandler(out _heartbeatStartedEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatSucceededEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatFailedEventHandler);
        }
Пример #17
0
 // static constructor
 static ServerDescriptionTests()
 {
     __clusterId = new ClusterId();
     __endPoint  = new DnsEndPoint("localhost", 27017);
     __serverId  = new ServerId(__clusterId, __endPoint);
     __subject   = new ServerDescription(
         __serverId,
         __endPoint,
         ServerState.Connected,
         ServerType.Standalone,
         TimeSpan.FromSeconds(1),
         null,
         null,
         new SemanticVersion(2, 6, 3),
         new Range <int>(0, 2));
 }
        public void Constructor_with_multiple_parameters_should_return_properly_initialized_instance()
        {
            var averageRoundTripTime = TimeSpan.FromSeconds(1);
            var canonicalEndPoint    = new DnsEndPoint("localhost", 27017);
            var electionId           = new ElectionId(ObjectId.GenerateNewId());
            var helloOk = true;
            var logicalSessionTimeout = TimeSpan.FromMinutes(1);
            var replicaSetConfig      = new ReplicaSetConfig(
                new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) },
                "name",
                new DnsEndPoint("localhost", 27017),
                1);
            var state            = ServerState.Connected;
            var tags             = new TagSet(new[] { new Tag("x", "a") });
            var type             = ServerType.ReplicaSetPrimary;
            var version          = new SemanticVersion(3, 6, 0);
            var wireVersionRange = new Range <int>(6, 14);

            var subject = new ServerDescription(
                __serverId,
                __endPoint,
                state: state,
                type: type,
                averageRoundTripTime: averageRoundTripTime,
                canonicalEndPoint: canonicalEndPoint,
                electionId: electionId,
                helloOk: helloOk,
                logicalSessionTimeout: logicalSessionTimeout,
                replicaSetConfig: replicaSetConfig,
                tags: tags,
                version: version,
                wireVersionRange: wireVersionRange);

            subject.AverageRoundTripTime.Should().Be(TimeSpan.FromSeconds(1));
            subject.CanonicalEndPoint.Should().Be(canonicalEndPoint);
            subject.ElectionId.Should().Be(electionId);
            subject.EndPoint.Should().Be(__endPoint);
            subject.HelloOk.Should().Be(helloOk);
            subject.LogicalSessionTimeout.Should().Be(logicalSessionTimeout);
            subject.ReplicaSetConfig.Should().Be(replicaSetConfig);
            subject.ServerId.Should().Be(__serverId);
            subject.State.Should().Be(state);
            subject.Tags.Should().Be(tags);
            subject.Type.Should().Be(type);
        }
        public void Equals_should_return_true_when_all_fields_are_equal()
        {
            var lastUpdateTimestamp   = DateTime.UtcNow;
            ServerDescription subject = new ServerDescription(
                __serverId,
                __endPoint,
                type: ServerType.Standalone,
                lastUpdateTimestamp: lastUpdateTimestamp);
            ServerDescription serverDescription2 = new ServerDescription(
                __serverId,
                __endPoint,
                type: ServerType.Standalone,
                lastUpdateTimestamp: lastUpdateTimestamp);

            subject.Equals(serverDescription2).Should().BeTrue();
            subject.Equals((object)serverDescription2).Should().BeTrue();
            subject.GetHashCode().Should().Be(serverDescription2.GetHashCode());
        }
Пример #20
0
        private void OnDescriptionChanged(ServerDescription newDescription)
        {
            var oldDescription = Interlocked.CompareExchange(ref _currentDescription, null, null);

            if (oldDescription.Equals(newDescription))
            {
                return;
            }
            Interlocked.Exchange(ref _currentDescription, newDescription);

            var handler = DescriptionChanged;

            if (handler != null)
            {
                var args = new ServerDescriptionChangedEventArgs(oldDescription, newDescription);
                try { handler(this, args); }
                catch { } // ignore exceptions
            }
        }
        public void With_should_return_same_instance_when_all_fields_are_equal()
        {
            var averageRoundTripTime = TimeSpan.FromSeconds(1);
            var helloOk             = true;
            var lastUpdateTimestamp = DateTime.UtcNow;
            var replicaSetConfig    = new ReplicaSetConfig(
                new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) },
                "name",
                new DnsEndPoint("localhost", 27017),
                1);
            var state            = ServerState.Connected;
            var tags             = new TagSet(new[] { new Tag("x", "a") });
            var type             = ServerType.ReplicaSetPrimary;
            var version          = new SemanticVersion(3, 6, 0);
            var wireVersionRange = new Range <int>(6, 14);

            var subject = new ServerDescription(
                __serverId,
                __endPoint,
                averageRoundTripTime: averageRoundTripTime,
                helloOk: helloOk,
                lastUpdateTimestamp: lastUpdateTimestamp,
                replicaSetConfig: replicaSetConfig,
                state: state,
                tags: tags,
                type: type,
                version: version,
                wireVersionRange: wireVersionRange);

            var result = subject.With(
                averageRoundTripTime: averageRoundTripTime,
                helloOk: helloOk,
                lastUpdateTimestamp: lastUpdateTimestamp,
                replicaSetConfig: replicaSetConfig,
                state: ServerState.Connected,
                tags: tags,
                type: type,
                version: version,
                wireVersionRange: wireVersionRange);

            result.ShouldBeEquivalentTo(subject);
        }
Пример #22
0
        public ServerMonitor(ServerId serverId, EndPoint endPoint, IConnectionFactory connectionFactory, ServerMonitorSettings serverMonitorSettings, IEventSubscriber eventSubscriber, IRoundTripTimeMonitor roundTripTimeMonitor)
        {
            _monitorCancellationTokenSource = new CancellationTokenSource();
            _serverId          = Ensure.IsNotNull(serverId, nameof(serverId));
            _endPoint          = Ensure.IsNotNull(endPoint, nameof(endPoint));
            _connectionFactory = Ensure.IsNotNull(connectionFactory, nameof(connectionFactory));
            Ensure.IsNotNull(eventSubscriber, nameof(eventSubscriber));
            _serverMonitorSettings = Ensure.IsNotNull(serverMonitorSettings, nameof(serverMonitorSettings));

            _baseDescription      = _currentDescription = new ServerDescription(_serverId, endPoint, reasonChanged: "InitialDescription", heartbeatInterval: serverMonitorSettings.HeartbeatInterval);
            _roundTripTimeMonitor = Ensure.IsNotNull(roundTripTimeMonitor, nameof(roundTripTimeMonitor));

            _state = new InterlockedInt32(State.Initial);
            eventSubscriber.TryGetEventHandler(out _heartbeatStartedEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatSucceededEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatFailedEventHandler);
            eventSubscriber.TryGetEventHandler(out _sdamInformationEventHandler);

            _heartbeatCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_monitorCancellationTokenSource.Token);
        }
        public void Constructor_with_serverId_and_endPoint_only_should_return_disconnected_instance()
        {
            var subject = new ServerDescription(__serverId, __endPoint);

            subject.AverageRoundTripTime.Should().Be(TimeSpan.Zero);
            subject.CanonicalEndPoint.Should().BeNull();
            subject.ElectionId.Should().BeNull();
            subject.EndPoint.Should().Be(__endPoint);
            subject.HelloOk.Should().BeFalse();
            subject.LogicalSessionTimeout.Should().NotHaveValue();
            subject.ReplicaSetConfig.Should().BeNull();
            subject.ServerId.Should().Be(__serverId);
            subject.State.Should().Be(ServerState.Disconnected);
            subject.Tags.Should().BeNull();
            subject.Type.Should().Be(ServerType.Unknown);
#pragma warning disable CS0618 // Type or member is obsolete
            subject.Version.Should().BeNull();
#pragma warning restore CS0618 // Type or member is obsolete
            subject.WireVersionRange.Should().BeNull();
        }
Пример #24
0
        // constructors
        public ClusterableServer(ClusterId clusterId, ClusterConnectionMode clusterConnectionMode, ServerSettings settings, EndPoint endPoint, IConnectionPoolFactory connectionPoolFactory, IConnectionFactory heartbeatConnectionFactory, IEventSubscriber eventSubscriber)
        {
            Ensure.IsNotNull(clusterId, nameof(clusterId));
            _clusterConnectionMode = clusterConnectionMode;
            _settings = Ensure.IsNotNull(settings, nameof(settings));;
            _endPoint = Ensure.IsNotNull(endPoint, nameof(endPoint));
            Ensure.IsNotNull(connectionPoolFactory, nameof(connectionPoolFactory));
            _heartbeatConnectionFactory = Ensure.IsNotNull(heartbeatConnectionFactory, nameof(heartbeatConnectionFactory));
            Ensure.IsNotNull(eventSubscriber, nameof(eventSubscriber));

            _serverId        = new ServerId(clusterId, endPoint);
            _baseDescription = _currentDescription = new ServerDescription(_serverId, endPoint);
            _connectionPool  = connectionPoolFactory.CreateConnectionPool(_serverId, endPoint);
            _state           = new InterlockedInt32(State.Initial);

            eventSubscriber.TryGetEventHandler(out _openingEventHandler);
            eventSubscriber.TryGetEventHandler(out _openedEventHandler);
            eventSubscriber.TryGetEventHandler(out _closingEventHandler);
            eventSubscriber.TryGetEventHandler(out _closedEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatStartedEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatSucceededEventHandler);
            eventSubscriber.TryGetEventHandler(out _heartbeatFailedEventHandler);
            eventSubscriber.TryGetEventHandler(out _descriptionChangedEventHandler);
        }
Пример #25
0
        public LoadBalancedServer(
            ClusterId clusterId,
            IClusterClock clusterClock,
            ServerSettings serverSettings,
            EndPoint endPoint,
            IConnectionPoolFactory connectionPoolFactory,
            IEventSubscriber eventSubscriber,
            ServerApi serverApi)
            : base(
                clusterId,
                clusterClock,
#pragma warning disable CS0618 // Type or member is obsolete
                ClusterConnectionMode.Automatic,
                ConnectionModeSwitch.UseConnectionMode,
#pragma warning restore CS0618 // Type or member is obsolete
                directConnection: null,
                serverSettings,
                endPoint,
                connectionPoolFactory,
                eventSubscriber,
                serverApi)
        {
            _baseDescription = _currentDescription = new ServerDescription(ServerId, endPoint, reasonChanged: "ServerInitialDescription");
        }
Пример #26
0
        // constructors
        public Server(ClusterId clusterId, IClusterClock clusterClock, ClusterConnectionMode clusterConnectionMode, ServerSettings settings, EndPoint endPoint, IConnectionPoolFactory connectionPoolFactory, IServerMonitorFactory serverMonitorFactory, IEventSubscriber eventSubscriber)
        {
            Ensure.IsNotNull(clusterId, nameof(clusterId));
            _clusterClock          = Ensure.IsNotNull(clusterClock, nameof(clusterClock));
            _clusterConnectionMode = clusterConnectionMode;
            _settings = Ensure.IsNotNull(settings, nameof(settings));
            _endPoint = Ensure.IsNotNull(endPoint, nameof(endPoint));
            Ensure.IsNotNull(connectionPoolFactory, nameof(connectionPoolFactory));
            Ensure.IsNotNull(serverMonitorFactory, nameof(serverMonitorFactory));
            Ensure.IsNotNull(eventSubscriber, nameof(eventSubscriber));

            _serverId           = new ServerId(clusterId, endPoint);
            _connectionPool     = connectionPoolFactory.CreateConnectionPool(_serverId, endPoint);
            _state              = new InterlockedInt32(State.Initial);
            _monitor            = serverMonitorFactory.Create(_serverId, _endPoint);
            _baseDescription    = new ServerDescription(_serverId, endPoint, reasonChanged: "ServerInitialDescription", heartbeatInterval: settings.HeartbeatInterval);
            _currentDescription = _baseDescription;

            eventSubscriber.TryGetEventHandler(out _openingEventHandler);
            eventSubscriber.TryGetEventHandler(out _openedEventHandler);
            eventSubscriber.TryGetEventHandler(out _closingEventHandler);
            eventSubscriber.TryGetEventHandler(out _closedEventHandler);
            eventSubscriber.TryGetEventHandler(out _descriptionChangedEventHandler);
        }
Пример #27
0
        public void WithHeartbeat_should_return_same_instance_when_all_fields_are_equal()
        {
            var averageRoundTripTime = TimeSpan.FromSeconds(1);
            var replicaSetConfig     = new ReplicaSetConfig(
                new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) },
                "name",
                new DnsEndPoint("localhost", 27017),
                1);
            var state            = ServerState.Connected;
            var tags             = new TagSet(new[] { new Tag("x", "a") });
            var type             = ServerType.ReplicaSetPrimary;
            var version          = new SemanticVersion(2, 6, 3);
            var wireVersionRange = new Range <int>(0, 2);

            var subject = new ServerDescription(
                __serverId,
                __endPoint,
                state: state,
                type: type,
                averageRoundTripTime: averageRoundTripTime,
                replicaSetConfig: replicaSetConfig,
                tags: tags,
                version: version,
                wireVersionRange: wireVersionRange);

            var serverDescription2 = subject.With(
                averageRoundTripTime: averageRoundTripTime,
                replicaSetConfig: replicaSetConfig,
                state: ServerState.Connected,
                tags: tags,
                type: type,
                version: version,
                wireVersionRange: wireVersionRange);

            serverDescription2.Should().BeSameAs(subject);
        }
Пример #28
0
        public void Equals_should_return_false_when_any_field_is_not_equal(string notEqualField)
        {
            var averageRoundTripTime  = TimeSpan.FromSeconds(1);
            var canonicalEndPoint     = new DnsEndPoint("localhost", 27017);
            var electionId            = new ElectionId(ObjectId.GenerateNewId());
            var endPoint              = new DnsEndPoint("localhost", 27017);
            var logicalSessionTimeout = TimeSpan.FromMinutes(1);
            var replicaSetConfig      = new ReplicaSetConfig(
                new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) },
                "name",
                new DnsEndPoint("localhost", 27017),
                1);
            var serverId         = new ServerId(__clusterId, endPoint);
            var state            = ServerState.Connected;
            var tags             = new TagSet(new[] { new Tag("x", "a") });
            var type             = ServerType.ReplicaSetPrimary;
            var version          = new SemanticVersion(2, 6, 3);
            var wireVersionRange = new Range <int>(2, 3);

            var subject = new ServerDescription(
                serverId,
                endPoint,
                state: state,
                type: type,
                averageRoundTripTime: averageRoundTripTime,
                canonicalEndPoint: canonicalEndPoint,
                logicalSessionTimeout: logicalSessionTimeout,
                replicaSetConfig: replicaSetConfig,
                tags: tags,
                version: version,
                wireVersionRange: wireVersionRange);

            switch (notEqualField)
            {
            case "AverageRoundTripTime": averageRoundTripTime = averageRoundTripTime.Add(TimeSpan.FromSeconds(1)); break;

            case "CanonicalEndPoint": canonicalEndPoint = new DnsEndPoint("localhost", 27018); break;

            case "ElectionId": electionId = new ElectionId(ObjectId.Empty); break;

            case "EndPoint": endPoint = new DnsEndPoint(endPoint.Host, endPoint.Port + 1); serverId = new ServerId(__clusterId, endPoint); break;

            case "LogicalSessionTimeout": logicalSessionTimeout = TimeSpan.FromMinutes(2); break;

            case "ReplicaSetConfig": replicaSetConfig = new ReplicaSetConfig(replicaSetConfig.Members, "newname", replicaSetConfig.Primary, replicaSetConfig.Version); break;

            case "State": state = ServerState.Disconnected; break;

            case "ServerId": serverId = new ServerId(new ClusterId(), endPoint); break;

            case "Tags": tags = new TagSet(new[] { new Tag("x", "b") }); break;

            case "Type": type = ServerType.ReplicaSetSecondary; break;

            case "Version": version = new SemanticVersion(version.Major, version.Minor, version.Patch + 1); break;

            case "WireVersionRange": wireVersionRange = new Range <int>(0, 0); break;
            }

            var serverDescription2 = new ServerDescription(
                serverId,
                endPoint,
                state: state,
                type: type,
                averageRoundTripTime: averageRoundTripTime,
                canonicalEndPoint: canonicalEndPoint,
                electionId: electionId,
                logicalSessionTimeout: logicalSessionTimeout,
                replicaSetConfig: replicaSetConfig,
                tags: tags,
                version: version,
                wireVersionRange: wireVersionRange);

            subject.Equals(serverDescription2).Should().BeFalse();
            subject.Equals((object)serverDescription2).Should().BeFalse();
            subject.GetHashCode().Should().NotBe(serverDescription2.GetHashCode());
        }
Пример #29
0
        public void With_should_return_new_instance_when_a_field_is_not_equal(string notEqualField)
        {
            var averageRoundTripTime  = TimeSpan.FromSeconds(1);
            var canonicalEndPoint     = new DnsEndPoint("localhost", 27017);
            var electionId            = new ElectionId(ObjectId.GenerateNewId());
            var heartbeatException    = new Exception();
            var heartbeatInterval     = TimeSpan.FromSeconds(10);
            var lastUpdateTimestamp   = DateTime.UtcNow;
            var lastWriteTimestamp    = DateTime.UtcNow;
            var logicalSessionTimeout = TimeSpan.FromMinutes(1);
            var maxBatchCount         = 1000;
            var maxDocumentSize       = 16000000;
            var maxMessageSize        = 48000000;
            var maxWireDocumentSize   = 16000000;
            var replicaSetConfig      = new ReplicaSetConfig(
                new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) },
                "name",
                new DnsEndPoint("localhost", 27017),
                1);
            var state            = ServerState.Connected;
            var tags             = new TagSet(new[] { new Tag("x", "a") });
            var type             = ServerType.ReplicaSetPrimary;
            var version          = new SemanticVersion(2, 6, 3);
            var wireVersionRange = new Range <int>(2, 3);

            var subject = new ServerDescription(
                __serverId,
                __endPoint,
                averageRoundTripTime: averageRoundTripTime,
                canonicalEndPoint: canonicalEndPoint,
                electionId: electionId,
                heartbeatException: heartbeatException,
                heartbeatInterval: heartbeatInterval,
                lastUpdateTimestamp: lastUpdateTimestamp,
                lastWriteTimestamp: lastWriteTimestamp,
                logicalSessionTimeout: logicalSessionTimeout,
                maxBatchCount: maxBatchCount,
                maxDocumentSize: maxDocumentSize,
                maxMessageSize: maxMessageSize,
                maxWireDocumentSize: maxWireDocumentSize,
                replicaSetConfig: replicaSetConfig,
                state: state,
                tags: tags,
                type: type,
                version: version,
                wireVersionRange: wireVersionRange);

            switch (notEqualField)
            {
            case "AverageRoundTripTime": averageRoundTripTime = averageRoundTripTime.Add(TimeSpan.FromSeconds(1)); break;

            case "CanonicalEndPoint": canonicalEndPoint = new DnsEndPoint("localhost", 27018); break;

            case "ElectionId": electionId = new ElectionId(ObjectId.Empty); break;

            case "HeartbeatException": heartbeatException = new Exception(); break;

            case "HeartbeatInterval": heartbeatInterval = TimeSpan.FromSeconds(11); break;

            case "LastUpdateTimestamp": lastUpdateTimestamp = lastUpdateTimestamp.Add(TimeSpan.FromSeconds(1)); break;

            case "LastWriteTimestamp": lastWriteTimestamp = lastWriteTimestamp.Add(TimeSpan.FromSeconds(1)); break;

            case "LogicalSessionTimeout": logicalSessionTimeout = TimeSpan.FromMinutes(2); break;

            case "MaxBatchCount": maxBatchCount += 1; break;

            case "MaxDocumentSize": maxDocumentSize += 1; break;

            case "MaxMessageSize": maxMessageSize += 1; break;

            case "MaxWireDocumentSize": maxWireDocumentSize += 1; break;

            case "ReplicaSetConfig": replicaSetConfig = new ReplicaSetConfig(replicaSetConfig.Members, "newname", replicaSetConfig.Primary, replicaSetConfig.Version); break;

            case "State": state = ServerState.Disconnected; break;

            case "Tags": tags = new TagSet(new[] { new Tag("x", "b") }); break;

            case "Type": type = ServerType.ReplicaSetSecondary; break;

            case "Version": version = new SemanticVersion(version.Major, version.Minor, version.Patch + 1); break;

            case "WireVersionRange": wireVersionRange = new Range <int>(0, 0); break;
            }

            var result = subject.With(
                averageRoundTripTime: averageRoundTripTime,
                canonicalEndPoint: canonicalEndPoint,
                electionId: electionId,
                heartbeatException: heartbeatException,
                heartbeatInterval: heartbeatInterval,
                lastUpdateTimestamp: lastUpdateTimestamp,
                lastWriteTimestamp: lastWriteTimestamp,
                logicalSessionTimeout: logicalSessionTimeout,
                maxBatchCount: maxBatchCount,
                maxDocumentSize: maxDocumentSize,
                maxMessageSize: maxMessageSize,
                maxWireDocumentSize: maxWireDocumentSize,
                replicaSetConfig: replicaSetConfig,
                state: state,
                tags: tags,
                type: type,
                version: version,
                wireVersionRange: wireVersionRange);

            result.Should().NotBeSameAs(subject);
            result.Equals(subject).Should().BeFalse();
            result.Equals((object)subject).Should().BeFalse();
            result.GetHashCode().Should().NotBe(subject.GetHashCode());
        }
Пример #30
0
        public void HandleChannelException_should_update_topology_as_expected_on_network_error_or_timeout(
            string errorType, bool shouldUpdateTopology)
        {
            var       serverId     = new ServerId(_clusterId, _endPoint);
            var       connectionId = new ConnectionId(serverId);
            Exception innerMostException;

            switch (errorType)
            {
            case "MongoConnectionExceptionWithSocketTimeout":
                innerMostException = new SocketException((int)SocketError.TimedOut);
                break;

            case nameof(MongoConnectionException):
                innerMostException = new SocketException((int)SocketError.NetworkUnreachable);
                break;

            default: throw new ArgumentException("Unknown error type.");
            }

            var operationUsingChannelException = new MongoConnectionException(connectionId, "Oops", new IOException("Cry", innerMostException));
            var mockConnection = new Mock <IConnectionHandle>();
            var isMasterResult = new IsMasterResult(new BsonDocument {
                { "compressors", new BsonArray() }
            });
            // the server version doesn't matter when we're not testing MongoNotPrimaryExceptions, but is needed when
            // Server calls ShouldClearConnectionPoolForException
            var buildInfoResult = new BuildInfoResult(new BsonDocument {
                { "version", "4.4.0" }
            });

            mockConnection.SetupGet(c => c.Description)
            .Returns(new ConnectionDescription(new ConnectionId(serverId, 0), isMasterResult, buildInfoResult));
            var mockConnectionPool = new Mock <IConnectionPool>();

            mockConnectionPool.Setup(p => p.AcquireConnection(It.IsAny <CancellationToken>())).Returns(mockConnection.Object);
            mockConnectionPool.Setup(p => p.AcquireConnectionAsync(It.IsAny <CancellationToken>())).ReturnsAsync(mockConnection.Object);
            var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>();

            mockConnectionPoolFactory
            .Setup(f => f.CreateConnectionPool(It.IsAny <ServerId>(), _endPoint))
            .Returns(mockConnectionPool.Object);
            var mockMonitorServerInitialDescription = new ServerDescription(serverId, _endPoint).With(reasonChanged: "Initial D", type: ServerType.Unknown);
            var mockServerMonitor = new Mock <IServerMonitor>();

            mockServerMonitor.SetupGet(m => m.Description).Returns(mockMonitorServerInitialDescription);
            mockServerMonitor.SetupGet(m => m.Lock).Returns(new object());
            var mockServerMonitorFactory = new Mock <IServerMonitorFactory>();

            mockServerMonitorFactory.Setup(f => f.Create(It.IsAny <ServerId>(), _endPoint)).Returns(mockServerMonitor.Object);
            var subject = new DefaultServer(_clusterId, _clusterClock, _clusterConnectionMode, _connectionModeSwitch, _directConnection, _settings, _endPoint, mockConnectionPoolFactory.Object, mockServerMonitorFactory.Object, _capturedEvents, _serverApi);

            subject.Initialize();
            var heartbeatDescription = mockMonitorServerInitialDescription.With(reasonChanged: "Heartbeat", type: ServerType.Standalone);

            mockServerMonitor.Setup(m => m.Description).Returns(heartbeatDescription);
            mockServerMonitor.Raise(
                m => m.DescriptionChanged += null,
                new ServerDescriptionChangedEventArgs(mockMonitorServerInitialDescription, heartbeatDescription));
            subject.Description.Should().Be(heartbeatDescription);

            subject.HandleChannelException(mockConnection.Object, operationUsingChannelException);

            if (shouldUpdateTopology)
            {
                subject.Description.Type.Should().Be(ServerType.Unknown);
                subject.Description.ReasonChanged.Should().Contain("ChannelException");
            }
            else
            {
                subject.Description.Should().Be(heartbeatDescription);
            }
        }