public void ConsumeTest()
        {
            KafkaConnection kConnection = new KafkaConnection
            {
                Url   = "localhost",
                Port  = 9092,
                Topic = "witsmlCreateEvent"
            };
            Action <string>  onMessageConsumed = ConsumeMessage;
            KafkaTaskManager taskManager       = new KafkaTaskManager();
            string           group             = $"test_{new Random().Next()}";
            string           autoOffsetReset   = "earliest";
            int timeOut = 10 * 1000;

            // Create the token source for cancelation purpose
            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken       ct  = cts.Token;

            Assert.Throws <OperationCanceledException>(() =>
            {
                cts.CancelAfter(timeOut);
                KafkaTaskManager.Consume(kConnection, group, autoOffsetReset, ct, onMessageConsumed);
            });

            cts.Dispose();

            Assert.IsTrue(isMessageConsumed, "Message should be received from kafka");
        }
Пример #2
0
        [Test, Repeat(1)]///  [Test, Repeat(100)]
        public async Task ReadShouldLogDisconnectAndRecover()
        {
            var mockLog = _kernel.GetMock <IKafkaLog>();

            using (var server = new FakeTcpServer(_log, 8999))
                using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint, _maxRetry))
                    using (var conn = new KafkaConnection(socket, log: mockLog.Object))
                    {
                        var disconnected = false;
                        socket.OnServerDisconnected += () => disconnected = true;

                        await TaskTest.WaitFor(() => server.ConnectionEventcount > 0);

                        Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                        server.DropConnection();
                        await TaskTest.WaitFor(() => server.DisconnectionEventCount > 0);

                        Assert.That(server.DisconnectionEventCount, Is.EqualTo(1));

                        //Wait a while for the client to notice the disconnect and log
                        await TaskTest.WaitFor(() => disconnected);

                        //should log an exception and keep going
                        mockLog.Verify(x => x.ErrorFormat(It.IsAny <string>(), It.IsAny <Exception>()));

                        await TaskTest.WaitFor(() => server.ConnectionEventcount > 1);

                        Assert.That(server.ConnectionEventcount, Is.EqualTo(2));
                    }
        }
Пример #3
0
        /// <summary>
        /// This task allows caller to produce a message
        /// </summary>
        /// <returns>Task<bool> true if task succeded</returns>
        public static async Task <bool> Produce(KafkaConnection kConnection, int timeout, string message)
        {
            var config = new ProducerConfig {
                BootstrapServers = $"{kConnection.Url}:{kConnection.Port}"
            };

            // A Producer for sending messages with null keys and UTF-8 encoded values.
            using (var p = new Producer <Null, string>(config))
            {
                try
                {
                    var dr = p.ProduceAsync(kConnection.Topic, new Message <Null, string> {
                        Value = message
                    });
                    if (await Task.WhenAny(dr, Task.Delay(timeout)) == dr)
                    {
                        var taskResult = await dr;
                        Console.WriteLine($"Delivered '{taskResult.Value}' to '{taskResult.TopicPartitionOffset}'");
                        return(true);
                        // task completed within timeout
                    }
                    else
                    {
                        // timeout logic
                        Console.WriteLine($"Request timedout");
                        return(false);
                    }
                }
                catch (KafkaException e)
                {
                    Console.WriteLine($"Delivery failed: {e.Error.Reason}");
                    return(false);
                }
            }
        }
        public void Setup()
        {
            var options = new KafkaOptions(IntegrationConfig.IntegrationUri);

            _kafkaConnection = new KafkaConnection(new KafkaTcpSocket(new DefaultTraceLog(), options.KafkaServerUri.First()), options.ResponseTimeoutMs, options.Log);
            _router          = new BrokerRouter(options);
        }
        public void Setup()
        {
            var options  = new KafkaOptions(IntegrationConfig.IntegrationUri);
            var endpoint = new DefaultKafkaConnectionFactory().Resolve(options.KafkaServerUri.First(), options.Log);

            _conn = new KafkaConnection(new KafkaTcpSocket(new DefaultTraceLog(), endpoint), options.ResponseTimeoutMs, options.Log);
        }
Пример #6
0
        /// <summary>
        /// Combine multiple fetch requests in one call.
        /// </summary>
        /// <param name="request">
        /// The list of fetch requests.
        /// </param>
        /// <returns>
        /// A list of sets of fetched messages.
        /// </returns>
        /// <remarks>
        /// Offset is passed in on every request, allowing the user to maintain this metadata
        /// however they choose.
        /// </remarks>
        public IList <BufferedMessageSet> MultiFetch(MultiFetchRequest request)
        {
            var   result     = new List <BufferedMessageSet>();
            short tryCounter = 1;

            while (tryCounter <= this.config.NumberOfTries)
            {
                try
                {
                    using (var conn = new KafkaConnection(
                               this.host,
                               this.port,
                               this.config.BufferSize,
                               this.config.SocketTimeout))
                    {
                        conn.Write(request);
                        int size = conn.Reader.ReadInt32();
                        return(BufferedMessageSet.ParseMultiFrom(conn.Reader, size, request.ConsumerRequests.Count, request.ConsumerRequests.Select(x => x.Offset).ToList()));
                    }
                }
                catch (Exception ex)
                {
                    // if maximum number of tries reached
                    if (tryCounter == this.config.NumberOfTries)
                    {
                        throw;
                    }

                    tryCounter++;
                    Logger.InfoFormat(CultureInfo.CurrentCulture, "MultiFetch reconnect due to {0}", ex);
                }
            }

            return(result);
        }
Пример #7
0
        public async void SendAsyncShouldNotAllowResponseToTimeoutWhileAwaitingKafkaToEstableConnection()
        {
            using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
                using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(1000000), log: _log))
                {
                    Console.WriteLine("SendAsync blocked by reconnection attempts...");
                    var taskResult = conn.SendAsync(new MetadataRequest());

                    taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(1));

                    Console.WriteLine("Task result should be WaitingForActivation...");
                    Assert.That(taskResult.IsFaulted, Is.False);
                    Assert.That(taskResult.Status, Is.EqualTo(TaskStatus.WaitingForActivation));

                    Console.WriteLine("Starting server to establish connection...");
                    using (var server = new FakeTcpServer(8999))
                    {
                        server.OnClientConnected += () => Console.WriteLine("Client connected...");
                        server.OnBytesReceived   += (b) =>
                        {
                            server.SendDataAsync(MessageHelper.CreateMetadataResponse(1, "Test"));
                        };

                        await taskResult;

                        Assert.That(taskResult.IsFaulted, Is.False);
                        Assert.That(taskResult.IsCanceled, Is.False);
                        Assert.That(taskResult.Status, Is.EqualTo(TaskStatus.RanToCompletion));
                    }
                }
        }
