예제 #1
0
        //-------------------------------------------------------
        // Get Info via Socket Address
        //-------------------------------------------------------
        /// <summary>
        /// Get one info value by name from the specified database server node.
        /// This method does not support user authentication.
        /// </summary>
        /// <param name="socketAddress">InetSocketAddress of server node</param>
        /// <param name="name">name of value to retrieve</param>
        public static string Request(IPEndPoint socketAddress, string name)
        {
            Connection conn = new Connection(socketAddress, DEFAULT_TIMEOUT);

            try
            {
                return Request(conn, name);
            }
            finally
            {
                conn.Close();
            }
        }
예제 #2
0
        /// <summary>
        /// Get all the default info from the specified database server node.
        /// This method does not support user authentication.
        /// </summary>
        /// <param name="socketAddress">InetSocketAddress of server node</param>
        public static Dictionary<string, string> Request(IPEndPoint socketAddress)
        {
            Connection conn = new Connection(socketAddress, DEFAULT_TIMEOUT);

            try
            {
                return Request(conn);
            }
            finally
            {
                conn.Close();
            }
        }
예제 #3
0
 /// <summary>
 /// Put connection back into connection pool.
 /// </summary>
 /// <param name="conn">socket connection</param>
 public void PutConnection(Connection conn)
 {
     if (!active || !connectionQueue.TryAdd(conn))
     {
         conn.Close();
     }
 }
        public NodeValidator(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, DEFAULT_TIMEOUT);
            aliases = new Host[addresses.Length];

            for (int i = 0; i < addresses.Length; i++)
            {
                aliases[i] = new Host(addresses[i].ToString(), host.port);
            }

            Exception exception = null;

            for (int i = 0; i < addresses.Length; i++)
            {
                try
                {
                    IPEndPoint address = new IPEndPoint(addresses[i], host.port);
                    Connection conn = new Connection(address, cluster.connectionTimeout);

                    try
                    {
                        if (cluster.user != null)
                        {
                            AdminCommand command = new AdminCommand();
                            command.Authenticate(conn, cluster.user, cluster.password);
                        }
                        Dictionary<string, string> map = Info.Request(conn, "node", "features");
                        string nodeName;

                        if (map.TryGetValue("node", out nodeName))
                        {
                            this.name = nodeName;
                            this.address = address;
                            SetFeatures(map);
                            return;
                        }
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
                catch (Exception e)
                {
                    // Try next address.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Alias " + addresses[i] + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            if (exception == null)
            {
                throw new AerospikeException.Connection("Failed to find addresses for " + host);
            }
            throw exception;
        }
        public static RegisterTask Register(Cluster cluster, Policy policy, string content, string serverPath, Language language)
        {
            StringBuilder sb = new StringBuilder(serverPath.Length + content.Length + 100);

            sb.Append("udf-put:filename=");
            sb.Append(serverPath);
            sb.Append(";content=");
            sb.Append(content);
            sb.Append(";content-len=");
            sb.Append(content.Length);
            sb.Append(";udf-type=");
            sb.Append(language);
            sb.Append(";");

            // Send UDF to one node. That node will distribute the UDF to other nodes.
            string     command = sb.ToString();
            Node       node    = cluster.GetRandomNode();
            int        timeout = (policy == null) ? 0 : policy.timeout;
            Connection conn    = node.GetConnection(timeout);

            try
            {
                Info info = new Info(conn, command);
                Info.NameValueParser parser = info.GetNameValueParser();
                string error   = null;
                string file    = null;
                string line    = null;
                string message = null;

                while (parser.Next())
                {
                    string name = parser.GetName();

                    if (name.Equals("error"))
                    {
                        error = parser.GetValue();
                    }
                    else if (name.Equals("file"))
                    {
                        file = parser.GetValue();
                    }
                    else if (name.Equals("line"))
                    {
                        line = parser.GetValue();
                    }
                    else if (name.Equals("message"))
                    {
                        message = parser.GetStringBase64();
                    }
                }

                if (error != null)
                {
                    throw new AerospikeException("Registration failed: " + error + Environment.NewLine +
                                                 "File: " + file + Environment.NewLine +
                                                 "Line: " + line + Environment.NewLine +
                                                 "Message: " + message
                                                 );
                }
                node.PutConnection(conn);
                return(new RegisterTask(cluster, serverPath));
            }
            catch (Exception)
            {
                conn.Close();
                throw;
            }
        }
예제 #6
0
        /// <summary>
        /// Get a socket connection from connection pool to the server node.
        /// </summary>
        /// <param name="timeoutMillis">connection timeout value in milliseconds if a new connection is created</param>	
        /// <exception cref="AerospikeException">if a connection could not be provided</exception>
        public Connection GetConnection(int timeoutMillis)
        {
            Connection conn;
            while (connectionQueue.TryTake(out conn))
            {
                if (conn.IsValid())
                {
                    try
                    {
                        conn.SetTimeout(timeoutMillis);
                        return conn;
                    }
                    catch (Exception e)
                    {
                        // Set timeout failed. Something is probably wrong with timeout
                        // value itself, so don't empty queue retrying.  Just get out.
                        conn.Close();
                        throw new AerospikeException.Connection(e);
                    }
                }
                conn.Close();
            }
            conn = new Connection(address, timeoutMillis, cluster.maxSocketIdleMillis);

            if (cluster.user != null)
            {
                try
                {
                    AdminCommand command = new AdminCommand();
                    command.Authenticate(conn, cluster.user, cluster.password);
                }
                catch (Exception)
                {
                    // Socket not authenticated.  Do not put back into pool.
                    conn.Close();
                    throw;
                }
            }
            return conn;
        }
예제 #7
0
        /// <summary>
        /// Request current status from server node.
        /// </summary>
        public void Refresh(Peers peers)
        {
            if (!active)
            {
                return;
            }

            try
            {
                if (tendConnection.IsClosed())
                {
                    tendConnection = CreateConnection(host.tlsName, address, cluster.connectionTimeout, null);

                    if (cluster.user != null)
                    {
                        try
                        {
                            if (!EnsureLogin())
                            {
                                AdminCommand command = new AdminCommand(ThreadLocalData.GetBuffer(), 0);

                                if (!command.Authenticate(cluster, tendConnection, sessionToken))
                                {
                                    // Authentication failed.  Session token probably expired.
                                    // Must login again to get new session token.
                                    command.Login(cluster, tendConnection, out sessionToken, out sessionExpiration);
                                }
                            }
                        }
                        catch (Exception)
                        {
                            tendConnection.Close(this);
                            throw;
                        }
                    }
                }
                else
                {
                    if (cluster.user != null)
                    {
                        EnsureLogin();
                    }
                }

                if (peers.usePeers)
                {
                    string[] commands = cluster.rackAware ? INFO_PERIODIC_REB : INFO_PERIODIC;
                    Dictionary <string, string> infoMap = Info.Request(tendConnection, commands);

                    VerifyNodeName(infoMap);
                    VerifyPeersGeneration(infoMap, peers);
                    VerifyPartitionGeneration(infoMap);

                    if (cluster.rackAware)
                    {
                        VerifyRebalanceGeneration(infoMap);
                    }
                }
                else
                {
                    string[] commands = cluster.useServicesAlternate ?
                                        new string[] { "node", "partition-generation", "services-alternate" } :
                    new string[] { "node", "partition-generation", "services" };

                    Dictionary <string, string> infoMap = Info.Request(tendConnection, commands);
                    VerifyNodeName(infoMap);
                    VerifyPartitionGeneration(infoMap);
                    AddFriends(infoMap, peers);
                }
                peers.refreshCount++;
                failures = 0;
            }
            catch (Exception e)
            {
                if (peers.usePeers)
                {
                    peers.genChanged = true;
                }
                RefreshFailed(e);
            }
        }
예제 #8
0
 /// <summary>
 /// Close connection and decrement connection count.
 /// </summary>
 public void CloseConnection(Connection conn)
 {
     conn.pool.DecrementTotal();
     conn.Close(this);
 }
        private void SetAddress(Cluster cluster, Dictionary <string, string> map, string addressCommand, string tlsName)
        {
            if (!map.TryGetValue(addressCommand, out var result) || result == null || result.Length == 0)
            {
                // Server does not support service level call (service-clear-std, ...).
                // Load balancer detection is not possible.
                return;
            }

            List <Host> hosts = Host.ParseServiceHosts(result);
            Host        h;

            // Search real hosts for seed.
            foreach (Host host in hosts)
            {
                h = host;

                string alt;
                if (cluster.ipMap != null && cluster.ipMap.TryGetValue(h.name, out alt))
                {
                    h = new Host(alt, h.port);
                }

                if (h.Equals(this.primaryHost))
                {
                    // Found seed which is not a load balancer.
                    return;
                }
            }

            // Seed not found, so seed is probably a load balancer.
            // Find first valid real host.
            foreach (Host host in hosts)
            {
                try
                {
                    h = host;

                    string alt;
                    if (cluster.ipMap != null && cluster.ipMap.TryGetValue(h.name, out alt))
                    {
                        h = new Host(alt, h.port);
                    }

                    IPAddress[] addresses = Connection.GetHostAddresses(h.name, cluster.connectionTimeout);

                    foreach (IPAddress address in addresses)
                    {
                        try
                        {
                            IPEndPoint socketAddress = new IPEndPoint(address, h.port);
                            Connection conn          = (cluster.tlsPolicy != null) ?
                                                       new TlsConnection(cluster.tlsPolicy, tlsName, socketAddress, cluster.connectionTimeout, cluster.maxSocketIdleMillis, null) :
                                                       new Connection(socketAddress, cluster.connectionTimeout, cluster.maxSocketIdleMillis, null);

                            try
                            {
                                if (cluster.user != null)
                                {
                                    AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);

                                    if (!admin.Authenticate(cluster, conn, this.sessionToken))
                                    {
                                        throw new AerospikeException("Authentication failed");
                                    }
                                }

                                // Authenticated connection.  Set real host.
                                SetAliases(addresses, tlsName, h.port);
                                this.primaryHost    = new Host(address.ToString(), tlsName, h.port);
                                this.primaryAddress = socketAddress;
                                this.primaryConn.Close();
                                this.primaryConn = conn;
                                return;
                            }
                            catch (Exception)
                            {
                                conn.Close();
                            }
                        }
                        catch (Exception)
                        {
                            // Try next address.
                        }
                    }
                }
                catch (Exception)
                {
                    // Try next host.
                }
            }

            // Failed to find a valid address. IP Address is probably internal on the cloud
            // because the server access-address is not configured.  Log warning and continue
            // with original seed.
            if (Log.InfoEnabled())
            {
                Log.Info("Invalid address " + result + ". access-address is probably not configured on server.");
            }
        }
        private void ValidateAddress(Cluster cluster, IPAddress address, string tlsName, int port, bool detectLoadBalancer)
        {
            IPEndPoint socketAddress = new IPEndPoint(address, port);
            Connection conn          = (cluster.tlsPolicy != null) ?
                                       new TlsConnection(cluster.tlsPolicy, tlsName, socketAddress, cluster.connectionTimeout, cluster.maxSocketIdleMillis, null) :
                                       new Connection(socketAddress, cluster.connectionTimeout, cluster.maxSocketIdleMillis, null);

            try
            {
                if (cluster.user != null)
                {
                    // Login
                    AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);
                    admin.Login(cluster, conn, out sessionToken, out sessionExpiration);

                    if (cluster.tlsPolicy != null && cluster.tlsPolicy.forLoginOnly)
                    {
                        // Switch to using non-TLS socket.
                        SwitchClear sc = new SwitchClear(cluster, conn, sessionToken);
                        conn.Close();
                        address       = sc.clearAddress;
                        socketAddress = sc.clearSocketAddress;
                        conn          = sc.clearConn;

                        // Disable load balancer detection since non-TLS address has already
                        // been retrieved via service info command.
                        detectLoadBalancer = false;
                    }
                }

                List <string> commands = new List <string>(5);
                commands.Add("node");
                commands.Add("partition-generation");
                commands.Add("features");

                bool hasClusterName = cluster.HasClusterName;

                if (hasClusterName)
                {
                    commands.Add("cluster-name");
                }

                string addressCommand = null;

                if (detectLoadBalancer)
                {
                    // Seed may be load balancer with changing address. Determine real address.
                    addressCommand = (cluster.tlsPolicy != null) ?
                                     cluster.useServicesAlternate ? "service-tls-alt" : "service-tls-std" :
                                     cluster.useServicesAlternate ? "service-clear-alt" : "service-clear-std";

                    commands.Add(addressCommand);
                }

                // Issue commands.
                Dictionary <string, string> map = Info.Request(conn, commands);

                // Node returned results.
                this.primaryHost    = new Host(address.ToString(), tlsName, port);
                this.primaryAddress = socketAddress;
                this.primaryConn    = conn;

                ValidateNode(map);
                ValidatePartitionGeneration(map);
                SetFeatures(map);

                if (hasClusterName)
                {
                    ValidateClusterName(cluster, map);
                }

                if (addressCommand != null)
                {
                    SetAddress(cluster, map, addressCommand, tlsName);
                }
            }
            catch (Exception)
            {
                conn.Close();
                throw;
            }
        }
예제 #11
0
 /// <summary>
 /// Close connection and decrement connection count.
 /// </summary>
 public void CloseConnection(Connection conn)
 {
     Interlocked.Decrement(ref connectionCount);
     conn.Close();
 }
        public NodeValidator(Cluster cluster, Host host)
        {
            IPAddress[] addresses = Connection.GetHostAddresses(host.name, DEFAULT_TIMEOUT);
            aliases = new Host[addresses.Length];

            for (int i = 0; i < addresses.Length; i++)
            {
                aliases[i] = new Host(addresses[i].ToString(), host.port);
            }

            Exception exception = null;

            for (int i = 0; i < addresses.Length; i++)
            {
                try
                {
                    IPEndPoint address = new IPEndPoint(addresses[i], host.port);
                    Connection conn    = new Connection(address, cluster.connectionTimeout);

                    try
                    {
                        if (cluster.user != null)
                        {
                            AdminCommand command = new AdminCommand();
                            command.Authenticate(conn, cluster.user, cluster.password);
                        }
                        Dictionary <string, string> map = Info.Request(conn, "node", "features");
                        string nodeName;

                        if (map.TryGetValue("node", out nodeName))
                        {
                            this.name    = nodeName;
                            this.address = address;
                            SetFeatures(map);
                            return;
                        }
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
                catch (Exception e)
                {
                    // Try next address.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Alias " + addresses[i] + " failed: " + Util.GetErrorMessage(e));
                    }

                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            if (exception == null)
            {
                throw new AerospikeException.Connection("Failed to find addresses for " + host);
            }
            throw exception;
        }
        public void Execute()
        {
            Policy   policy          = GetPolicy();
            int      remainingMillis = policy.timeout;
            DateTime limit           = DateTime.UtcNow.AddMilliseconds(remainingMillis);
            Node     node            = null;
            int      failedNodes     = 0;
            int      failedConns     = 0;
            int      iterations      = 0;

            dataBuffer = ThreadLocalData.GetBuffer();

            // Execute command until successful, timed out or maximum iterations have been reached.
            while (true)
            {
                try
                {
                    node = GetNode();
                    Connection conn = node.GetConnection(remainingMillis);

                    try
                    {
                        // Set command buffer.
                        WriteBuffer();

                        // Reset timeout in send buffer (destined for server) and socket.
                        ByteUtil.IntToBytes((uint)remainingMillis, dataBuffer, 22);

                        // Send command.
                        conn.Write(dataBuffer, dataOffset);

                        // Parse results.
                        ParseResult(conn);

                        // Reflect healthy status.
                        conn.UpdateLastUsed();

                        // Put connection back in pool.
                        node.PutConnection(conn);

                        // Command has completed successfully.  Exit method.
                        return;
                    }
                    catch (AerospikeException ae)
                    {
                        if (ae.KeepConnection())
                        {
                            // Put connection back in pool.
                            conn.UpdateLastUsed();
                            node.PutConnection(conn);
                        }
                        else
                        {
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            conn.Close();
                        }
                        throw;
                    }
                    catch (SocketException ioe)
                    {
                        // IO errors are considered temporary anomalies.  Retry.
                        // Close socket to flush out possible garbage.  Do not put back in pool.
                        conn.Close();

                        if (Log.DebugEnabled())
                        {
                            Log.Debug("Node " + node + ": " + Util.GetErrorMessage(ioe));
                        }
                    }
                    catch (Exception)
                    {
                        // All runtime exceptions are considered fatal.  Do not retry.
                        // Close socket to flush out possible garbage.  Do not put back in pool.
                        conn.Close();
                        throw;
                    }
                }
                catch (AerospikeException.InvalidNode)
                {
                    // Node is currently inactive.  Retry.
                    failedNodes++;
                }
                catch (AerospikeException.Connection ce)
                {
                    // Socket connection error has occurred. Retry.
                    if (Log.DebugEnabled())
                    {
                        Log.Debug("Node " + node + ": " + Util.GetErrorMessage(ce));
                    }
                    failedConns++;
                }

                if (++iterations > policy.maxRetries)
                {
                    break;
                }

                // Check for client timeout.
                if (policy.timeout > 0)
                {
                    remainingMillis = (int)limit.Subtract(DateTime.UtcNow).TotalMilliseconds - policy.sleepBetweenRetries;

                    if (remainingMillis <= 0)
                    {
                        break;
                    }
                }

                if (policy.sleepBetweenRetries > 0)
                {
                    // Sleep before trying again.
                    Util.Sleep(policy.sleepBetweenRetries);
                }

                // Reset node reference and try again.
                node = null;
            }

            throw new AerospikeException.Timeout(node, policy.timeout, iterations, failedNodes, failedConns);
        }