private void ValidateAlias(Cluster cluster, IPAddress ipAddress, int port)
        {
            IPEndPoint address = new IPEndPoint(ipAddress, 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;
                    this.conn    = conn;
                    SetFeatures(map);
                    return;
                }
                else
                {
                    throw new AerospikeException.InvalidNode();
                }
            }
            catch (Exception)
            {
                conn.Close();
                throw;
            }
        }
예제 #2
0
        public Cluster(ClientPolicy policy, Host[] hosts)
        {
            this.seeds = hosts;

            if (policy.user != null && policy.user.Length > 0)
            {
                this.user = ByteUtil.StringToUtf8(policy.user);

                string pass = policy.password;

                if (pass == null)
                {
                    pass = "";
                }

                if (!(pass.Length == 60 && pass.StartsWith("$2a$")))
                {
                    pass = AdminCommand.HashPassword(pass);
                }
                this.password = ByteUtil.StringToUtf8(pass);
            }

            connectionQueueSize = policy.maxConnsPerNode;
            connectionTimeout   = policy.timeout;
            maxSocketIdleMillis = 1000 * ((policy.maxSocketIdle <= MaxSocketIdleSecondLimit) ? policy.maxSocketIdle : MaxSocketIdleSecondLimit);
            tendInterval        = policy.tendInterval;
            ipMap = policy.ipMap;
            requestProleReplicas = policy.requestProleReplicas;
            useServicesAlternate = policy.useServicesAlternate;

            aliases      = new Dictionary <Host, Node>();
            nodes        = new Node[0];
            partitionMap = new Dictionary <string, Node[][]>();
        }
        public Cluster(ClientPolicy policy, Host[] hosts)
        {
            this.seeds = hosts;

            if (policy.user != null && policy.user.Length > 0)
            {
                this.user = ByteUtil.StringToUtf8(policy.user);

                string pass = policy.password;

                if (pass == null)
                {
                    pass = "";
                }

                if (!(pass.Length == 60 && pass.StartsWith("$2a$")))
                {
                    pass = AdminCommand.HashPassword(pass);
                }
                this.password = ByteUtil.StringToUtf8(pass);
            }

            connectionQueueSize = policy.maxThreads + 1;             // Add one connection for tend thread.
            connectionTimeout   = policy.timeout;
            maxSocketIdle       = policy.maxSocketIdle;
            tendInterval        = policy.tendInterval;
            ipMap = policy.ipMap;
            requestProleReplicas = policy.requestProleReplicas;

            aliases      = new Dictionary <Host, Node>();
            nodes        = new Node[0];
            partitionMap = new Dictionary <string, Node[][]>();
        }
예제 #4
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.
                        CloseConnection(conn);
                        throw new AerospikeException.Connection(e);
                    }
                }
                CloseConnection(conn);
            }

            if (Interlocked.Increment(ref connectionCount) <= cluster.connectionQueueSize)
            {
                try
                {
                    conn = new Connection(address, timeoutMillis, cluster.maxSocketIdleMillis);
                }
                catch (Exception)
                {
                    Interlocked.Decrement(ref connectionCount);
                    throw;
                }

                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.
                        CloseConnection(conn);
                        throw;
                    }
                }
                return(conn);
            }
            else
            {
                Interlocked.Decrement(ref connectionCount);
                throw new AerospikeException.Connection(ResultCode.NO_MORE_CONNECTIONS,
                                                        "Node " + this + " max connections " + cluster.connectionQueueSize + " would be exceeded.");
            }
        }
