private void SendDropMessage(JsonOperationContext context, BlittableJsonTextWriter writer, TcpConnectionHeaderResponse headerResponse)
 {
     context.Write(writer, new DynamicJsonValue
     {
         [nameof(TcpConnectionHeaderMessage.DatabaseName)]     = Destination.Database,
         [nameof(TcpConnectionHeaderMessage.Operation)]        = TcpConnectionHeaderMessage.OperationTypes.Drop.ToString(),
         [nameof(TcpConnectionHeaderMessage.SourceNodeTag)]    = _parent._server.NodeTag,
         [nameof(TcpConnectionHeaderMessage.OperationVersion)] = TcpConnectionHeaderMessage.GetOperationTcpVersion(TcpConnectionHeaderMessage.OperationTypes.Drop),
         [nameof(TcpConnectionHeaderMessage.Info)]             =
             $"Couldn't agree on replication TCP version ours:{TcpConnectionHeaderMessage.ReplicationTcpVersion} theirs:{headerResponse.Version}"
     });
     writer.Flush();
 }
Beispiel #2
0
        private async Task <PingResult> PingOnce(string url)
        {
            var sp     = Stopwatch.StartNew();
            var result = new PingResult
            {
                Url = url
            };

            using (var cts = new CancellationTokenSource(ServerStore.Engine.TcpConnectionTimeout))
            {
                var info = await ReplicationUtils.GetTcpInfoAsync(url, null, "PingTest", ServerStore.Engine.ClusterCertificate, cts.Token);

                result.TcpInfoTime = sp.ElapsedMilliseconds;

                using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                {
                    var log = new List <string>();

                    using (await TcpUtils.ConnectSecuredTcpSocket(info, ServerStore.Engine.ClusterCertificate, Server.CipherSuitesPolicy,
                                                                  TcpConnectionHeaderMessage.OperationTypes.Ping, NegotiationCallback, context, ServerStore.Engine.TcpConnectionTimeout, log, cts.Token))
                    {
                    }

                    result.Log = log;

                    async Task <TcpConnectionHeaderMessage.SupportedFeatures> NegotiationCallback(string curUrl, TcpConnectionInfo tcpInfo, Stream stream,
                                                                                                  JsonOperationContext ctx, List <string> logs = null)
                    {
                        try
                        {
                            var msg = new DynamicJsonValue
                            {
                                [nameof(TcpConnectionHeaderMessage.DatabaseName)]     = null,
                                [nameof(TcpConnectionHeaderMessage.Operation)]        = TcpConnectionHeaderMessage.OperationTypes.Ping,
                                [nameof(TcpConnectionHeaderMessage.OperationVersion)] = -1,
                                [nameof(TcpConnectionHeaderMessage.ServerId)]         = tcpInfo.ServerId
                            };

                            await using (var writer = new AsyncBlittableJsonTextWriter(ctx, stream))
                                using (var msgJson = ctx.ReadObject(msg, "message"))
                                {
                                    result.SendTime = sp.ElapsedMilliseconds;
                                    logs?.Add($"message sent to url {curUrl} at {result.SendTime} ms.");
                                    ctx.Write(writer, msgJson);
                                }

                            using (var rawResponse = await ctx.ReadForMemoryAsync(stream, "cluster-ConnectToPeer-header-response"))
                            {
                                TcpConnectionHeaderResponse response = JsonDeserializationServer.TcpConnectionHeaderResponse(rawResponse);
                                result.ReceiveTime = sp.ElapsedMilliseconds;
                                logs?.Add($"response received from url {curUrl} at {result.ReceiveTime} ms.");

                                switch (response.Status)
                                {
                                case TcpConnectionStatus.Ok:
                                    result.Error = null;
                                    logs?.Add($"Successfully negotiated with {url}.");
                                    break;

                                case TcpConnectionStatus.AuthorizationFailed:
                                    result.Error = $"Connection to {url} failed because of authorization failure: {response.Message}";
                                    logs?.Add(result.Error);
                                    throw new AuthorizationException(result.Error);

                                case TcpConnectionStatus.TcpVersionMismatch:
                                    result.Error = $"Connection to {url} failed because of mismatching tcp version: {response.Message}";
                                    logs?.Add(result.Error);
                                    throw new AuthorizationException(result.Error);

                                case TcpConnectionStatus.InvalidNetworkTopology:
                                    result.Error = $"Connection to {url} failed because of {nameof(TcpConnectionStatus.InvalidNetworkTopology)} error: {response.Message}";
                                    logs?.Add(result.Error);
                                    throw new InvalidNetworkTopologyException(result.Error);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            result.Error = e.ToString();
                            logs?.Add($"Error occurred while attempting to negotiate with the server. {e.Message}");
                            throw;
                        }

                        return(null);
                    }
                }
            }
            return(result);
        }