//------------------------------------------------------- // 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(); } }
/// <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(); } }
/// <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; } }
/// <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; }
/// <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); } }
/// <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; } }
/// <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); }