예제 #5
0
        // Switch from TLS connection to non-TLS connection.
        internal SwitchClear(Cluster cluster, Connection conn, byte[] sessionToken)
        {
            // Obtain non-TLS addresses.
            string      command = cluster.useServicesAlternate ? "service-clear-alt" : "service-clear-std";
            string      result  = Info.Request(conn, command);
            List <Host> hosts   = Host.ParseServiceHosts(result);
            Host        clearHost;

            // Find first valid non-TLS host.
            foreach (Host host in hosts)
            {
                try
                {
                    clearHost = host;

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

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

                    foreach (IPAddress ia in addresses)
                    {
                        try
                        {
                            clearAddress       = ia;
                            clearSocketAddress = new IPEndPoint(ia, clearHost.port);
                            clearConn          = new Connection(clearSocketAddress, cluster.connectionTimeout, null);

                            try
                            {
                                AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);

                                if (!admin.Authenticate(cluster, clearConn, sessionToken))
                                {
                                    throw new AerospikeException("Authentication failed");
                                }
                                return;                                 // Authenticated clear connection.
                            }
                            catch (Exception)
                            {
                                clearConn.Close();
                            }
                        }
                        catch (Exception)
                        {
                            // Try next address.
                        }
                    }
                }
                catch (Exception)
                {
                    // Try next host.
                }
            }
            throw new AerospikeException("Invalid non-TLS address: " + result);
        }
예제 #6
0
        /// <summary>
        /// Request current status from server node.
        /// </summary>
        public void Refresh(Peers peers)
        {
            if (!active)
            {
                return;
            }

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

                    if (cluster.user != null)
                    {
                        try
                        {
                            AdminCommand command = new AdminCommand(ThreadLocalData.GetBuffer(), 0);
                            command.Authenticate(tendConnection, cluster.user, cluster.password);
                        }
                        catch (Exception)
                        {
                            tendConnection.Close();
                            throw;
                        }
                    }
                }

                if (peers.usePeers)
                {
                    Dictionary <string, string> infoMap = Info.Request(tendConnection, "node", "peers-generation", "partition-generation");
                    VerifyNodeName(infoMap);
                    VerifyPeersGeneration(infoMap, peers);
                    VerifyPartitionGeneration(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);
            }
        }
예제 #7
0
        public Cluster(ClientPolicy policy, Host[] hosts)
        {
            this.clusterName = policy.clusterName;

            // Default TLS names when TLS enabled.
            if (policy.tlsPolicy != null)
            {
                bool useClusterName = HasClusterName;

                for (int i = 0; i < hosts.Length; i++)
                {
                    Host host = hosts[i];

                    if (host.tlsName == null)
                    {
                        string tlsName = useClusterName ? clusterName : host.name;
                        hosts[i] = new Host(host.name, tlsName, host.port);
                    }
                }
            }
            this.seeds = hosts;

            if (policy.user != null && policy.user.Length > 0)
            {
                this.user = ByteUtil.StringToUtf8(policy.user);

                string pass = policy.password;

                if (pass == null)
                {
                    pass = "";
                }

                if (!(pass.Length == 60 && pass.StartsWith("$2a$")))
                {
                    pass = AdminCommand.HashPassword(pass);
                }
                this.password = ByteUtil.StringToUtf8(pass);
            }

            tlsPolicy           = policy.tlsPolicy;
            connectionQueueSize = policy.maxConnsPerNode;
            connPoolsPerNode    = policy.connPoolsPerNode;
            connectionTimeout   = policy.timeout;
            maxSocketIdleMillis = 1000 * ((policy.maxSocketIdle <= MaxSocketIdleSecondLimit) ? policy.maxSocketIdle : MaxSocketIdleSecondLimit);
            tendInterval        = policy.tendInterval;
            ipMap = policy.ipMap;
            requestProleReplicas = policy.requestProleReplicas;
            useServicesAlternate = policy.useServicesAlternate;

            aliases      = new Dictionary <Host, Node>();
            nodesMap     = new Dictionary <string, Node>();
            nodes        = new Node[0];
            partitionMap = new Dictionary <string, Partitions>();
            cancel       = new CancellationTokenSource();
            cancelToken  = cancel.Token;
        }
예제 #8
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)
                    {
                        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);
                            }
                        }
                    }
                }
                else
                {
                    if (cluster.user != null)
                    {
                        EnsureLogin();
                    }
                }

                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);
                }
                peers.refreshCount++;
                failures = 0;
            }
            catch (Exception e)
            {
                peers.genChanged = true;
                RefreshFailed(e);
            }
        }
