Esempio n. 1
0
            private async Task <ClusterMaintenanceConnection> ConnectToClientNodeAsync(TcpConnectionInfo tcpConnectionInfo, TimeSpan timeout)
            {
                TcpConnectionHeaderMessage.SupportedFeatures supportedFeatures;
                TcpClient tcpClient;
                string    url;

                (tcpClient, url) = await TcpUtils.ConnectSocketAsync(tcpConnectionInfo, timeout, _log);

                var connection = await TcpUtils.WrapStreamWithSslAsync(tcpClient, tcpConnectionInfo, _parent._server.Server.Certificate.Certificate, timeout);

                using (_contextPool.AllocateOperationContext(out JsonOperationContext ctx))
                    using (var writer = new BlittableJsonTextWriter(ctx, connection))
                    {
                        var parameters = new TcpNegotiateParameters
                        {
                            Database  = null,
                            Operation = TcpConnectionHeaderMessage.OperationTypes.Heartbeats,
                            Version   = TcpConnectionHeaderMessage.HeartbeatsTcpVersion,
                            ReadResponseAndGetVersionCallback = SupervisorReadResponseAndGetVersion,
                            DestinationUrl     = url,
                            DestinationNodeTag = ClusterTag
                        };
                        supportedFeatures = TcpNegotiation.NegotiateProtocolVersion(ctx, connection, parameters);

                        WriteClusterMaintenanceConnectionHeader(writer);
                    }

                return(new ClusterMaintenanceConnection
                {
                    TcpClient = tcpClient,
                    Stream = connection,
                    SupportedFeatures = supportedFeatures
                });
            }
        private void WriteHeaderToRemotePeer()
        {
            using (_database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext documentsContext))
                using (var writer = new BlittableJsonTextWriter(documentsContext, _stream))
                {
                    var parameters = new TcpNegotiateParameters
                    {
                        Database           = Destination.Database,
                        Operation          = TcpConnectionHeaderMessage.OperationTypes.Replication,
                        SourceNodeTag      = _parent._server.NodeTag,
                        DestinationNodeTag = GetNode(),
                        DestinationUrl     = Destination.Url,
                        ReadResponseAndGetVersionCallback = ReadHeaderResponseAndThrowIfUnAuthorized,
                        Version = TcpConnectionHeaderMessage.ReplicationTcpVersion
                    };

                    //This will either throw or return acceptable protocol version.
                    SupportedFeatures = TcpNegotiation.NegotiateProtocolVersion(documentsContext, _stream, parameters);

                    if (SupportedFeatures.ProtocolVersion <= 0)
                    {
                        throw new InvalidOperationException(
                                  $"{OutgoingReplicationThreadName}: TCP negotiation resulted with an invalid protocol version:{SupportedFeatures.ProtocolVersion}");
                    }

                    //start request/response for fetching last etag
                    var request = new DynamicJsonValue
                    {
                        ["Type"] = "GetLastEtag",
                        [nameof(ReplicationLatestEtagRequest.SourceDatabaseId)]   = _database.DbId.ToString(),
                        [nameof(ReplicationLatestEtagRequest.SourceDatabaseName)] = _database.Name,
                        [nameof(ReplicationLatestEtagRequest.SourceUrl)]          = _parent._server.GetNodeHttpServerUrl(),
                        [nameof(ReplicationLatestEtagRequest.SourceTag)]          = _parent._server.NodeTag,
                        [nameof(ReplicationLatestEtagRequest.SourceMachineName)]  = Environment.MachineName
                    };

                    documentsContext.Write(writer, request);
                    writer.Flush();
                }
        }