Пример #8
0
        /// <summary>
        /// Fetch a set of messages from a topic.
        /// </summary>
        /// <param name="request">
        /// Specifies the topic name, topic partition, starting byte offset, maximum bytes to be fetched.
        /// </param>
        /// <returns>
        /// A set of fetched messages.
        /// </returns>
        /// <remarks>
        /// Offset is passed in on every request, allowing the user to maintain this metadata
        /// however they choose.
        /// </remarks>
        public BufferedMessageSet Fetch(FetchRequest request)
        {
            short tryCounter = 1;

            while (tryCounter <= this.config.NumberOfTries)
            {
                try
                {
                    using (var conn = new KafkaConnection(
                               this.host,
                               this.port,
                               this.config.BufferSize,
                               this.config.SocketTimeout))
                    {
                        conn.Write(request);
                        int size = conn.Reader.ReadInt32();
                        return(BufferedMessageSet.ParseFrom(conn.Reader, size, request.Offset));
                    }
                }
                catch (Exception ex)
                {
                    //// if maximum number of tries reached
                    if (tryCounter == this.config.NumberOfTries)
                    {
                        throw;
                    }

                    tryCounter++;
                    Logger.InfoFormat(CultureInfo.CurrentCulture, "Fetch reconnect due to {0}", ex);
                }
            }

            return(null);
        }
        public async Task SendAsyncShouldTimeoutMultipleMessagesAtATime()
        {
            using (var server = new FakeTcpServer(_log, 8999))
                using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint, _maxRetry))
                    using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log))
                    {
                        server.HasClientConnected.Wait(TimeSpan.FromSeconds(3));
                        Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                        var tasks = new[]
                        {
                            conn.SendAsync(new MetadataRequest()),
                            conn.SendAsync(new MetadataRequest()),
                            conn.SendAsync(new MetadataRequest())
                        };

                        Task.WhenAll(tasks);

                        await TaskTest.WaitFor(() => tasks.All(t => t.IsFaulted));

                        foreach (var task in tasks)
                        {
                            Assert.That(task.IsFaulted, Is.True, "Task should have faulted.");
                            Assert.That(task.Exception.InnerException, Is.TypeOf <ResponseTimeoutException>(),
                                        "Task fault should be of type ResponseTimeoutException.");
                        }
                    }
        }
        public async Task KafkaConnectionShouldLogDisconnectAndRecover()
        {
            var mockLog = new Mock <IKafkaLog>();
            var log     = new DefaultTraceLog(LogLevel.Error);

            using (var server = new FakeTcpServer(log, 8999))
                using (var socket = new KafkaTcpSocket(log, _kafkaEndpoint, _maxRetry))
                    using (var conn = new KafkaConnection(socket, log: mockLog.Object))
                    {
                        var disconnected = 0;
                        socket.OnServerDisconnected += () => Interlocked.Increment(ref disconnected);

                        for (int connectionAttempt = 1; connectionAttempt < 4; connectionAttempt++)
                        {
                            await TaskTest.WaitFor(() => server.ConnectionEventcount == connectionAttempt);

                            Assert.That(server.ConnectionEventcount, Is.EqualTo(connectionAttempt));
                            server.SendDataAsync(CreateCorrelationMessage(1)).Wait(TimeSpan.FromSeconds(5));
                            await TaskTest.WaitFor(() => !conn.IsOnErrorState());

                            Assert.IsFalse(conn.IsOnErrorState());
                            mockLog.Verify(x => x.InfoFormat("Polling read thread has recovered: {0}", It.IsAny <object[]>()), Times.Exactly(connectionAttempt - 1));

                            server.DropConnection();
                            await TaskTest.WaitFor(() => conn.IsOnErrorState());

                            Assert.AreEqual(disconnected, connectionAttempt);
                            Assert.IsTrue(conn.IsOnErrorState());

                            mockLog.Verify(x => x.ErrorFormat("Exception occured in polling read thread {0}: {1}", It.IsAny <object[]>()), Times.Exactly(connectionAttempt));
                        }
                    }
        }
        public void Setup()
        {
            var options = new KafkaOptions(IntegrationConfig.IntegrationUri);
            var endpoint = new DefaultKafkaConnectionFactory().Resolve(options.KafkaServerUri.First(), options.Log);

            _conn = new KafkaConnection(new KafkaTcpSocket(new DefaultTraceLog(), endpoint), options.ResponseTimeoutMs, options.Log);
        }
        public async Task ReadShouldIgnoreMessageWithUnknownCorrelationId()
        {
            const int correlationId = 99;

            var mockLog = _kernel.GetMock <IKafkaLog>();

            using (var server = new FakeTcpServer(_log, 8999))
                using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint, _maxRetry))
                    using (var conn = new KafkaConnection(socket, log: mockLog.Object))
                    {
                        var receivedData = false;
                        socket.OnBytesReceived += i => receivedData = true;

                        //send correlation message
                        server.SendDataAsync(CreateCorrelationMessage(correlationId)).Wait(TimeSpan.FromSeconds(5));

                        //wait for connection
                        await TaskTest.WaitFor(() => server.ConnectionEventcount > 0);

                        Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                        await TaskTest.WaitFor(() => receivedData);

                        //should log a warning and keep going
                        mockLog.Verify(x => x.WarnFormat(It.IsAny <string>(), It.Is <int>(o => o == correlationId)));
                    }
        }
Пример #13
0
        private static async Task JoinGroup(KafkaConnection kafka)
        {
            Console.WriteLine("----- JoinGroup");

            var response = await kafka.JoinGroup(new JoinGroupRequest
            {
                GroupId          = "test_" + Guid.NewGuid().ToString(),
                SessionTimeout   = 10000,
                RebalanceTimeout = 300000,
                ProtocolType     = "consumer",
                Protocols        = new JoinGroupRequest.Protocol[]
                {
                    new JoinGroupRequest.Protocol {
                        Name = "range",
                    }
                }
            });

            Console.WriteLine($"throttle:     {response.ThrottleTime}");
            Console.WriteLine($"errorCode:    {response.ErrorCode}");
            Console.WriteLine($"genId:        {response.GenerationId}");
            Console.WriteLine($"ProtocolName: {response.ProtocolName}");
            Console.WriteLine($"Leader:       {response.Leader}");
            Console.WriteLine($"memberId:     {response.MemberId}");
            foreach (var m in response.Members)
            {
                Console.WriteLine($"  memberId:{m.MemberId} group:{m.GroupInstanceId} meta:{(m.Metadata?.Length.ToString() ?? "NONE")}");
            }
        }