예제 #9
0
 private bool EnsureLogin()
 {
     if (performLogin > 0 || (sessionExpiration.HasValue && DateTime.Compare(DateTime.UtcNow, sessionExpiration.Value) >= 0))
     {
         AdminCommand admin = new AdminCommand(ThreadLocalData.GetBuffer(), 0);
         admin.Login(cluster, tendConnection, out sessionToken, out sessionExpiration);
         performLogin = 0;
         return(true);
     }
     return(false);
 }
예제 #10
0
        private void ValidateAlias(Cluster cluster, IPAddress ipAddress, Host alias)
        {
            IPEndPoint address = new IPEndPoint(ipAddress, alias.port);
            Connection conn    = cluster.CreateConnection(alias.tlsName, address, cluster.connectionTimeout);

            try
            {
                if (cluster.user != null)
                {
                    AdminCommand command = new AdminCommand(ThreadLocalData.GetBuffer(), 0);
                    command.Authenticate(conn, cluster.user, cluster.password);
                }
                Dictionary <string, string> map;
                bool hasClusterName = cluster.HasClusterName;

                if (hasClusterName)
                {
                    map = Info.Request(conn, "node", "features", "cluster-name");
                }
                else
                {
                    map = Info.Request(conn, "node", "features");
                }

                string nodeName;

                if (!map.TryGetValue("node", out nodeName))
                {
                    throw new AerospikeException.InvalidNode();
                }

                if (hasClusterName)
                {
                    string id;

                    if (!map.TryGetValue("cluster-name", out id) || !cluster.clusterName.Equals(id))
                    {
                        throw new AerospikeException.InvalidNode("Node " + nodeName + ' ' + alias + ' ' + " expected cluster name '" + cluster.clusterName + "' received '" + id + "'");
                    }
                }

                this.name           = nodeName;
                this.primaryHost    = alias;
                this.primaryAddress = address;
                this.conn           = conn;
                SetFeatures(map);
            }
            catch (Exception)
            {
                conn.Close();
                throw;
            }
        }
 internal void ConnectionCreated()
 {
     if (cluster.user != null)
     {
         AdminCommand command = new AdminCommand(dataBuffer, 0);
         dataLength = command.SetAuthenticate(cluster, node.sessionToken);
         eventArgs.SetBuffer(dataBuffer, 0, dataLength);
         dataOffset = 0;
         Send();
         return;
     }
     ConnectionReady();
 }
예제 #12
0
        private void ConnectionCreated()
        {
            if (cluster.user != null)
            {
                inAuthenticate = true;
                // Authentication messages are small.  Set a reasonable upper bound.
                dataOffset = 200;
                SizeBuffer();

                AdminCommand command = new AdminCommand(dataBuffer, dataOffset);
                dataLength = command.SetAuthenticate(cluster, node.sessionToken);
                eventArgs.SetBuffer(dataBuffer, dataOffset, dataLength - dataOffset);
                Send();
                return;
            }
            ConnectionReady();
        }
예제 #13
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);
        }
        private void ConnectionCreated()
        {
            if (complete != 0)
            {
                AlreadyCompleted(complete);
                return;
            }

            if (cluster.user != null)
            {
                inAuthenticate = true;
                // Authentication messages are small.  Set a reasonable upper bound.
                dataOffset = 200;
                SizeBuffer();

                AdminCommand command = new AdminCommand(dataBuffer);
                dataLength = command.SetAuthenticate(cluster.user, cluster.password);
                dataOffset = 0;
                eventArgs.SetBuffer(dataBuffer, dataOffset, dataLength);
                Send();
                return;
            }
            ConnectionReady();
        }
