public void PruneNodes_Does_Not_Remove_Single_Service_Nodes() { //Arrange var config = ResourceHelper.ReadResource(@"Documents\Configs\rev-36310-service-per-node.json", InternalSerializationContext.Default.BucketConfig); var context = new ClusterContext(); var hosts = new List <string> { "10.143.194.101", "10.143.194.102", "10.143.194.103", "10.143.194.104" }; hosts.ForEach(x => context.AddNode(CreateMockedNode(x, 11210))); //Act context.PruneNodes(config); //Assert foreach (var host in hosts) { var removed = new HostEndpointWithPort(host, 11210); Assert.Contains(context.Nodes, node => node.EndPoint.Equals(removed)); } }
public async Task <IClusterNode> CreateAndConnectAsync(HostEndpointWithPort endPoint, NodeAdapter?nodeAdapter, CancellationToken cancellationToken = default) { var clusterNode = new ClusterNode(_clusterContext, _connectionPoolFactory, _logger, _operationBuilderPool, _circuitBreaker, _saslMechanismFactory, _redactor, endPoint, nodeAdapter, _tracer); //ensure server calls are made to set the state await clusterNode.InitializeAsync().ConfigureAwait(false); return(clusterNode); }
public async Task Test_Filter_Removed_Nodes(string oldConfigPath, string newConfigPath) { var oldConfig = ResourceHelper.ReadResource(oldConfigPath, InternalSerializationContext.Default.BucketConfig); var newConfig = ResourceHelper.ReadResource(newConfigPath, InternalSerializationContext.Default.BucketConfig); var options = new ClusterOptions(); var bucketNodes = new ConcurrentDictionary <HostEndpointWithPort, IClusterNode>(); var context = new ClusterContext(new CancellationTokenSource(), options); var ipEndpointService = context.ServiceProvider.GetRequiredService <IIpEndPointService>(); //load up the initial state after bootstrapping foreach (var server in oldConfig.GetNodes()) { var endPoint = HostEndpointWithPort.Create(server, options); var clusterNode = new ClusterNode(context, new Mock <IConnectionPoolFactory>().Object, new Mock <ILogger <ClusterNode> >().Object, new DefaultObjectPool <OperationBuilder>(new OperationBuilderPoolPolicy()), new Mock <ICircuitBreaker>().Object, new Mock <ISaslMechanismFactory>().Object, new TypedRedactor(RedactionLevel.None), endPoint, server, NoopRequestTracer.Instance); context.AddNode(clusterNode); bucketNodes.TryAdd(endPoint, clusterNode); } foreach (var nodesExt in newConfig.GetNodes()) { var endPoint = HostEndpointWithPort.Create(nodesExt, options); if (bucketNodes.ContainsKey(endPoint)) { continue; } var clusterNode = new ClusterNode(context, new Mock <IConnectionPoolFactory>().Object, new Mock <ILogger <ClusterNode> >().Object, new DefaultObjectPool <OperationBuilder>(new OperationBuilderPoolPolicy()), new Mock <ICircuitBreaker>().Object, new Mock <ISaslMechanismFactory>().Object, new TypedRedactor(RedactionLevel.None), endPoint, nodesExt, NoopRequestTracer.Instance); context.AddNode(clusterNode); bucketNodes.TryAdd(endPoint, clusterNode); } context.PruneNodes(newConfig); Assert.Equal(newConfig.NodesExt.Count, context.Nodes.Count); }
public void SpanFormattable_Redacts_Properly() { var options = new ClusterOptions { RedactionLevel = RedactionLevel.Full }; var redactor = new TypedRedactor(options); var spanFormattable = new HostEndpointWithPort("localhost", 8675309); var asString = $"{redactor.UserData(spanFormattable)} is formatted"; Assert.Contains("</ud>", asString); }
private IList <HostEndpointWithPort> GetEndPoints(BucketConfig config) { var endPoints = new List <HostEndpointWithPort>(); foreach (var node in config.GetNodes().Where(p => p.IsKvNode)) { //log any alternate address mapping _logger.LogInformation(node.ToString()); endPoints.Add(HostEndpointWithPort.Create(node, _clusterOptions)); } return(endPoints); }
public void PruneNodes_Removes_Rebalanced_Node() { //Arrange var config = ResourceHelper.ReadResource(@"Documents\Configs\config-error.json", InternalSerializationContext.Default.BucketConfig); var context = new ClusterContext(); var hosts = new List <string> { "10.143.194.101", "10.143.194.102", "10.143.194.103", "10.143.194.104" }; hosts.ForEach(x => context.AddNode(CreateMockedNode(x, 11210))); //Act context.PruneNodes(config); //Assert var removed = new HostEndpointWithPort("10.143.194.102", 11210); Assert.DoesNotContain(context.Nodes, node => node.EndPoint.Equals(removed)); }
public Task <IClusterNode> CreateAndConnectAsync(HostEndpointWithPort endPoint, CancellationToken cancellationToken = default) { return(CreateAndConnectAsync(endPoint, null, cancellationToken)); }
public async Task <IConnection> CreateAndConnectAsync(HostEndpointWithPort hostEndpoint, CancellationToken cancellationToken = default) { if (_clusterOptions.IsCapella && !_clusterOptions.EffectiveEnableTls) { _multiplexLogger.LogWarning("TLS is required when connecting to Couchbase Capella. Please enable TLS by prefixing the connection string with \"couchbases://\" (note the final 's')."); } var endPoint = await _ipEndPointService.GetIpEndPointAsync(hostEndpoint.Host, hostEndpoint.Port, cancellationToken) .ConfigureAwait(false); if (endPoint is null) { throw new ConnectException($"Unable to resolve host '{hostEndpoint}'."); } var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { var connectTask = socket.ConnectAsync(endPoint); var whichTask = await Task .WhenAny(connectTask, Task.Delay(_clusterOptions.KvConnectTimeout, cancellationToken)) .ConfigureAwait(false); if (whichTask != connectTask) { // Was a timeout const int connectionTimedOut = 10060; throw new SocketException(connectionTimedOut); } } catch { socket.Dispose(); throw; } #if NETCOREAPP3_0_OR_GREATER _multiplexLogger.LogDebug("Setting TCP Keep-Alives using SocketOptions - enable keep-alives {EnableTcpKeepAlives}, time {TcpKeepAliveTime}, interval {TcpKeepAliveInterval}.", _clusterOptions.EnableTcpKeepAlives, _clusterOptions.TcpKeepAliveTime, _clusterOptions.TcpKeepAliveInterval); if (!socket.TryEnableKeepAlives(_clusterOptions.EnableTcpKeepAlives, (int)_clusterOptions.TcpKeepAliveTime.TotalSeconds, (int)_clusterOptions.TcpKeepAliveInterval.TotalSeconds, out string setKeepAliveMessage) ) { _multiplexLogger.LogWarning(setKeepAliveMessage); } #else _multiplexLogger.LogDebug( "Setting TCP Keep-Alives using Socket.IOControl on {endpoint} - enable tcp keep-alives {EnableTcpKeepAlives}, time {TcpKeepAliveTime}, interval {TcpKeepAliveInterval}", endPoint, _clusterOptions.EnableTcpKeepAlives, _clusterOptions.TcpKeepAliveTime, _clusterOptions.TcpKeepAliveInterval); if (!socket.TrySetKeepAlives(_clusterOptions.EnableTcpKeepAlives, (uint)_clusterOptions.TcpKeepAliveTime.TotalMilliseconds, (uint)_clusterOptions.TcpKeepAliveInterval.TotalMilliseconds, out var setKeepAliveMessage) ) { _multiplexLogger.LogWarning(setKeepAliveMessage); } #endif if (_clusterOptions.EffectiveEnableTls) { //Check if were using x509 auth, if so fetch the certificates X509Certificate2Collection?certs = null; if (_clusterOptions.X509CertificateFactory != null) { certs = _clusterOptions.X509CertificateFactory.GetCertificates(); if (certs == null || certs.Count == 0) { throw new AuthenticationException( "No certificates matching the X509FindType and specified FindValue were found in the Certificate Store."); } if (_sslLogger.IsEnabled(LogLevel.Debug)) { foreach (var cert in certs) { _sslLogger.LogDebug("Cert sent {cert.FriendlyName} - Thumbprint {cert.Thumbprint}", cert.FriendlyName, cert.Thumbprint); } _sslLogger.LogDebug("Sending {certs.Count} certificates to the server.", certs.Count); } } //The endpoint we are connecting to var targetHost = _clusterOptions.ForceIpAsTargetHost ? endPoint.Address.ToString() : hostEndpoint.Host; //create the sslstream with appropriate authentication RemoteCertificateValidationCallback?certValidationCallback = _clusterOptions.KvCertificateCallbackValidation; if (certValidationCallback == null) { certValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { if (_clusterOptions.KvIgnoreRemoteCertificateNameMismatch && CertificateFactory.ValidatorWithIgnoreNameMismatch(sender, certificate, chain, sslPolicyErrors)) { return(true); } return(CertificateFactory.ValidateWithDefaultCertificates(sender, certificate, chain, sslPolicyErrors)); }; } var sslStream = new SslStream(new NetworkStream(socket, true), false, certValidationCallback); #if !NETCOREAPP3_1_OR_GREATER await sslStream.AuthenticateAsClientAsync(targetHost, certs, _clusterOptions.EnabledSslProtocols, _clusterOptions.EnableCertificateRevocation) .ConfigureAwait(false); #else SslClientAuthenticationOptions sslOptions = new SslClientAuthenticationOptions() { TargetHost = targetHost, ClientCertificates = certs, EnabledSslProtocols = _clusterOptions.EnabledSslProtocols, CertificateRevocationCheckMode = _clusterOptions.EnableCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck }; if (_clusterOptions.EnabledTlsCipherSuites != null && _clusterOptions.EnabledTlsCipherSuites.Count > 0) { sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(_clusterOptions.EnabledTlsCipherSuites); } await sslStream.AuthenticateAsClientAsync(sslOptions) .ConfigureAwait(false); #endif var isSecure = sslStream.IsAuthenticated && sslStream.IsSigned && sslStream.IsEncrypted; _sslLogger.LogDebug("IsAuthenticated {0} on {1}", sslStream.IsAuthenticated, targetHost); _sslLogger.LogDebug("IsSigned {0} on {1}", sslStream.IsSigned, targetHost); _sslLogger.LogDebug("IsEncrypted {0} on {1}", sslStream.IsEncrypted, targetHost); //punt if we cannot successfully authenticate if (!isSecure) { throw new AuthenticationException($"The SSL/TLS connection could not be authenticated on [{targetHost}]."); } return(new SslConnection(sslStream, socket.LocalEndPoint !, socket.RemoteEndPoint !, _sslLogger, _multiplexLogger)); } return(new MultiplexingConnection(socket, _multiplexLogger)); }
public Task <IConnection> CreateAndConnectAsync(HostEndpointWithPort hostEndpoint, CancellationToken cancellationToken = default) { return(Task.FromResult <IConnection>(new MockConnection())); }
public KetamaNode(HostEndpointWithPort server) { _server = server; }