Пример #14
0
        private static async Task Produce(KafkaConnection kafka)
        {
            Console.WriteLine("----- Produce");

            var msg = new Message <string, string>
            {
                Topic = TopicName,
                Key   = "fred",
                Value = "flintstone " + Guid.NewGuid().ToString()
            };

            Console.WriteLine(msg.Value);

            var response = await kafka.Produce(msg, IntrinsicSerializers.String, IntrinsicSerializers.String);

            Console.WriteLine($"throttle: {response.ThrottleTime}");
            foreach (var r in response.Topics)
            {
                Console.WriteLine($"topic: {r.Topic}");
                foreach (var p in r.Partitions)
                {
                    Console.WriteLine($"    {p.Partition} (error: {p.ErrorCode.ToString()}) - {p.BaseOffset} {p.LogStartOffset} {Timestamp.UnixTimestampMsToDateTime(p.LogAppendTime)}");
                }
            }
        }
Пример #15
0
        public void SendAsyncShouldTimeoutMultipleMessagesAtATime()
        {
            using (var server = new FakeTcpServer(8999))
                using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
                    using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log))
                    {
                        TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
                        Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                        var tasks = new[]
                        {
                            conn.SendAsync(new MetadataRequest()),
                            conn.SendAsync(new MetadataRequest()),
                            conn.SendAsync(new MetadataRequest())
                        };

                        Task.WhenAll(tasks);

                        TaskTest.WaitFor(() => tasks.Any(t => t.IsFaulted));
                        foreach (var task in tasks)
                        {
                            Assert.That(task.IsFaulted, Is.True);
                            Assert.That(task.Exception.InnerException, Is.TypeOf <ResponseTimeoutException>());
                        }
                    }
        }
Пример #16
0
        public void ReadShouldLogDisconnectAndRecover()
        {
            var mockLog = _kernel.GetMock <IKafkaLog>();

            using (var server = new FakeTcpServer(8999))
                using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint))
                    using (var conn = new KafkaConnection(socket, log: mockLog.Object))
                    {
                        TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
                        Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                        server.DropConnection();
                        TaskTest.WaitFor(() => server.DisconnectionEventCount > 0);
                        Assert.That(server.DisconnectionEventCount, Is.EqualTo(1));

                        //Wait a while for the client to notice the disconnect and log
                        Thread.Sleep(15);

                        //should log an exception and keep going
                        mockLog.Verify(x => x.ErrorFormat(It.IsAny <string>(), It.IsAny <Exception>()));

                        TaskTest.WaitFor(() => server.ConnectionEventcount > 1);
                        Assert.That(server.ConnectionEventcount, Is.EqualTo(2));
                    }
        }
Пример #17
0
        private KafkaConnection Connect()
        {
            TimeSpan connectBackoff = new TimeSpan(1 * TimeSpan.TicksPerMillisecond);
            DateTime beginTime      = DateTime.Now;

            while (connection == null && !disposed)
            {
                try
                {
                    connection = new KafkaConnection(Config.Host, Config.Port, Config.BufferSize, Config.SocketTimeout);
                    Logger.Info("Connected to " + Config.Host + ":" + Config.Port + " for producing");
                }
                catch (Exception e)
                {
                    Disconnect();
                    DateTime endTime = DateTime.Now;
                    // Throw because the connection timeout has expired
                    if (((endTime - beginTime) + connectBackoff).TotalMilliseconds > Config.ConnectTimeout)
                    {
                        Logger.Error("Producer connection to " + Config.Host + ":" + Config.Port + " timing out after " +
                                     Config.ConnectTimeout + " ms", e);
                        throw;
                    }
                    int backoff = Convert.ToInt32(connectBackoff.TotalMilliseconds);
                    Logger.Error("Connection attempt to " + Config.Host + ":" + Config.Port + " failed, next attempt in " + backoff + " ms", e);
                    System.Threading.Thread.Sleep(backoff);
                    backoff        = Math.Min(10 * backoff, MAX_CONNECT_BACKOFF_MS);
                    connectBackoff = new TimeSpan(backoff * TimeSpan.TicksPerMillisecond);
                }
            }
            return(connection);
        }
Пример #18
0
        private static async Task Fetch(KafkaConnection kafka, string topicName = TopicName, int partitionId = 0, int offset = 0)
        {
            Console.WriteLine($"----- Fetch: topic:{topicName} p:{partitionId} o:{offset}");

            var req = new FetchRequest
            {
                ReplicaId      = -1,
                MaxWaitTime    = 100,
                MinBytes       = 1,
                MaxBytes       = 64 * 1024,
                IsolationLevel = 0,
                SessionId      = 0,
                SessionEpoc    = -1,
                Topics         = new FetchRequest.Topic[]
                {
                    new FetchRequest.Topic
                    {
                        TopicName  = topicName,
                        Partitions = new FetchRequest.Topic.Partition[]
                        {
                            new FetchRequest.Topic.Partition
                            {
                                PartitionId       = partitionId,
                                CurrentLeaderEpoc = -1,
                                FetchOffset       = offset,
                                LogStartOffset    = -1,
                                PartitionMaxBytes = 32 * 1024
                            }
                        }
                    }
                }
            };

            var response = await kafka.Fetch(req);

            Console.WriteLine($"throttle:     {response.ThrottleTime}");
            Console.WriteLine($"errorCode:    {response.ErrorCode}");

            foreach (var r in response.Responses)
            {
                Console.WriteLine($"topic: {r.TopicName}");
                foreach (var pr in r.PartitionResponses)
                {
                    Console.WriteLine($"  partition: {pr.PartitionId} error: {pr.ErrorCode.ToString()}");
                    foreach (var batch in pr.RecordBatches)
                    {
                        Console.WriteLine("    batch offset: " + batch.BaseOffset);
                        foreach (var rec in batch.Records)
                        {
                            Console.WriteLine("      offset: " + rec.Offset);
                            Console.WriteLine("      key   : " + Encoding.UTF8.GetString(rec.Key));
                            Console.WriteLine("      val   : " + Encoding.UTF8.GetString(rec.Value));
                        }
                    }
                }
            }
        }