예제 #15
0
        private Connection CreateConnection(Pool <Connection> pool)
        {
            Connection conn = CreateConnection(host.tlsName, address, cluster.connectionTimeout, pool);

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

                    if (!command.Authenticate(cluster, conn, sessionToken))
                    {
                        throw new AerospikeException("Authentication failed");
                    }
                }
                catch (Exception)
                {
                    // Socket not authenticated.  Do not put back into pool.
                    CloseConnection(conn);
                    throw;
                }
            }
            return(conn);
        }
 /// <summary>
 /// Remove roles from user's list of roles.
 /// </summary>
 /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
 /// <param name="user">user name</param>
 /// <param name="roles">role names.  Predefined roles are listed in Role.cs</param>
 public void RevokeRoles(AdminPolicy policy, string user, IList<string> roles)
 {
     AdminCommand command = new AdminCommand();
     command.RevokeRoles(cluster, policy, user, roles);
 }
 /// <summary>
 /// Remove user from cluster.
 /// </summary>
 /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
 /// <param name="user">user name</param>
 public void DropUser(AdminPolicy policy, string user)
 {
     AdminCommand command = new AdminCommand();
     command.DropUser(cluster, policy, user);
 }
        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;
        }
예제 #19
0
        public Cluster(ClientPolicy policy, Host[] hosts)
        {
            this.clusterName = policy.clusterName;
            tlsPolicy        = policy.tlsPolicy;
            this.authMode    = policy.authMode;

            // Default TLS names when TLS enabled.
            if (tlsPolicy != null)
            {
                bool useClusterName = HasClusterName;

                for (int i = 0; i < hosts.Length; i++)
                {
                    Host host = hosts[i];

                    if (host.tlsName == null)
                    {
                        string tlsName = useClusterName ? clusterName : host.name;
                        hosts[i] = new Host(host.name, tlsName, host.port);
                    }
                }
            }
            else
            {
                if (authMode == AuthMode.EXTERNAL)
                {
                    throw new AerospikeException("TLS is required for authentication mode: " + authMode);
                }
            }

            this.seeds = hosts;

            if (policy.user != null && policy.user.Length > 0)
            {
                this.user = ByteUtil.StringToUtf8(policy.user);

                // Only store clear text password if external authentication is used.
                if (authMode != AuthMode.INTERNAL)
                {
                    this.password = ByteUtil.StringToUtf8(policy.password);
                }

                string pass = policy.password;

                if (pass == null)
                {
                    pass = "";
                }

                if (!(pass.Length == 60 && pass.StartsWith("$2a$")))
                {
                    pass = AdminCommand.HashPassword(pass);
                }
                this.passwordHash = ByteUtil.StringToUtf8(pass);
            }

            connectionQueueSize = policy.maxConnsPerNode;
            connPoolsPerNode    = policy.connPoolsPerNode;
            connectionTimeout   = policy.timeout;
            loginTimeout        = policy.loginTimeout;
            maxSocketIdleMillis = 1000 * ((policy.maxSocketIdle <= MaxSocketIdleSecondLimit) ? policy.maxSocketIdle : MaxSocketIdleSecondLimit);
            tendInterval        = policy.tendInterval;
            ipMap = policy.ipMap;
            useServicesAlternate = policy.useServicesAlternate;
            rackAware            = policy.rackAware;
            rackId = policy.rackId;

            aliases      = new Dictionary <Host, Node>();
            nodesMap     = new Dictionary <string, Node>();
            nodes        = new Node[0];
            partitionMap = new Dictionary <string, Partitions>();
            cancel       = new CancellationTokenSource();
            cancelToken  = cancel.Token;
        }
        private void SetAddress(Cluster cluster, Dictionary <string, string> map, string addressCommand, string tlsName)
        {
            string      result = map[addressCommand];
            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 host.
            throw new AerospikeException("Invalid address: " + result);
        }
