Exemplo n.º 1
0
        /// <summary>
        ///   Opens the connection
        /// </summary>
        private async Task OpenAsyncInternal(Logger logger)
        {
            //switch state to connecting if not done so
            int state = Interlocked.CompareExchange(ref _connectionState, 1, 0);

            if (state == 1)
                return;

            if (state == 2)
                throw new ObjectDisposedException("Connection disposed before opening!");

            try
            {
                //create TCP connection
                _client = new TcpClient();
                await _client.ConnectAsync(_address, _cluster.Config.Port).ConfigureAwait(false);
                _writeStream = _client.GetStream();
                _readStream = _client.GetStream();

                logger.LogVerbose("TCP connection to {0} is opened", Address);

                //start readloop
                StartReadingAsync();

                //get compression option
                _allowCompression = false; //assume false unless
                if (_cluster.Config.AllowCompression)
                {
                    //check wether compression is supported by getting compression options from server
                    var options = new OptionsFrame();
                    var supported =
                        await SendRequestAsync(options, logger, 1, true).ConfigureAwait(false) as SupportedFrame;

                    if (supported == null)
                        throw new ProtocolException(0, "Expected Supported frame not received");

                    IList<string> compressionOptions;
                    //check if options contain compression
                    if (supported.SupportedOptions.TryGetValue("COMPRESSION", out compressionOptions))
                    {
                        //check wether snappy is supported
                        _allowCompression = compressionOptions.Contains("snappy");
                    }

                    //dispose supported frame
                    supported.Dispose();
                }

                //submit startup frame
                var startup = new StartupFrame(_cluster.Config.CqlVersion);
                if (_allowCompression)
                {
                    logger.LogVerbose("Enabling Snappy Compression.");
                    startup.Options["COMPRESSION"] = "snappy";
                }

                Frame response = await SendRequestAsync(startup, logger, 1, true).ConfigureAwait(false);

                //authenticate if required
                var auth = response as AuthenticateFrame;
                if (auth != null)
                {
                    logger.LogVerbose("Authentication requested, attempting to provide credentials", Address);

                    //check if _username is actually set
                    if (_cluster.Config.Username == null || _cluster.Config.Password == null)
                        throw new UnauthorizedException("No credentials provided");

                    //dispose AuthenticateFrame
                    response.Dispose();

                    var cred = new CredentialsFrame(_cluster.Config.Username, _cluster.Config.Password);
                    response = await SendRequestAsync(cred, logger, 1, true).ConfigureAwait(false);
                }

                //check if ready
                if (!(response is ReadyFrame))
                    throw new ProtocolException(0, "Expected Ready frame not received");

                //dispose ready frame
                response.Dispose();

                using (logger.ThreadBinding())
                {
                    if (OnConnectionChange != null)
                        OnConnectionChange(this, new ConnectionChangeEvent { Connected = true });
                }

                logger.LogInfo("{0} is opened and ready for use", this);
            }
            catch (Exception ex)
            {
                using (logger.ThreadBinding())
                {
                    Dispose(true, ex);
                    throw;
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Negotiates the connection options.
        /// </summary>
        /// <param name="logger">The logger.</param>
        /// <returns></returns>
        /// <exception cref="ProtocolException">0;Expected Supported frame not received</exception>
        private async Task NegotiateConnectionOptionsAsync(Logger logger)
        {
            //get options from server
            var options = new OptionsFrame();

            var frame =
                await SendRequestAsyncInternal(options, logger, 1, CancellationToken.None).AutoConfigureAwait();
            
            var supported = frame as SupportedFrame;
            if (supported == null)
                throw new ProtocolException(frame.ProtocolVersion, 0, "Expected Supported frame not received");

            //setup concurrent calls depending on frameversion
            _frameSubmitLock = new SemaphoreSlim(supported.ProtocolVersion <= 2 ? sbyte.MaxValue : short.MaxValue);

            //setuo compression
            _allowCompression = false;
            if (_config.AllowCompression)
            {
                IList<string> compressionOptions;
                //check if options contain compression
                if (supported.SupportedOptions.TryGetValue("COMPRESSION", out compressionOptions))
                {
                    //check wether snappy is supported
                    _allowCompression = compressionOptions.Contains("snappy");
                }
            }

            //dispose supported frame
            supported.Dispose();
        }