Пример #19
0
 public void ShouldStartReadPollingOnConstruction()
 {
     using (var socket = new KafkaTcpSocket(_log, new Uri("http://localhost:8999")))
         using (var conn = new KafkaConnection(socket, log: _log))
         {
             TaskTest.WaitFor(() => conn.ReadPolling);
             Assert.That(conn.ReadPolling, Is.True);
         }
 }
Пример #20
0
 public void ShouldStartReadPollingOnConstruction()
 {
     using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
         using (var conn = new KafkaConnection(socket, log: _log))
         {
             TaskTest.WaitFor(() => conn.ReadPolling);
             Assert.That(conn.ReadPolling, Is.True);
         }
 }
Пример #21
0
 public void ShouldStartReadPollingOnConstruction()
 {
     using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
     using (var conn = new KafkaConnection(socket, log: _log))
     {
         TaskTest.WaitFor(() => conn.ReadPolling);
         Assert.That(conn.ReadPolling, Is.True);
     }
 }
Пример #22
0
 public void ShouldReportServerUriOnConstruction()
 {
     var expectedUrl = _kafkaEndpoint;
     using (var socket = new KafkaTcpSocket(_log, expectedUrl))
     using (var conn = new KafkaConnection(socket, log: _log))
     {
         Assert.That(conn.Endpoint, Is.EqualTo(expectedUrl));
     }
 }
Пример #23
0
        public void ShouldReportServerUriOnConstruction()
        {
            var expectedUrl = new Uri("http://localhost:8999");

            using (var socket = new KafkaTcpSocket(_log, expectedUrl))
                using (var conn = new KafkaConnection(socket, log: _log))
                {
                    Assert.That(conn.KafkaUri, Is.EqualTo(expectedUrl));
                }
        }
Пример #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SyncProducer"/> class.
 /// </summary>
 /// <param name="config">
 /// The producer config.
 /// </param>
 public SyncProducer(SyncProducerConfiguration config)
 {
     Guard.NotNull(config, "config");
     this.Config     = config;
     this.connection = new KafkaConnection(
         this.Config.Host,
         this.Config.Port,
         config.BufferSize,
         config.SocketTimeout);
 }
Пример #25
0
 public void ShouldDisposeWithoutExceptionThrown()
 {
     using (var server = new FakeTcpServer(8999))
     using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
     {
         var conn = new KafkaConnection(socket, log: _log);
         TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
         using (conn) { }
     }
 }
Пример #26
0
 public void ShouldDisposeWithoutExceptionEvenWhileCallingSendAsync()
 {
     using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
         using (var conn = new KafkaConnection(socket, log: _log))
         {
             var task = conn.SendAsync(new MetadataRequest());
             task.Wait(TimeSpan.FromMilliseconds(1000));
             Assert.That(task.IsCompleted, Is.False, "The send task should still be pending.");
         }
 }
Пример #27
0
        public void ShouldReportServerUriOnConstruction()
        {
            var expectedUrl = _kafkaEndpoint;

            using (var socket = new KafkaTcpSocket(_log, expectedUrl))
                using (var conn = new KafkaConnection(socket, log: _log))
                {
                    Assert.That(conn.Endpoint, Is.EqualTo(expectedUrl));
                }
        }
Пример #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SyncProducer"/> class.
 /// </summary>
 /// <param name="config">
 /// The producer config.
 /// </param>
 public SyncProducer(SyncProducerConfiguration config)
 {
     Guard.NotNull(config, "config");
     this.Config = config;
     this.connection = new KafkaConnection(
         this.Config.Host,
         this.Config.Port,
         config.BufferSize,
         config.SocketTimeout);
 }
Пример #29
0
 public void ShouldDisposeWithoutExceptionEvenWhileCallingSendAsync()
 {
     using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
     using (var conn = new KafkaConnection(socket, log: _log))
     {
         var task = conn.SendAsync(new MetadataRequest());
         task.Wait(TimeSpan.FromMilliseconds(1000));
         Assert.That(task.IsCompleted, Is.False, "The send task should still be pending.");
     }
 }
Пример #30
0
 public void ShouldDisposeWithoutExceptionThrown()
 {
     using (var server = new FakeTcpServer(8999))
         using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
         {
             var conn = new KafkaConnection(socket, log: _log);
             TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
             using (conn) { }
         }
 }
Пример #31
0
        private static async Task GetVersion(KafkaConnection kafka)
        {
            Console.WriteLine("----- ApiVersion");
            var apiversions = await kafka.ApiVersion();

            Console.WriteLine("error: " + apiversions.ErrorCode);
            foreach (var v in apiversions.ApiVersions)
            {
                Console.WriteLine($"{ApiKey.GetName(v.ApiKey).PadRight(20)} {v.MinVersion}->{v.MaxVersion}");
            }
        }
Пример #32
0
        /// <summary>
        /// Gets a list of valid offsets (up to maxSize) before the given time.
        /// </summary>
        /// <param name="request">
        /// The offset request.
        /// </param>
        /// <returns>
        /// The list of offsets, in descending order.
        /// </returns>
        public IList <long> GetOffsetsBefore(OffsetRequest request)
        {
            var   result     = new List <long>();
            short tryCounter = 1;

            while (tryCounter <= this.config.NumberOfTries)
            {
                try
                {
                    using (var conn = new KafkaConnection(
                               this.host,
                               this.port,
                               this.config.BufferSize,
                               this.config.SocketTimeout))
                    {
                        conn.Write(request);
                        int size = conn.Reader.ReadInt32();
                        if (size == 0)
                        {
                            return(result);
                        }

                        short errorCode = conn.Reader.ReadInt16();
                        if (errorCode != ErrorMapping.NoError)
                        {
                            throw new KafkaException(errorCode);
                        }

                        int count = conn.Reader.ReadInt32();
                        for (int i = 0; i < count; i++)
                        {
                            result.Add(conn.Reader.ReadInt64());
                        }

                        return(result);
                    }
                }
                catch (Exception ex)
                {
                    //// if maximum number of tries reached
                    if (tryCounter == this.config.NumberOfTries)
                    {
                        throw;
                    }

                    tryCounter++;
                    Logger.InfoFormat(CultureInfo.CurrentCulture, "GetOffsetsBefore reconnect due to {0}", ex);
                }
            }

            return(result);
        }
Пример #33
0
        public void SendAsyncShouldTimeoutByThrowingResponseTimeoutExceptionWhenTcpConnectionIsNotAvailable()
        {
            using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
                using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log))
                {
                    var taskResult = conn.SendAsync(new MetadataRequest());

                    taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(1));

                    Assert.That(taskResult.IsFaulted, Is.True);
                    Assert.That(taskResult.Exception.InnerException, Is.TypeOf <ResponseTimeoutException>());
                }
        }