예제 #21
0
        private void SetAddress(Cluster cluster, Dictionary <string, string> map, string addressCommand, string tlsName)
        {
            string result;

            if (!map.TryGetValue(addressCommand, out 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, null) :
                                                       new Connection(socketAddress, cluster.connectionTimeout, 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(address, 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.");
            }
        }
예제 #22
0
        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, null) :
                                       new Connection(socketAddress, cluster.connectionTimeout, 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;
            }
        }
 /// <summary>
 /// Revoke privileges from an user defined role.
 /// </summary>
 /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
 /// <param name="roleName">role name</param>
 /// <param name="privileges">privileges assigned to the role.</param>
 /// <exception cref="AerospikeException">if command fails</exception>
 public void RevokePrivileges(AdminPolicy policy, string roleName, IList<Privilege> privileges)
 {
     AdminCommand command = new AdminCommand();
     command.RevokePrivileges(cluster, policy, roleName, privileges);
 }
 /// <summary>
 /// Drop user defined role.
 /// </summary>
 /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
 /// <param name="roleName">role name</param>
 /// <exception cref="AerospikeException">if command fails</exception>
 public void DropRole(AdminPolicy policy, string roleName)
 {
     AdminCommand command = new AdminCommand();
     command.DropRole(cluster, policy, roleName);
 }
예제 #25
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.
                        CloseConnection(conn);
                        throw new AerospikeException.Connection(e);
                    }
                }
                CloseConnection(conn);
            }

            if (Interlocked.Increment(ref connectionCount) <= cluster.connectionQueueSize)
            {
                try
                {
                    conn = new Connection(address, timeoutMillis, cluster.maxSocketIdleMillis);
                }
                catch (Exception)
                {
                    Interlocked.Decrement(ref connectionCount);
                    throw;
                }

                if (cluster.user != null)
                {
                    try
                    {
                        AdminCommand command = new AdminCommand(ThreadLocalData.GetBuffer(), 0);
                        command.Authenticate(conn, cluster.user, cluster.password);
                    }
                    catch (Exception)
                    {
                        // Socket not authenticated.  Do not put back into pool.
                        CloseConnection(conn);
                        throw;
                    }
                }
                return conn;
            }
            else
            {
                Interlocked.Decrement(ref connectionCount);
                throw new AerospikeException.Connection(ResultCode.NO_MORE_CONNECTIONS,
                    "Node " + this + " max connections " + cluster.connectionQueueSize + " would be exceeded.");
            }
        }
예제 #26
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;
        }
예제 #27
0
        private void ConnectionCreated()
        {
            if (complete != 0)
            {
                AlreadyCompleted(complete);
                return;
            }

            if (cluster.user != null)
            {
                inAuthenticate = true;
                // Authentication messages are small.  Set a reasonable upper bound.
                dataOffset = 200;
                SizeBuffer();

                AdminCommand command = new AdminCommand(dataBuffer, dataOffset);
                dataLength = command.SetAuthenticate(cluster.user, cluster.password);
                eventArgs.SetBuffer(dataBuffer, dataOffset, dataLength - dataOffset);
                Send();
                return;
            }
            ConnectionReady();
        }
        /// <summary>
        /// Change user's password.  Clear-text password will be hashed using bcrypt 
        /// before sending to server.
        /// </summary>
        /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
        /// <param name="user">user name</param>
        /// <param name="password">user password in clear-text format</param>
        public void ChangePassword(AdminPolicy policy, string user, string password)
        {
            if (cluster.user == null)
            {
                throw new AerospikeException("Invalid user");
            }

            string hash = AdminCommand.HashPassword(password);
            AdminCommand command = new AdminCommand();
            byte[] userBytes = ByteUtil.StringToUtf8(user);

            if (Util.ByteArrayEquals(userBytes, cluster.user))
            {
                // Change own password.
                command.ChangePassword(cluster, policy, userBytes, hash);
            }
            else
            {
                // Change other user's password by user admin.
                command.SetPassword(cluster, policy, userBytes, hash);
            }
            cluster.ChangePassword(userBytes, hash);
        }
 /// <summary>
 /// Create user defined role.
 /// </summary>
 /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
 /// <param name="roleName">role name</param>
 /// <param name="privileges">privileges assigned to the role.</param>
 /// <exception cref="AerospikeException">if command fails </exception>
 public void CreateRole(AdminPolicy policy, string roleName, IList<Privilege> privileges)
 {
     AdminCommand command = new AdminCommand();
     command.CreateRole(cluster, policy, roleName, privileges);
 }
        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;
        }
 //-------------------------------------------------------
 // User administration
 //-------------------------------------------------------
 /// <summary>
 /// Create user with password and roles.  Clear-text password will be hashed using bcrypt 
 /// before sending to server.
 /// </summary>
 /// <param name="policy">admin configuration parameters, pass in null for defaults</param>
 /// <param name="user">user name</param>
 /// <param name="password">user password in clear-text format</param>
 /// <param name="roles">variable arguments array of role names.  Predefined roles are listed in Role.cs</param>		
 public void CreateUser(AdminPolicy policy, string user, string password, IList<string> roles)
 {
     string hash = AdminCommand.HashPassword(password);
     AdminCommand command = new AdminCommand();
     command.CreateUser(cluster, policy, user, hash, roles);
 }
