Esempio n. 1
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var consumerConfig = new ConsumerConfig
            {
                GroupId          = "socket-server-consumer-command-response" + Guid.NewGuid(), // NOTE: If the socket server restarts it will never join the same group. This is to ensure it always reads the latest data
                BootstrapServers = KafkaHelpers.BootstrapServers,
                AutoOffsetReset  = AutoOffsetReset.Latest,
            };

            KafkaHelpers.SetKafkaConfigKerberos(consumerConfig);

            using (var c = new ConsumerBuilder <Ignore, string>(consumerConfig).Build())
            {
                c.Subscribe($"^{KafkaHelpers.CommandResponseTopicPrefix}");

                _logger.LogInformation("Listening for responses from all command servers");
                while (!stoppingToken.IsCancellationRequested)
                {
                    // consumer does not have an async method. So it is wrapped in a task, so that the rest of the application doesn't hang here
                    var consumeResult = await Task.Factory.StartNew(() => c.Consume(stoppingToken));

                    Console.WriteLine("Found a result! " + consumeResult.Message.Value);
                    await _updatersHub.Clients.All.SendCommandResponses(consumeResult.Message.Value);
                }
                c.Close();
            }
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var consumerConfig = new ConsumerConfig
            {
                GroupId          = "socket-server-consumer",
                BootstrapServers = KafkaHelpers.BootstrapServers,
                AutoOffsetReset  = AutoOffsetReset.Latest,
            };

            KafkaHelpers.SetKafkaConfigKerberos(consumerConfig);

            using (var c = new ConsumerBuilder <Ignore, string>(consumerConfig).Build())
            {
                c.Subscribe(new List <string>
                {
                    KafkaHelpers.OverviewTopic, KafkaHelpers.StatsTopic, KafkaHelpers.InspectTopic
                });

                _logger.LogInformation("Listening for updates");
                while (!stoppingToken.IsCancellationRequested)
                {
                    // consumer does not have an async method. So it is wrapped in a task, so that the rest of the application doesn't hang here
                    var consumeResult = await Task.Factory.StartNew(() => c.Consume(stoppingToken));

                    switch (consumeResult.Topic)
                    {
                    case KafkaHelpers.OverviewTopic:
                        await _updatersHub.Clients.All.SendOverviewData(consumeResult.Message.Value);

                        // NOTE: The method checks on LatestOverviewInfo, so it's important this is called before LatestOverviewInfo is set after the record has been saved
                        // await SaveStatusRecordInDb(consumeResult.Message.Value);
                        KafkaHelpers.LatestOverviewInfo = consumeResult.Message.Value;
                        break;

                    case KafkaHelpers.StatsTopic:
                        await _updatersHub.Clients.All.SendStatsData(consumeResult.Message.Value);

                        // NOTE: The method checks on LatestOverviewInfo, so it's important this is called before LatestOverviewInfo is set after the record has been saved
                        // await SaveRessourceUsageRecordInDb(consumeResult.Message.Value);
                        KafkaHelpers.LatestStatsInfo = consumeResult.Message.Value;
                        break;

                    case KafkaHelpers.InspectTopic:
                        var inspectData = JsonConvert.DeserializeObject <InspectData>(consumeResult.Message.Value);
                        await _updatersHub.Clients.All.SendInspectResponse(
                            JsonConvert.SerializeObject(inspectData));

                        break;
                    }
                }

                c.Close();
            }
        }
Esempio n. 3
0
        public SubscriptionWorker(ILogger <SubscriptionWorker> logger, IServiceProvider services)
        {
            _services = services;
            _logger   = logger;

            var producerConfig = new ProducerConfig {
                Acks = Acks.Leader
            };

            KafkaHelpers.SetKafkaConfigKerberos(producerConfig);

            _producer = new ProducerBuilder <Null, string>(producerConfig).Build();
        }
Esempio n. 4
0
        public static async void Start(CancellationTokenSource cts)
        {
            var consumerConfig = new ConsumerConfig {
                GroupId          = "command-server" + KafkaHelpers.Servername,
                BootstrapServers = KafkaHelpers.BootstrapServers,
                AutoOffsetReset  = AutoOffsetReset.Latest,
            };

            KafkaHelpers.SetKafkaConfigKerberos(consumerConfig);

            using (var c = new ConsumerBuilder <Ignore, string>(consumerConfig).Build()) {
                c.Subscribe(KafkaHelpers.RequestTopic);

                Console.WriteLine($"Listening for commands on topic {KafkaHelpers.RequestTopic}");
                try {
                    var producerConfig = new ProducerConfig {
                        BootstrapServers = KafkaHelpers.BootstrapServers, Acks = Acks.Leader
                    };
                    KafkaHelpers.SetKafkaConfigKerberos(producerConfig);

                    using (var p = new ProducerBuilder <Null, string>(producerConfig).Build()) {
                        while (true)
                        {
                            try {
                                var consumeResult = c.Consume(cts.Token); // Polling for new messages, waiting here until message recieved

                                var messageJsonString = consumeResult.Message.Value;

                                ContainerRequest request = JsonConvert.DeserializeObject <ContainerRequest>(messageJsonString);
                                await CallAction(request.Action, messageJsonString, p);
                            } catch (ConsumeException ex) {
                                Console.Error.WriteLine(ex.Error);
                            } catch (Newtonsoft.Json.JsonException ex) {
                                await KafkaHelpers.SendMessageAsync(KafkaHelpers.ResponseTopic, new ContainerResponse {
                                    ResponseStatusCode = 400,
                                    Message            = ex.Message
                                }, p);
                            }
                        }
                    }
                } catch (OperationCanceledException) { } finally {
                    // Ensure the consumer leaves the group cleanly and final offsets are committed.
                    c.Close();
                }
            }
        }