Пример #34
0
        private static async Task FindCoordinator(KafkaConnection kafka)
        {
            Console.WriteLine("----- FindCoordinator");

            var response = await kafka.FindCoordinator(Guid.NewGuid().ToString());

            Console.WriteLine($"throttle:     {response.ThrottleTime}");
            Console.WriteLine($"errorCode:    {response.ErrorCode}");
            Console.WriteLine($"errorMessage: {response.ErrorMessage}");
            Console.WriteLine($"nodeId:       {response.NodeId}");
            Console.WriteLine($"host:         {response.Host}");
            Console.WriteLine($"port:         {response.Port}");
        }
Пример #35
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AsyncProducer"/> class.
        /// </summary>
        /// <param name="config">
        /// The producer config.
        /// </param>
        /// <param name="callbackHandler">
        /// The callback invoked when a request is finished being sent.
        /// </param>
        public AsyncProducer(
            AsyncProducerConfiguration config,
            ICallbackHandler callbackHandler)
        {
            Guard.NotNull(config, "config");

            this.Config          = config;
            this.callbackHandler = callbackHandler;
            this.connection      = new KafkaConnection(
                this.Config.Host,
                this.Config.Port,
                this.Config.BufferSize,
                this.Config.SocketTimeout);
        }
Пример #36
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AsyncProducer"/> class.
        /// </summary>
        /// <param name="config">
        /// The producer config.
        /// </param>
        /// <param name="callbackHandler">
        /// The callback invoked when a request is finished being sent.
        /// </param>
        public AsyncProducer(
            AsyncProducerConfiguration config,
            ICallbackHandler callbackHandler)
        {
            Guard.NotNull(config, "config");

            this.Config = config;
            this.callbackHandler = callbackHandler;
            this.connection = new KafkaConnection(
                this.Config.Host,
                this.Config.Port,
                this.Config.BufferSize,
                this.Config.SocketTimeout);
        }
Пример #37
0
        /// <summary>
        /// Gets a list of valid offsets (up to maxSize) before the given time.
        /// </summary>
        /// <param name="request">
        /// The offset request.
        /// </param>
        /// <returns>
        /// The list of offsets, in descending order.
        /// </returns>
        public IList <long> GetOffsetsBefore(OffsetRequest request)
        {
            KafkaConnection conn       = null;
            int             size       = 0;
            var             result     = new List <long>();
            short           tryCounter = 1;

            while (tryCounter <= this.config.NumberOfTries)
            {
                try
                {
                    conn = KafkaClusterConnectionPool.GetConnection(this.host, this.port);
                    conn.Write(request);
                    size = conn.Reader.ReadInt32();
                    if (size > 0)
                    {
                        short errorCode = conn.Reader.ReadInt16();
                        if (errorCode != ErrorMapping.NoError)
                        {
                            throw new KafkaException(errorCode);
                        }

                        int count = conn.Reader.ReadInt32();
                        for (int i = 0; i < count; i++)
                        {
                            result.Add(conn.Reader.ReadInt64());
                        }
                    }
                    break;
                }
                catch (Exception ex)
                {
                    //// if maximum number of tries reached
                    if (tryCounter == this.config.NumberOfTries)
                    {
                        throw;
                    }

                    tryCounter++;
                    Logger.InfoFormat(CultureInfo.CurrentCulture, "GetOffsetsBefore reconnect due to {0}", ex);
                }
                finally
                {
                    KafkaClusterConnectionPool.ReleaseConnection(conn);
                }
            }

            return(result);
        }
Пример #38
0
        /// <summary>
        /// Sends the data to a multiple topics on Kafka server synchronously
        /// </summary>
        /// <param name="requests">
        /// The requests.
        /// </param>
        public void MultiSend(IEnumerable<ProducerRequest> requests)
        {
            Guard.Assert<ArgumentNullException>(() => requests != null);
            Guard.Assert<ArgumentNullException>(
                () => requests.All(
                    x => x != null && x.MessageSet != null && x.MessageSet.Messages != null));
            Guard.Assert<ArgumentNullException>(
                () => requests.All(
                    x => x.MessageSet.Messages.All(
                        y => y != null && y.PayloadSize <= this.Config.MaxMessageSize)));

            var multiRequest = new MultiProducerRequest(requests);
            using (var conn = new KafkaConnection(this.config.Host, this.config.Port))
            {
                conn.Write(multiRequest);
            }
        }
        /// <summary>
        /// Check that brokers alive by sending topic metadata request to them
        /// </summary>
        /// <param name="brokers">Collection of brokers to check. If null - brokers list will be retrieved from ZooKeeper state</param>
        /// <returns>
        ///     Dictionary where Key is Broker Id and Value indicates whether Broker responds to requests. 
        ///     Value is true when Broker TopicMetadataRequest was successfully sent to broker and any response was recieved back.
        ///     Value is false when connection to Broker failed or 
        ///  </returns>
        /// <remarks>
        /// If brokers not specified this method will only ping brokers that exist in ZooKeeper state
        /// </remarks>
        public IDictionary<int, bool> GetKafkaBrokersAliveState(ICollection<Broker> brokers = null)
        {
            // retrive latest brokers info
            if (brokers == null)
            {
                this.RefreshKafkaBrokersInfo();
            }

            brokers = brokers ?? this.kafkaCluster.Brokers.Values;
            var brokersConnectionString = string.Join(", ", this.kafkaCluster.Brokers.Values.Select(x => string.Join(":", x.Id, x.Host, x.Port)));
            Logger.InfoFormat("Collecting brokers alive state for brokers {0}", brokersConnectionString);

            var brokerAliveStateMap = new SortedDictionary<int, bool>();
            foreach (var broker in brokers)
            {
                try
                {
                    Logger.DebugFormat("Sending request to broker #{0} {1}:{2}", broker.Id, broker.Host, broker.Port);
                    using (var kafkaConnection = new KafkaConnection(broker.Host, broker.Port, this.config.BufferSize, this.config.SendTimeout, this.config.ReceiveTimeout, int.MaxValue))
                    {
                        // send topic offset request for random non-existing topic
                        var requestInfos = new Dictionary<string, List<PartitionOffsetRequestInfo>>();
                        requestInfos[Guid.NewGuid().ToString("N")] = new List<PartitionOffsetRequestInfo>() { new PartitionOffsetRequestInfo(0, OffsetRequest.EarliestTime, 1) };
                        kafkaConnection.Send(new OffsetRequest(requestInfos));
                    }

                    brokerAliveStateMap[broker.Id] = true;
                }
                catch (Exception exc)
                {
                    Logger.WarnFormat("Failed to send request to broker #{0} {1}:{2}. Error:", broker.Id, broker.Host, broker.Port, exc.FormatException());
                    brokerAliveStateMap[broker.Id] = false;
                }
            }

            Logger.InfoFormat("Completed collecting brokers alive state for brokers {0}", brokersConnectionString);

            return brokerAliveStateMap;
        }
