private TcpConnectionInfo GetConnectionInfo(ReplicationNode node, bool external) { var shutdownInfo = new ConnectionShutdownInfo { Node = node, External = external }; _outgoingFailureInfo.TryAdd(node, shutdownInfo); try { if (node is ExternalReplication exNode) { using (var requestExecutor = RequestExecutor.Create(exNode.ConnectionString.TopologyDiscoveryUrls, exNode.ConnectionString.Database, _server.Server.Certificate.Certificate, DocumentConventions.Default)) using (_server.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx)) { var database = exNode.ConnectionString.Database; var cmd = new GetTcpInfoCommand("extrenal-replication", database); requestExecutor.Execute(cmd, ctx); node.Database = database; node.Url = requestExecutor.Url; return(cmd.Result); } } if (node is InternalReplication internalNode) { using (var cts = new CancellationTokenSource(_server.Engine.TcpConnectionTimeout)) { return(ReplicationUtils.GetTcpInfo(internalNode.Url, internalNode.Database, "Replication", _server.Server.Certificate.Certificate, cts.Token)); } } throw new InvalidOperationException( $"Unexpected replication node type, Expected to be '{typeof(ExternalReplication)}' or '{typeof(InternalReplication)}', but got '{node.GetType()}'"); } catch (Exception e) { // will try to fetch it again later if (_log.IsInfoEnabled) { _log.Info($"Failed to fetch tcp connection information for the destination '{node.FromString()}' , the connection will be retried later.", e); } _reconnectQueue.TryAdd(shutdownInfo); } return(null); }
public static async Task <TcpConnectionInfo> GetTcpInfoAsync(string url, string databaseName, string tag, X509Certificate2 certificate) { using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(url, certificate)) using (requestExecutor.ContextPool.AllocateOperationContext(out JsonOperationContext context)) { var getTcpInfoCommand = new GetTcpInfoCommand(tag, databaseName); await requestExecutor.ExecuteAsync(getTcpInfoCommand, context); var tcpConnectionInfo = getTcpInfoCommand.Result; if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && tcpConnectionInfo.Certificate == null) { throw new InvalidOperationException("Getting TCP info over HTTPS but the server didn't return the expected certificate to use over TCP, invalid response, aborting"); } return(tcpConnectionInfo); } }
private async Task <Stream> ConnectToServer(RequestExecuter requestExecuter) { var command = new GetTcpInfoCommand(); JsonOperationContext context; using (requestExecuter.ContextPool.AllocateOperationContext(out context)) { await requestExecuter.ExecuteAsync(command, context).ConfigureAwait(false); } var uri = new Uri(command.Result.Url); await _tcpClient.ConnectAsync(uri.Host, uri.Port).ConfigureAwait(false); _tcpClient.NoDelay = true; _tcpClient.SendBufferSize = 32 * 1024; _tcpClient.ReceiveBufferSize = 4096; var networkStream = _tcpClient.GetStream(); return(networkStream); }
private async Task <Stream> ConnectToServer() { var command = new GetTcpInfoCommand(); JsonOperationContext context; var requestExecuter = _store.GetRequestExecuter(_dbName ?? _store.DefaultDatabase); requestExecuter.ContextPool.AllocateOperationContext(out context); await requestExecuter.ExecuteAsync(command, context).ConfigureAwait(false); var uri = new Uri(command.Result.Url); await _tcpClient.ConnectAsync(uri.Host, uri.Port).ConfigureAwait(false); _tcpClient.NoDelay = true; _tcpClient.SendBufferSize = 32 * 1024; _tcpClient.ReceiveBufferSize = 4096; _networkStream = _tcpClient.GetStream(); var header = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new TcpConnectionHeaderMessage { Operation = TcpConnectionHeaderMessage.OperationTypes.Subscription, DatabaseName = _dbName ?? _store.DefaultDatabase })); var options = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_options)); await _networkStream.WriteAsync(header, 0, header.Length); await _networkStream.WriteAsync(options, 0, options.Length); await _networkStream.FlushAsync(); return(_networkStream); }