Esempio n. 5
0
        public static void Start()
        {
            var producerConfig = new ProducerConfig {
                BootstrapServers = KafkaHelpers.BootstrapServers, Acks = Acks.Leader
            };

            KafkaHelpers.SetKafkaConfigKerberos(producerConfig);

            using var p = new ProducerBuilder <Null, string>(producerConfig).Build();

            Task[] tester = new Task[2];
            if (_processesToStart.Contains("overviewdata"))
            {
                var overviewTask = SendOverViewData(p);
                tester[0] = overviewTask;
            }
            if (_processesToStart.Contains("statsdata"))
            {
                var statsTask = SendStatsData(p);
                tester[1] = statsTask;
            }

            Task.WaitAll(tester);
        }
Esempio n. 6
0
        public async void ListenForSubscriptionsActions(CancellationToken stoppingToken, List <CurrentConditionSubscription> currentConditionSubscriptions, List <ForecastSubscription> forecastSubscriptions)
        {
            // Listening and waiting for new subscription requests from kafka
            var consumerConfig = new ConsumerConfig
            {
                GroupId         = "weather-station-new-subscription-group",
                AutoOffsetReset = AutoOffsetReset.Earliest,
            };

            KafkaHelpers.SetKafkaConfigKerberos(consumerConfig);

            using (var consumer = new ConsumerBuilder <Ignore, string>(consumerConfig).Build())
            {
                using (var scope = _services.CreateScope())
                {
                    var repo = scope.ServiceProvider.GetRequiredService <ISubscriptionRepo>();

                    consumer.Subscribe(KafkaHelpers.SubscriptionActionsTopic);

                    _logger.LogInformation("Listening for subscription action requests");
                    while (!stoppingToken.IsCancellationRequested)
                    {
                        try
                        {
                            // consumer does not have an async method. So it is wrapped in a task, so that the rest of the application doesn't hang here
                            var consumeResult = await Task.Factory.StartNew(() => consumer.Consume(stoppingToken));

                            var messageJsonString = consumeResult.Message.Value;

                            // Checking format required.
                            SubscriptionRequestDTO request = JsonConvert.DeserializeObject <SubscriptionRequestDTO>(messageJsonString);

                            _logger.LogInformation("A subscription action request has arrived");
                            switch (request.Action)
                            {
                            case SubscriptionAction.CREATECURRENTCONDITION:
                                var currentConditionRequest = JsonConvert.DeserializeObject <NewCurrentConditionSubscriptionRequestDTO>(messageJsonString);

                                var currentConditionSubscription = new CurrentConditionSubscription
                                {
                                    StationId       = currentConditionRequest.StationId,
                                    IntervalSeconds = currentConditionRequest.IntervalSeconds
                                };

                                // persisting the newly added subscription
                                await repo.AddCurrentConditionSubscription(currentConditionSubscription);

                                // adding it to the list of subscriptions
                                currentConditionSubscriptions.Add(currentConditionSubscription);

                                // starting the subscription. I want this to run in the background. So I discard the result  with '_'
                                _ = Task.Run(() => StartTimer(currentConditionSubscription));
                                break;

                            case SubscriptionAction.CREATEFORECAST:
                                var forecastSubscriptionRequest = JsonConvert.DeserializeObject <ForecastSubscription>(messageJsonString);

                                var forecastSubscription = new ForecastSubscription
                                {
                                    GeoCode         = forecastSubscriptionRequest.GeoCode,
                                    IntervalSeconds = forecastSubscriptionRequest.IntervalSeconds
                                };

                                // persisting the newly added subscription
                                await repo.AddForecastSubscription(forecastSubscription);

                                // adding it to the list of subscriptions
                                forecastSubscriptions.Add(forecastSubscription);

                                // starting the subscription. I want this to run in the background. So I discard the result  with '_'
                                _ = Task.Run(() => StartTimer(forecastSubscription));
                                break;

                            case SubscriptionAction.DELETE:
                                // TODO: Delete
                                break;

                            default:
                                throw new Newtonsoft.Json.JsonException("Invalid Subscription action");
                            }
                        }
                        catch (ConsumeException ex)
                        {
                            _logger.LogError(ex.Error.ToString());
                        }
                        // If the request from kafka is not correctly formatted an error will be thrown and catched here
                        catch (Newtonsoft.Json.JsonException ex)
                        {
                            _logger.LogError(ex.Message);
                        }
                        // Cancelled background worker
                        catch (OperationCanceledException)
                        {
                            consumer.Close();
                        }
                    }
                }
            }
            // If we reach this point it means the application is shutting down. Therefore we clean up
            _logger.LogInformation("Cleaning up");
            _producer.Flush(TimeSpan.FromSeconds(5));
            _producer.Dispose();
        }