Пример #40
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Consumer"/> class.
        /// </summary>
        /// <param name="config">
        /// The consumer configuration.
        /// </param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        public Consumer(ConsumerConfiguration config, string host, int port)
        {
            Guard.NotNull(config, "config");

            this.config = config;
            this.host = host;
            this.port = port;
            this.connection = new KafkaConnection(
                                  this.host,
                                  this.port,
                                  this.config.BufferSize,
                                  this.config.SendTimeout,
                                  this.config.ReceiveTimeout,
                                  this.config.ReconnectInterval);
        }
Пример #41
0
        public async void SendAsyncShouldNotAllowResponseToTimeoutWhileAwaitingKafkaToEstableConnection()
        {
            using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
            using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(1000000), log: _log))
            {
                Console.WriteLine("SendAsync blocked by reconnection attempts...");
                var taskResult = conn.SendAsync(new MetadataRequest());

                taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromSeconds(1));

                Console.WriteLine("Task result should be WaitingForActivation...");
                Assert.That(taskResult.IsFaulted, Is.False);
                Assert.That(taskResult.Status, Is.EqualTo(TaskStatus.WaitingForActivation));

                Console.WriteLine("Starting server to establish connection...");
                using (var server = new FakeTcpServer(8999))
                {
                    server.OnClientConnected += () => Console.WriteLine("Client connected...");
                    server.OnBytesReceived += (b) =>
                    {
                        server.SendDataAsync(MessageHelper.CreateMetadataResponse(1, "Test"));
                    };

                    await taskResult;

                    Assert.That(taskResult.IsFaulted, Is.False);
                    Assert.That(taskResult.IsCanceled, Is.False);
                    Assert.That(taskResult.Status, Is.EqualTo(TaskStatus.RanToCompletion));
                }
            }
        }
Пример #42
0
        public void SendAsyncShouldTimeoutMultipleMessagesAtATime()
        {
            using (var server = new FakeTcpServer(8999))
            using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
            using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(100), log: _log))
            {
                server.HasClientConnected.Wait(TimeSpan.FromSeconds(3));
                Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                var tasks = new[]
                    {
                        conn.SendAsync(new MetadataRequest()),
                        conn.SendAsync(new MetadataRequest()),
                        conn.SendAsync(new MetadataRequest())
                    };

                Task.WhenAll(tasks);

                TaskTest.WaitFor(() => tasks.Any(t => t.IsFaulted));
                foreach (var task in tasks)
                {
                    Assert.That(task.IsFaulted, Is.True, "Task should have faulted.");
                    Assert.That(task.Exception.InnerException, Is.TypeOf<ResponseTimeoutException>(), "Task fault should be of type ResponseTimeoutException.");
                }
            }
        }
Пример #43
0
        public void ReadShouldIgnoreMessageWithUnknownCorrelationId()
        {
            const int correlationId = 99;

            var mockLog = _kernel.GetMock<IKafkaLog>();

            using (var server = new FakeTcpServer(8999))
            using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint))
            using (var conn = new KafkaConnection(socket, log: mockLog.Object))
            {
                var receivedData = false;
                socket.OnBytesReceived += i => receivedData = true;

                //send correlation message
                server.SendDataAsync(CreateCorrelationMessage(correlationId)).Wait(TimeSpan.FromSeconds(5));

                //wait for connection
                TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
                Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                TaskTest.WaitFor(() => receivedData);

                //should log a warning and keep going
                mockLog.Verify(x => x.WarnFormat(It.IsAny<string>(), It.Is<int>(o => o == correlationId)));
            }
        }
Пример #44
0
        public void SendAsyncShouldTimeoutWhenSendAsyncTakesTooLong()
        {
            using (var server = new FakeTcpServer(8999))
            using (var socket = new KafkaTcpSocket(_log, _kafkaEndpoint))
            using (var conn = new KafkaConnection(socket, TimeSpan.FromMilliseconds(1), log: _log))
            {
                TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
                Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                var taskResult = conn.SendAsync(new MetadataRequest());

                taskResult.ContinueWith(t => taskResult = t).Wait(TimeSpan.FromMilliseconds(100));

                Assert.That(taskResult.IsFaulted, Is.True, "Task should have reported an exception.");
                Assert.That(taskResult.Exception.InnerException, Is.TypeOf<ResponseTimeoutException>());
            }
        }
Пример #45
0
        public async Task KafkaConnectionShouldLogDisconnectAndRecover()
        {
            var mockLog =new Mock<IKafkaLog>();
            var log= new DefaultTraceLog(LogLevel.Error);
            using (var server = new FakeTcpServer(log, 8999))
            using (var socket = new KafkaTcpSocket(log, _kafkaEndpoint, _maxRetry))
            using (var conn = new KafkaConnection(socket, log: mockLog.Object))
            {
                var disconnected = 0;
                socket.OnServerDisconnected += () => Interlocked.Increment(ref disconnected);

                for (int connectionAttempt = 1; connectionAttempt < 4; connectionAttempt++)
                {

                    await TaskTest.WaitFor(() => server.ConnectionEventcount == connectionAttempt);
                    Assert.That(server.ConnectionEventcount, Is.EqualTo(connectionAttempt));
                    server.SendDataAsync(CreateCorrelationMessage(1)).Wait(TimeSpan.FromSeconds(5));
                    await TaskTest.WaitFor(() => !conn.IsOnErrorState());

                    Assert.IsFalse(conn.IsOnErrorState());
                    mockLog.Verify(x => x.InfoFormat("Polling read thread has recovered: {0}", It.IsAny<object[]>()), Times.Exactly(connectionAttempt-1));

                    server.DropConnection();
                    await TaskTest.WaitFor(() => conn.IsOnErrorState());
                    Assert.AreEqual(disconnected,connectionAttempt);
                    Assert.IsTrue(conn.IsOnErrorState());

                    mockLog.Verify(x => x.ErrorFormat("Exception occured in polling read thread {0}: {1}", It.IsAny<object[]>()), Times.Exactly(connectionAttempt ));
                }

            }
        }
