Ejemplo n.º 1
0
        /// <summary>
        /// Gets the next connection and setup the event listener for the host and connection.
        /// Not thread-safe.
        /// </summary>
        private void SubscribeEventHandlers()
        {
            _host.Down += OnHostDown;
            _connection.CassandraEventResponse += OnConnectionCassandraEvent;
            //Register to events on the connection
            var registerTask = _connection.Send(new RegisterForEventRequest(CassandraEventTypes));

            TaskHelper.WaitToComplete(registerTask, 10000);
            if (!(registerTask.Result is ReadyResponse))
            {
                throw new DriverInternalError("Expected ReadyResponse, obtained " + registerTask.Result.GetType().Name);
            }
        }
Ejemplo n.º 2
0
 private void DoFetchTrace()
 {
     try
     {
         TaskHelper.WaitToComplete(LoadAsync(), _metadataFetchSyncTimeout);
     }
     catch (Exception ex)
     {
         throw new TraceRetrievalException("Unexpected exception while fetching query trace", ex);
     }
     finally
     {
         _isDisconnected = false;
     }
 }
Ejemplo n.º 3
0
        private Cluster(IEnumerable <object> contactPoints, Configuration configuration)
        {
            Configuration = configuration;
            _metadata     = new Metadata(configuration);
            TaskHelper.WaitToComplete(AddHosts(contactPoints));
            var protocolVersion = _maxProtocolVersion;

            if (Configuration.ProtocolOptions.MaxProtocolVersionValue != null &&
                Configuration.ProtocolOptions.MaxProtocolVersionValue.Value.IsSupported())
            {
                protocolVersion = Configuration.ProtocolOptions.MaxProtocolVersionValue.Value;
            }
            _controlConnection          = new ControlConnection(protocolVersion, Configuration, _metadata);
            _metadata.ControlConnection = _controlConnection;
            _serializer = _controlConnection.Serializer;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Updates the keyspace and token information
        /// </summary>
        public bool RefreshSchema(string keyspace = null, string table = null)
        {
            if (table == null)
            {
                //Refresh all the keyspaces and tables information
                return(TaskHelper.WaitToComplete(RefreshKeyspaces(true), Configuration.ClientOptions.QueryAbortTimeout));
            }
            var ks = GetKeyspace(keyspace);

            if (ks == null)
            {
                return(false);
            }
            ks.ClearTableMetadata(table);
            return(true);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Tries to create a connection to any of the contact points and retrieve cluster metadata for the first time. Not thread-safe.
 /// </summary>
 /// <exception cref="NoHostAvailableException" />
 /// <exception cref="DriverInternalError" />
 internal void Init()
 {
     _logger.Info("Trying to connect the ControlConnection");
     TaskHelper.WaitToComplete(Connect(true), _config.SocketOptions.ConnectTimeoutMillis);
     try
     {
         SubscribeEventHandlers();
         RefreshNodeList();
         Metadata.RefreshKeyspaces(false);
     }
     catch (SocketException ex)
     {
         //There was a problem using the connection obtained
         //It is not usual but can happen
         _logger.Error("An error occurred when trying to retrieve the cluster metadata, retrying.", ex);
         //Retry one more time and throw if there is problem
         TaskHelper.WaitToComplete(Reconnect(), _config.SocketOptions.ConnectTimeoutMillis);
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Waits until that the schema version in all nodes is the same or the waiting time passed.
        /// This method blocks the calling thread.
        /// </summary>
        internal bool WaitForSchemaAgreement(IConnection connection)
        {
            if (Hosts.Count == 1)
            {
                //If there is just one node, the schema is up to date in all nodes :)
                return(true);
            }
            var start       = DateTime.Now;
            var waitSeconds = Configuration.ProtocolOptions.MaxSchemaAgreementWaitSeconds;

            Metadata.Logger.Info("Waiting for schema agreement");
            try
            {
                var totalVersions = 0;
                while (DateTime.Now.Subtract(start).TotalSeconds < waitSeconds)
                {
                    var schemaVersionLocalQuery = new QueryRequest(ControlConnection.ProtocolVersion, Metadata.SelectSchemaVersionLocal, false, QueryProtocolOptions.Default);
                    var schemaVersionPeersQuery = new QueryRequest(ControlConnection.ProtocolVersion, Metadata.SelectSchemaVersionPeers, false, QueryProtocolOptions.Default);
                    var queries = new[] { connection.Send(schemaVersionLocalQuery), connection.Send(schemaVersionPeersQuery) };
                    // ReSharper disable once CoVariantArrayConversion
                    Task.WaitAll(queries, Configuration.ClientOptions.QueryAbortTimeout);

                    if (Metadata.CheckSchemaVersionResults(
                            Cassandra.ControlConnection.GetRowSet(queries[0].Result),
                            Cassandra.ControlConnection.GetRowSet(queries[1].Result)))
                    {
                        return(true);
                    }

                    Thread.Sleep(500);
                }
                Metadata.Logger.Info($"Waited for schema agreement, still {totalVersions} schema versions in the cluster.");
                TaskHelper.WaitToComplete(RefreshPartitionMap(), Configuration.ClientOptions.QueryAbortTimeout);
            }
            catch (Exception ex)
            {
                //Exceptions are not fatal
                Metadata.Logger.Error("There was an exception while trying to retrieve schema versions", ex);
            }

            return(false);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Starts the authentication flow
        /// </summary>
        /// <exception cref="AuthenticationException" />
        private void Authenticate()
        {
            //Determine which authentication flow to use.
            //Check if its using a C* 1.2 with authentication patched version (like DSE 3.1)
            var isPatchedVersion = ProtocolVersion == 1 && !(Configuration.AuthProvider is NoneAuthProvider) && Configuration.AuthInfoProvider == null;

            if (ProtocolVersion >= 2 || isPatchedVersion)
            {
                //Use protocol v2+ authentication flow

                //NewAuthenticator will throw AuthenticationException when NoneAuthProvider
                var authenticator = Configuration.AuthProvider.NewAuthenticator(Address);

                var initialResponse = authenticator.InitialResponse() ?? new byte[0];
                Authenticate(initialResponse, authenticator);
            }
            else
            {
                //Use protocol v1 authentication flow
                if (Configuration.AuthInfoProvider == null)
                {
                    throw new AuthenticationException(
                              String.Format("Host {0} requires authentication, but no credentials provided in Cluster configuration", Address),
                              Address);
                }
                var credentialsProvider = Configuration.AuthInfoProvider;
                var credentials         = credentialsProvider.GetAuthInfos(Address);
                var request             = new CredentialsRequest(ProtocolVersion, credentials);
                var response            = TaskHelper.WaitToComplete(this.Send(request), Configuration.SocketOptions.ConnectTimeoutMillis);
                //If Cassandra replied with a auth response error
                //The task already is faulted and the exception was already thrown.
                if (response is ReadyResponse)
                {
                    return;
                }
                throw new ProtocolErrorException("Expected SASL response, obtained " + response.GetType().Name);
            }
        }
Ejemplo n.º 8
0
        private Cluster(IEnumerable <object> contactPoints, Configuration configuration, IClusterLifecycleManager lifecycleManager)
        {
            Configuration = configuration;
            _metadata     = new Metadata(configuration);
            TaskHelper.WaitToComplete(AddHosts(contactPoints));
            var protocolVersion = _maxProtocolVersion;

            if (Configuration.ProtocolOptions.MaxProtocolVersionValue != null &&
                Configuration.ProtocolOptions.MaxProtocolVersionValue.Value.IsSupported())
            {
                protocolVersion = Configuration.ProtocolOptions.MaxProtocolVersionValue.Value;
            }

            _protocolEventDebouncer = new ProtocolEventDebouncer(
                configuration.TimerFactory,
                TimeSpan.FromMilliseconds(configuration.MetadataSyncOptions.RefreshSchemaDelayIncrement),
                TimeSpan.FromMilliseconds(configuration.MetadataSyncOptions.MaxTotalRefreshSchemaDelay));
            _controlConnection          = configuration.ControlConnectionFactory.Create(_protocolEventDebouncer, protocolVersion, Configuration, _metadata);
            _metadata.ControlConnection = _controlConnection;
            _serializer       = _controlConnection.Serializer;
            _sessionFactory   = configuration.SessionFactoryBuilder.BuildWithCluster(this);
            _lifecycleManager = lifecycleManager ?? new ClusterLifecycleManager(this);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Uses the active connection to execute a query
        /// </summary>
        public RowSet Query(string cqlQuery, bool retry = false)
        {
            var request = new QueryRequest(_controlConnectionProtocolVersion, cqlQuery, false, QueryProtocolOptions.Default);
            var task    = _connection.Send(request);

            try
            {
                TaskHelper.WaitToComplete(task, 10000);
            }
            catch (SocketException ex)
            {
                const string message = "There was an error while executing on the host {0} the query '{1}'";
                _logger.Error(String.Format(message, cqlQuery, _connection.Address), ex);
                if (retry)
                {
                    //Try to connect to another host
                    Refresh(reconnect: true, throwExceptions: true);
                    //Try to execute again without retry
                    return(Query(cqlQuery, false));
                }
                throw;
            }
            return(GetRowSet(task.Result));
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Fills the common properties of the RowSet
 /// </summary>
 private RowSet FillRowSet(RowSet rs)
 {
     rs.Info.SetTriedHosts(_triedHosts.Keys.ToList());
     if (_request is ICqlRequest)
     {
         rs.Info.SetAchievedConsistency(((ICqlRequest)_request).Consistency);
     }
     if (rs.PagingState != null && _request is IQueryRequest && typeof(T) == typeof(RowSet))
     {
         rs.FetchNextPage = (pagingState) =>
         {
             if (_session.IsDisposed)
             {
                 _logger.Warning("Trying to page results using a Session already disposed.");
                 return(new RowSet());
             }
             ((IQueryRequest)_request).PagingState = pagingState;
             var task = new RequestHandler <RowSet>(_session, _request, _statement).Send();
             TaskHelper.WaitToComplete(task, _session.Configuration.ClientOptions.QueryAbortTimeout);
             return((RowSet)(object)task.Result);
         };
     }
     return(rs);
 }
Ejemplo n.º 11
0
        /// <exception cref="AuthenticationException" />
        private void Authenticate(byte[] token, IAuthenticator authenticator)
        {
            var request  = new AuthResponseRequest(this.ProtocolVersion, token);
            var response = TaskHelper.WaitToComplete(this.Send(request), Configuration.SocketOptions.ConnectTimeoutMillis);

            if (response is AuthSuccessResponse)
            {
                //It is now authenticated
                return;
            }
            if (response is AuthChallengeResponse)
            {
                token = authenticator.EvaluateChallenge((response as AuthChallengeResponse).Token);
                if (token == null)
                {
                    // If we get a null response, then authentication has completed
                    //return without sending a further response back to the server.
                    return;
                }
                Authenticate(token, authenticator);
                return;
            }
            throw new ProtocolErrorException("Expected SASL response, obtained " + response.GetType().Name);
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Gets the definition associated with a User Defined Type from Cassandra
 /// </summary>
 public UdtColumnInfo GetUdtDefinition(string keyspace, string typeName)
 {
     return(TaskHelper.WaitToComplete(GetUdtDefinitionAsync(keyspace, typeName), _queryAbortTimeout));
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Updates the keyspace and token information
 /// </summary>
 public bool RefreshSchema(string keyspace = null, string table = null)
 {
     return(TaskHelper.WaitToComplete(RefreshSchemaAsync(keyspace, table), Configuration.DefaultRequestOptions.QueryAbortTimeout * 2));
 }
Ejemplo n.º 14
0
 /// <summary>
 ///  Returns metadata of specified view in this keyspace.
 /// </summary>
 /// <param name="viewName">the name of view to retrieve </param>
 /// <returns>the metadata for view <c>viewName</c> in this keyspace if it
 ///  exists, <c>null</c> otherwise.</returns>
 public MaterializedViewMetadata GetMaterializedViewMetadata(string viewName)
 {
     return(TaskHelper.WaitToComplete(
                GetMaterializedViewMetadataAsync(viewName), _parent.Configuration.DefaultRequestOptions.GetQueryAbortTimeout(2)));
 }
 /// <summary>
 ///  Returns metadata of specified table in this keyspace.
 /// </summary>
 /// <param name="tableName"> the name of table to retrieve </param>
 /// <returns>the metadata for table <c>tableName</c> in this keyspace if it
 ///  exists, <c>null</c> otherwise.</returns>
 public TableMetadata GetTableMetadata(string tableName)
 {
     return(TaskHelper.WaitToComplete(
                GetTableMetadataAsync(tableName), _parent.Configuration.ClientOptions.GetQueryAbortTimeout(2)));
 }
 /// <summary>
 /// Gets the definition of a User defined type
 /// </summary>
 internal UdtColumnInfo GetUdtDefinition(string typeName)
 {
     return(TaskHelper.WaitToComplete(GetUdtDefinitionAsync(typeName), _parent.Configuration.ClientOptions.QueryAbortTimeout));
 }
 /// <summary>
 ///  Returns names of all tables defined in this keyspace.
 /// </summary>
 ///
 /// <returns>a collection of all, defined in this
 ///  keyspace tables names.</returns>
 public ICollection <string> GetTablesNames()
 {
     return(TaskHelper.WaitToComplete(_parent.SchemaParser.GetTableNames(Name)));
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Add mapping definition(s) for UDTs, specifying how UDTs should be mapped to .NET types and vice versa.
 /// </summary>
 /// <exception cref="ArgumentException" />
 public void Define(params UdtMap[] udtMaps)
 {
     TaskHelper.WaitToComplete(DefineAsync(udtMaps), _cluster.Configuration.ClientOptions.QueryAbortTimeout);
 }
Ejemplo n.º 19
0
        internal Task <bool> Reconnect()
        {
            //If there is another thread reconnecting, use the same task
            var tcs         = new TaskCompletionSource <bool>();
            var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null);

            if (currentTask != null)
            {
                return(currentTask);
            }
            Unsubscribe();
            Connect(false).ContinueWith(t =>
            {
                if (Interlocked.Read(ref _isShutdown) > 0L)
                {
                    if (t.Exception != null)
                    {
                        t.Exception.Handle(e => true);
                    }
                    return;
                }
                if (t.Exception != null)
                {
                    t.Exception.Handle(e => true);
                    Interlocked.Exchange(ref _reconnectTask, null);
                    tcs.TrySetException(t.Exception.InnerException);
                    var delay = _reconnectionSchedule.NextDelayMs();
                    _logger.Error("ControlConnection was not able to reconnect: " + t.Exception.InnerException);
                    try
                    {
                        _reconnectionTimer.Change((int)delay, Timeout.Infinite);
                    }
                    catch (ObjectDisposedException)
                    {
                        //Control connection is being disposed
                    }
                    return;
                }
                try
                {
                    RefreshNodeList();
                    TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout);
                    _reconnectionSchedule = _reconnectionPolicy.NewSchedule();
                    tcs.TrySetResult(true);
                    Interlocked.Exchange(ref _reconnectTask, null);
                    _logger.Info("ControlConnection reconnected to host {0}", _host.Address);
                }
                catch (Exception ex)
                {
                    Interlocked.Exchange(ref _reconnectTask, null);
                    _logger.Error("There was an error when trying to refresh the ControlConnection", ex);
                    tcs.TrySetException(ex);
                    try
                    {
                        _reconnectionTimer.Change((int)_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                    }
                    catch (ObjectDisposedException)
                    {
                        //Control connection is being disposed
                    }
                }
            });
            return(tcs.Task);
        }
Ejemplo n.º 20
0
 /// <summary>
 ///  Returns TableMetadata for specified table in specified keyspace.
 /// </summary>
 /// <param name="keyspace">name of the keyspace within specified table is defined.</param>
 /// <param name="tableName">name of table for which metadata should be returned.</param>
 /// <returns>a TableMetadata for the specified table in the specified keyspace.</returns>
 public TableMetadata GetTable(string keyspace, string tableName)
 {
     return(TaskHelper.WaitToComplete(GetTableAsync(keyspace, tableName), _queryAbortTimeout * 2));
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Gets a CQL function by name and signature
 /// </summary>
 /// <returns>The function metadata or null if not found.</returns>
 public FunctionMetadata GetFunction(string functionName, string[] signature)
 {
     return(TaskHelper.WaitToComplete(
                GetFunctionAsync(functionName, signature), _parent.Configuration.DefaultRequestOptions.QueryAbortTimeout));
 }
Ejemplo n.º 22
0
        internal async Task <bool> Reconnect()
        {
            var tcs         = new TaskCompletionSource <bool>();
            var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null);

            if (currentTask != null)
            {
                // If there is another thread reconnecting, use the same task
                return(await currentTask.ConfigureAwait(false));
            }
            Unsubscribe();
            try
            {
                await Connect(false).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                // It failed to reconnect, schedule the timer for next reconnection and let go.
                Interlocked.Exchange(ref _reconnectTask, null).Forget();
                tcs.TrySetException(ex);
                var delay = _reconnectionSchedule.NextDelayMs();
                _logger.Error("ControlConnection was not able to reconnect: " + ex);
                try
                {
                    _reconnectionTimer.Change((int)delay, Timeout.Infinite);
                }
                catch (ObjectDisposedException)
                {
                    //Control connection is being disposed
                }
                // It will throw the same exception that it was set in the TCS
                throw;
            }

            if (Interlocked.Read(ref _isShutdown) > 0L)
            {
                return(false);
            }
            try
            {
                await RefreshNodeList().ConfigureAwait(false);

                TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout);
                _reconnectionSchedule = _reconnectionPolicy.NewSchedule();
                tcs.TrySetResult(true);
                Interlocked.Exchange(ref _reconnectTask, null).Forget();
                _logger.Info("ControlConnection reconnected to host {0}", _host.Address);
            }
            catch (Exception ex)
            {
                Interlocked.Exchange(ref _reconnectTask, null).Forget();
                _logger.Error("There was an error when trying to refresh the ControlConnection", ex);
                tcs.TrySetException(ex);
                try
                {
                    _reconnectionTimer.Change((int)_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                }
                catch (ObjectDisposedException)
                {
                    //Control connection is being disposed
                }
            }
            return(await tcs.Task.ConfigureAwait(false));
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Creates a new session on this cluster and using a keyspace an existing keyspace.
 /// </summary>
 /// <param name="keyspace">Case-sensitive keyspace name to use</param>
 public ISession Connect(string keyspace)
 {
     return(TaskHelper.WaitToComplete(ConnectAsync(keyspace)));
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Uses the active connection to execute a query
 /// </summary>
 public IEnumerable <Row> Query(string cqlQuery, bool retry = false)
 {
     return(TaskHelper.WaitToComplete(QueryAsync(cqlQuery, retry), MetadataAbortTimeout));
 }
 /// <summary>
 /// Gets the definition of a User defined type
 /// </summary>
 internal UdtColumnInfo GetUdtDefinition(string typeName)
 {
     return(TaskHelper.WaitToComplete(GetUdtDefinitionAsync(typeName), ControlConnection.MetadataAbortTimeout));
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Gets a CQL aggregate by name and signature
 /// </summary>
 /// <returns>The aggregate metadata or null if not found.</returns>
 public AggregateMetadata GetAggregate(string aggregateName, string[] signature)
 {
     return(TaskHelper.WaitToComplete(
                GetAggregateAsync(aggregateName, signature), _parent.Configuration.DefaultRequestOptions.QueryAbortTimeout));
 }