예제 #32
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)
        {
            uint max = (uint)cluster.connPoolsPerNode;
            uint initialIndex;
            bool backward;

            if (max == 1)
            {
                initialIndex = 0;
                backward     = false;
            }
            else
            {
                uint iter = connectionIter++;                 // not atomic by design
                initialIndex = iter % max;
                backward     = true;
            }

            Pool <Connection> pool = connectionPools[initialIndex];
            uint       queueIndex  = initialIndex;
            Connection conn;

            while (true)
            {
                if (pool.TryDequeue(out conn))
                {
                    // Found socket.
                    // Verify that socket is active and receive buffer is empty.
                    if (cluster.IsConnCurrentTran(conn.LastUsed) && 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.
                            CloseConnection(conn);
                            throw new AerospikeException.Connection(e);
                        }
                    }
                    CloseConnection(conn);
                }
                else if (pool.IncrementTotal() <= pool.Capacity)
                {
                    // Socket not found and queue has available slot.
                    // Create new connection.
                    try
                    {
                        conn = CreateConnection(host.tlsName, address, timeoutMillis, pool);
                    }
                    catch (Exception)
                    {
                        pool.DecrementTotal();
                        throw;
                    }

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

                            if (!command.Authenticate(cluster, conn, sessionToken))
                            {
                                SignalLogin();
                                throw new AerospikeException("Authentication failed");
                            }
                        }
                        catch (Exception)
                        {
                            // Socket not authenticated.  Do not put back into pool.
                            CloseConnection(conn);
                            throw;
                        }
                    }
                    return(conn);
                }
                else
                {
                    // Socket not found and queue is full.  Try another queue.
                    pool.DecrementTotal();

                    if (backward)
                    {
                        if (queueIndex > 0)
                        {
                            queueIndex--;
                        }
                        else
                        {
                            queueIndex = initialIndex;

                            if (++queueIndex >= max)
                            {
                                break;
                            }
                            backward = false;
                        }
                    }
                    else if (++queueIndex >= max)
                    {
                        break;
                    }
                    pool = connectionPools[queueIndex];
                }
            }
            throw new AerospikeException.Connection(ResultCode.NO_MORE_CONNECTIONS,
                                                    "Node " + this + " max connections " + cluster.maxConnsPerNode + " would be exceeded.");
        }
        private void ValidateAlias(Cluster cluster, IPAddress ipAddress, int port)
        {
            IPEndPoint address = new IPEndPoint(ipAddress, port);
            Connection conn = new Connection(address, cluster.connectionTimeout);

            try
            {
                if (cluster.user != null)
                {
                    AdminCommand command = new AdminCommand(ThreadLocalData.GetBuffer(), 0);
                    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;
                    this.conn = conn;
                    SetFeatures(map);
                    return;
                }
                else
                {
                    throw new AerospikeException.InvalidNode();
                }
            }
            catch (Exception)
            {
                conn.Close();
                throw;
            }
        }