Пример #46
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (connection != null)
                {
                    lock (this)
                    {
                        if (connection != null)
                        {

                            this.connection.Dispose();
                            this.connection = null;
                        }
                    }
                }
            }
        }
Пример #47
0
        /// <summary>
        /// Sends request to Kafka server asynchronously
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <param name="callback">
        /// The callback invoked when a request is finished being sent.
        /// </param>
        public void Send(ProducerRequest request, MessageSent<ProducerRequest> callback)
        {
            Guard.Assert<ArgumentNullException>(() => request != null);
            Guard.Assert<ArgumentNullException>(() => request.MessageSet != null);
            Guard.Assert<ArgumentNullException>(() => request.MessageSet.Messages != null);
            Guard.Assert<ArgumentException>(
                () => request.MessageSet.Messages.All(x => x.PayloadSize <= this.Config.MaxMessageSize));

            using (var conn = new KafkaConnection(this.config.Host, this.config.Port))
            {
                conn.BeginWrite(request, callback);
            }
        }
Пример #48
0
 /// <summary>
 /// Sends request to Kafka server asynchronously
 /// </summary>
 /// <param name="request">
 /// The request.
 /// </param>
 public void Send(ProducerRequest request)
 {
     Guard.Assert<ArgumentNullException>(() => request != null);
     Guard.Assert<ArgumentException>(() => request.MessageSet.Messages.All(x => x.PayloadSize <= this.Config.MaxMessageSize));
     if (this.callbackHandler != null)
     {
         this.Send(request, this.callbackHandler.Handle);
     }
     else
     {
         using (var conn = new KafkaConnection(this.config.Host, this.config.Port))
         {
             conn.BeginWrite(request);
         }
     }
 }
Пример #49
0
        private static void GetOffsetsBefore(KafkaConnection conn, OffsetRequest request, IList<long> offsets)
        {
            offsets.Clear(); // to make sure the list is clean after some previous attampts to get data
            conn.Write(request);
            int dataLength = BitConverter.ToInt32(BitWorks.ReverseBytes(conn.Read(4)), 0);

            if (dataLength > 0)
            {
                byte[] data = conn.Read(dataLength);

                int errorCode = BitConverter.ToInt16(BitWorks.ReverseBytes(data.Take(2).ToArray()), 0);
                if (errorCode != KafkaException.NoError)
                {
                    throw new KafkaException(errorCode);
                }

                // skip the error code and process the rest
                byte[] unbufferedData = data.Skip(2).ToArray();

                // first four bytes are the number of offsets
                int numOfOffsets =
                    BitConverter.ToInt32(BitWorks.ReverseBytes(unbufferedData.Take(4).ToArray()), 0);

                for (int ix = 0; ix < numOfOffsets; ix++)
                {
                    int position = (ix * 8) + 4;
                    offsets.Add(
                        BitConverter.ToInt64(
                            BitWorks.ReverseBytes(unbufferedData.Skip(position).Take(8).ToArray()), 0));
                }
            }
        }
Пример #50
0
        private static void MultiFetch(KafkaConnection conn, MultiFetchRequest request, IList<BufferedMessageSet> result)
        {
            result.Clear();
            conn.Write(request);
            int dataLength = BitConverter.ToInt32(BitWorks.ReverseBytes(conn.Read(4)), 0);
            if (dataLength <= 0)
            {
                return;
            }

            byte[] data = conn.Read(dataLength);

            int errorCode = BitConverter.ToInt16(BitWorks.ReverseBytes(data.Take(2).ToArray()), 0);
            if (errorCode != KafkaException.NoError)
            {
                throw new KafkaException(errorCode);
            }

            // skip the error code
            byte[] unbufferedData = data.Skip(2).ToArray();
            for (int i = 0; i < request.ConsumerRequests.Count; i++)
            {
                int partLength = BitConverter.ToInt32(BitWorks.ReverseBytes(unbufferedData.Take(4).ToArray()), 0);
                errorCode = BitConverter.ToInt16(BitWorks.ReverseBytes(unbufferedData.Skip(4).Take(2).ToArray()), 0);
                if (errorCode != KafkaException.NoError)
                {
                    throw new KafkaException(errorCode);
                }

                result.Add(BufferedMessageSet.ParseFrom(unbufferedData.Skip(6).Take(partLength - 2).ToArray()));
                unbufferedData = unbufferedData.Skip(partLength + 4).ToArray();
            }
        }
Пример #51
0
        private static BufferedMessageSet Fetch(KafkaConnection conn, FetchRequest request)
        {
            conn.Write(request);
            int dataLength = BitConverter.ToInt32(BitWorks.ReverseBytes(conn.Read(4)), 0);
            if (dataLength > 0)
            {
                byte[] data = conn.Read(dataLength);

                int errorCode = BitConverter.ToInt16(BitWorks.ReverseBytes(data.Take(2).ToArray()), 0);
                if (errorCode != KafkaException.NoError)
                {
                    throw new KafkaException(errorCode);
                }

                // skip the error code
                byte[] unbufferedData = data.Skip(2).ToArray();
                return BufferedMessageSet.ParseFrom(unbufferedData);
            }

            return null;
        }
Пример #52
0
        /// <summary>
        /// Combine multiple fetch requests in one call.
        /// </summary>
        /// <param name="request">
        /// The list of fetch requests.
        /// </param>
        /// <returns>
        /// A list of sets of fetched messages.
        /// </returns>
        /// <remarks>
        /// Offset is passed in on every request, allowing the user to maintain this metadata 
        /// however they choose.
        /// </remarks>
        public IList<BufferedMessageSet> MultiFetch(MultiFetchRequest request)
        {
            var result = new List<BufferedMessageSet>();
            using (var conn = new KafkaConnection(this.Host, this.Port))
            {
                short tryCounter = 1;
                bool success = false;
                while (!success && tryCounter <= this.config.NumberOfTries)
                {
                    try
                    {
                        MultiFetch(conn, request, result);
                        success = true;
                    }
                    catch (Exception ex)
                    {
                        // if maximum number of tries reached
                        if (tryCounter == this.config.NumberOfTries)
                        {
                            throw;
                        }

                        tryCounter++;
                        Logger.InfoFormat(CultureInfo.CurrentCulture, "MultiFetch reconnect due to {0}", ex);
                    }
                }
            }

            return result;
        }
