Example #1
0
        /// <inheritdoc/>
        public async Task AuthenticateAsync(IConnection connection, ConnectionDescription description, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(connection, nameof(connection));
            Ensure.IsNotNull(description, nameof(description));

            // If we don't have SaslSupportedMechs as part of the response, that means we didn't piggyback the initial
            // hello or legacy hello request and should query the server (provided that the server >= 4.0), merging results into
            // a new ConnectionDescription
            if (!description.HelloResult.HasSaslSupportedMechs &&
                Feature.ScramSha256Authentication.IsSupported(description.ServerVersion))
            {
                var command       = CustomizeInitialHelloCommand(HelloHelper.CreateCommand(_serverApi));
                var helloProtocol = HelloHelper.CreateProtocol(command, _serverApi);
                var helloResult   = await HelloHelper.GetResultAsync(connection, helloProtocol, cancellationToken).ConfigureAwait(false);

                var mergedHelloResult = new HelloResult(description.HelloResult.Wrapped.Merge(helloResult.Wrapped));
                description = new ConnectionDescription(
                    description.ConnectionId,
                    mergedHelloResult,
                    description.BuildInfoResult);
            }

            var authenticator = GetOrCreateAuthenticator(connection, description);
            await authenticator.AuthenticateAsync(connection, description, cancellationToken).ConfigureAwait(false);
        }
        private async Task <IsMasterResult> GetHelloResultAsync(
            IConnection connection,
            CommandWireProtocol <BsonDocument> helloProtocol,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (_heartbeatStartedEventHandler != null)
            {
                _heartbeatStartedEventHandler(new ServerHeartbeatStartedEvent(connection.ConnectionId, connection.Description.IsMasterResult.TopologyVersion != null));
            }

            try
            {
                var stopwatch   = Stopwatch.StartNew();
                var helloResult = await HelloHelper.GetResultAsync(connection, helloProtocol, cancellationToken).ConfigureAwait(false);

                stopwatch.Stop();

                if (_heartbeatSucceededEventHandler != null)
                {
                    _heartbeatSucceededEventHandler(new ServerHeartbeatSucceededEvent(connection.ConnectionId, stopwatch.Elapsed, connection.Description.IsMasterResult.TopologyVersion != null));
                }

                return(helloResult);
            }
            catch (Exception ex)
            {
                if (_heartbeatFailedEventHandler != null)
                {
                    _heartbeatFailedEventHandler(new ServerHeartbeatFailedEvent(connection.ConnectionId, ex, connection.Description.IsMasterResult.TopologyVersion != null));
                }
                throw;
            }
        }
        public async Task RunAsync()
        {
            var helloOk = false;

            while (!_cancellationToken.IsCancellationRequested)
            {
                try
                {
                    if (_roundTripTimeConnection == null)
                    {
                        await InitializeConnectionAsync().ConfigureAwait(false); // sets _roundTripTimeConnection
                    }
                    else
                    {
                        var helloCommand  = HelloHelper.CreateCommand(_serverApi, helloOk);
                        var helloProtocol = HelloHelper.CreateProtocol(helloCommand, _serverApi);

                        var stopwatch   = Stopwatch.StartNew();
                        var helloResult = await HelloHelper.GetResultAsync(_roundTripTimeConnection, helloProtocol, _cancellationToken).ConfigureAwait(false);

                        stopwatch.Stop();
                        AddSample(stopwatch.Elapsed);
                        helloOk = helloResult.HelloOk;
                    }
                }
                catch (Exception)
                {
                    IConnection toDispose;
                    lock (_lock)
                    {
                        toDispose = _roundTripTimeConnection;
                        _roundTripTimeConnection = null;
                    }
                    toDispose?.Dispose();
                }

                await Task.Delay(_heartbeatInterval, _cancellationToken).ConfigureAwait(false);
            }
        }