public static ConsumerDto ToConsumerDto(this ProxyConsumer proxyConsumer) { var consumerDto = new ConsumerDto { Id = proxyConsumer.Id, ServiceName = proxyConsumer.GateConsumer.ServiceName, TopicName = proxyConsumer.GateConsumer.TopicName, Endpoint = proxyConsumer.Endpoint, IsStarted = proxyConsumer.GateConsumer.IsStarted, MaxConcurrentMessages = proxyConsumer.GateConsumer.MaxConcurrentMessages, AbortTime = proxyConsumer.AbortTime, RestartCount = proxyConsumer.RestartCount, RestartDelayInSeconds = proxyConsumer.RestartDelayInSeconds }; if (proxyConsumer.RestartTask != null && proxyConsumer.RestartTask.IsCompletedSuccessfully) { consumerDto.RestartTaskStatus = "COMPLETED_SUCCESSFULLY"; } if (proxyConsumer.RestartTask != null && proxyConsumer.RestartTask.IsFaulted) { consumerDto.RestartTaskStatus = "FAULTED"; } if (proxyConsumer.RestartTask != null && !proxyConsumer.RestartTask.IsCompleted) { consumerDto.RestartTaskStatus = "RUNNING"; } return(consumerDto); }
public async Task <ProxyConsumer> SubscribeConsumerAsync( string serviceName, string topicName, Uri endpoint, int maxConcurrentMessages, int restartDelayInSeconds, int restartCount, CancellationToken cancellationToken = default) { serviceName = serviceName ?? throw new ArgumentNullException(nameof(serviceName)); topicName = topicName ?? throw new ArgumentNullException(nameof(topicName)); endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); if (!endpoint.IsAbsoluteUri) { throw new ArgumentException("Endpoint uri must be absolute", nameof(endpoint)); } var consumerId = $"{serviceName}_{topicName}_{endpoint}".ToSha256(); var proxyConsumer = new ProxyConsumer(); if (!_proxyConsumers.TryAdd(consumerId, proxyConsumer)) { throw new InvalidOperationException("Consumer already exists"); } try { proxyConsumer.Id = consumerId; proxyConsumer.Endpoint = endpoint; proxyConsumer.AbortTime = null; proxyConsumer.RestartDelayInSeconds = restartDelayInSeconds; proxyConsumer.RestartCount = restartCount; proxyConsumer.HttpClient = _httpClientFactory.CreateClient(); proxyConsumer.UnsubscribeCompletionSource = null; proxyConsumer.GateConsumer = _gateFactory.CreateConsumer <GateRequest, GateResponse>(serviceName, topicName, async(genericContext, ct) => { var httpRequestMessage = genericContext.Message.ToHttpRequestMessage(endpoint); var httpResponseMessage = await proxyConsumer.HttpClient.SendAsync(httpRequestMessage, ct); if (!httpResponseMessage.IsSuccessStatusCode && !genericContext.IsRequest) { if (!_fallbackServices.Any()) { httpResponseMessage.EnsureSuccessStatusCode(); } var fallbackExceptions = new List <Exception>(); foreach (var fallbackService in _fallbackServices) { try { await fallbackService.SendAsync(serviceName, topicName, genericContext.Message, ct); break; } catch (Exception ex) { fallbackExceptions.Add(ex); } } if (fallbackExceptions.Any()) { throw new AggregateException("Can not send message to service or fallbacks", fallbackExceptions); } } if (genericContext.IsRequest) { genericContext.Reply = await httpResponseMessage.ToGateResponseAsync(); } }, () => { proxyConsumer.AbortTime = DateTime.Now; if (proxyConsumer.UnsubscribeCompletionSource != null) { proxyConsumer.UnsubscribeCompletionSource.TrySetResult(true); } else { proxyConsumer.RestartCancellationTokenSource = new CancellationTokenSource(); proxyConsumer.RestartTask = RestartHandler(consumerId); } }, false, maxConcurrentMessages); await proxyConsumer.GateConsumer.StartConsumeAsync(cancellationToken); return(proxyConsumer); } catch (Exception ex) { _logger.LogError(ex, "Error starting consumer"); _proxyConsumers.TryRemove(consumerId, out _); throw; } }