Пример #53
0
        /// <summary>
        /// Combine multiple fetch requests in one call.
        /// </summary>
        /// <param name="request">
        /// The list of fetch requests.
        /// </param>
        /// <returns>
        /// A list of sets of fetched messages.
        /// </returns>
        /// <remarks>
        /// Offset is passed in on every request, allowing the user to maintain this metadata 
        /// however they choose.
        /// </remarks>
        public IList<BufferedMessageSet> MultiFetch(MultiFetchRequest request)
        {
            var result = new List<BufferedMessageSet>();
            short tryCounter = 1;
            while (tryCounter <= this.config.NumberOfTries)
            {
                try
                {
                    using (var conn = new KafkaConnection(
                        this.host,
                        this.port,
                        this.config.BufferSize,
                        this.config.SocketTimeout))
                    {
                        conn.Write(request);
                        int size = conn.Reader.ReadInt32();
                        return BufferedMessageSet.ParseMultiFrom(conn.Reader, size, request.ConsumerRequests.Count);
                    }
                }
                catch (Exception ex)
                {
                    // if maximum number of tries reached
                    if (tryCounter == this.config.NumberOfTries)
                    {
                        throw;
                    }

                    tryCounter++;
                    Logger.InfoFormat(CultureInfo.CurrentCulture, "MultiFetch reconnect due to {0}", ex);
                }
            }

            return result;
        }
Пример #54
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Consumer"/> class.
        /// </summary>
        /// <param name="config">
        /// The consumer configuration.
        /// </param>
        public Consumer(ConsumerConfiguration config)
        {
            Guard.NotNull(config, "config");

            this.config = config;
            this.host = config.Broker.Host;
            this.port = config.Broker.Port;
            this.connection = new KafkaConnection(
                                  this.host,
                                  this.port,
                                  this.config.BufferSize,
                                  this.config.SendTimeout,
                                  this.config.ReceiveTimeout,
                                  this.config.ReconnectInterval);
            this.CreatedTimeInUTC = DateTime.UtcNow.Ticks;
        }
Пример #55
0
        /// <summary>
        /// Gets a list of valid offsets (up to maxSize) before the given time.
        /// </summary>
        /// <param name="request">
        /// The offset request.
        /// </param>
        /// <returns>
        /// The list of offsets, in descending order.
        /// </returns>
        public IList<long> GetOffsetsBefore(OffsetRequest request)
        {
            var result = new List<long>();
            short tryCounter = 1;
            while (tryCounter <= this.config.NumberOfTries)
            {
                try
                {
                    using (var conn = new KafkaConnection(
                        this.host,
                        this.port,
                        this.config.BufferSize,
                        this.config.SocketTimeout))
                    {
                        conn.Write(request);
                        int size = conn.Reader.ReadInt32();
                        if (size == 0)
                        {
                            return result;
                        }

                        short errorCode = conn.Reader.ReadInt16();
                        if (errorCode != KafkaException.NoError)
                        {
                            throw new KafkaException(errorCode);
                        }

                        int count = conn.Reader.ReadInt32();
                        for (int i = 0; i < count; i++)
                        {
                            result.Add(conn.Reader.ReadInt64());
                        }

                        return result;
                    }
                }
                catch (Exception ex)
                {
                    //// if maximum number of tries reached
                    if (tryCounter == this.config.NumberOfTries)
                    {
                        throw;
                    }

                    tryCounter++;
                    Logger.InfoFormat(CultureInfo.CurrentCulture, "GetOffsetsBefore reconnect due to {0}", ex);
                }
            }

            return result;
        }
Пример #56
0
        public void Setup()
        {
            var options = new KafkaOptions(new Uri(ConfigurationManager.AppSettings["IntegrationKafkaServerUrl"]));

            _conn = new KafkaConnection(options.KafkaServerUri.First(), options.ResponseTimeoutMs, options.Log);
        }
Пример #57
0
        /// <summary>
        /// Gets a list of valid offsets (up to maxSize) before the given time.
        /// </summary>
        /// <param name="request">
        /// The offset request.
        /// </param>
        /// <returns>
        /// The list of offsets, in descending order.
        /// </returns>
        public IList<long> GetOffsetsBefore(OffsetRequest request)
        {
            var offsets = new List<long>();
            using (var conn = new KafkaConnection(this.Host, this.Port))
            {
                short tryCounter = 1;
                bool success = false;
                while (!success && tryCounter <= this.config.NumberOfTries)
                {
                    try
                    {
                        GetOffsetsBefore(conn, request, offsets);
                        success = true;
                    }
                    catch (Exception ex)
                    {
                        // if maximum number of tries reached
                        if (tryCounter == this.config.NumberOfTries)
                        {
                            throw;
                        }

                        tryCounter++;
                        Logger.InfoFormat(CultureInfo.CurrentCulture, "GetOffsetsBefore reconnect due to {0}", ex);
                    }
                }
            }

            return offsets;
        }
Пример #58
0
        public void ReadShouldLogDisconnectAndRecover()
        {
            var mockLog = _kernel.GetMock<IKafkaLog>();

            using (var server = new FakeTcpServer(8999))
            using (var socket = new KafkaTcpSocket(mockLog.Object, _kafkaEndpoint))
            using (var conn = new KafkaConnection(socket, log: mockLog.Object))
            {
                var disconnected = false;
                socket.OnServerDisconnected += () => disconnected = true;

                TaskTest.WaitFor(() => server.ConnectionEventcount > 0);
                Assert.That(server.ConnectionEventcount, Is.EqualTo(1));

                server.DropConnection();
                TaskTest.WaitFor(() => server.DisconnectionEventCount > 0);
                Assert.That(server.DisconnectionEventCount, Is.EqualTo(1));

                //Wait a while for the client to notice the disconnect and log
                TaskTest.WaitFor(() => disconnected);
                

                //should log an exception and keep going
                mockLog.Verify(x => x.ErrorFormat(It.IsAny<string>(), It.IsAny<Exception>()));

                TaskTest.WaitFor(() => server.ConnectionEventcount > 1);
                Assert.That(server.ConnectionEventcount, Is.EqualTo(2));
            }
        }
Пример #59
0
 /// <summary>
 /// Sends request to Kafka server synchronously
 /// </summary>
 /// <param name="request">
 /// The request.
 /// </param>
 public void Send(ProducerRequest request)
 {
     Guard.Assert<ArgumentNullException>(() => request != null);
     using (var conn = new KafkaConnection(this.config.Host, this.config.Port))
     {
         conn.Write(request);
     }
 }