public async Task Consume(ConsumeContext <KafkaMessage> context) { var message = context.Message; var cacheKey = $"KafkaMessageKey:{context.GetKey<string>()}"; var cancellationToken = context.CancellationToken; // check that this key wasn't consumed before var cache = await _distributedCache.GetAsync(cacheKey, cancellationToken); //skip if already consumed if (cache != null) { _logger.LogTrace("Skipping already consumed message {Key}", cacheKey); return; } _logger.LogTrace("Received message with Key:{Key}", cacheKey); await context.Publish <PublishMessageByUserId>( new { UserId = message.Hash, Message = new EncryptedMessage(message.Nonce, message.EncodedMessage) }, cancellationToken); // mark as consumed await _distributedCache.SetAsync(cacheKey, new byte[1], new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromDays(2) }, cancellationToken); }
public async Task Should_contains_payload() { TaskCompletionSource <ConsumeContext <KafkaMessage> > taskCompletionSource = GetTask <ConsumeContext <KafkaMessage> >(); var services = new ServiceCollection(); services.AddSingleton(taskCompletionSource); services.TryAddSingleton <ILoggerFactory>(LoggerFactory); services.TryAddSingleton(typeof(ILogger <>), typeof(Logger <>)); services.AddMassTransit(x => { x.UsingInMemory((context, cfg) => cfg.ConfigureEndpoints(context)); x.AddRider(rider => { rider.AddConsumer <KafkaMessageConsumer>(); rider.AddProducer <string, KafkaMessage>(Topic, (context, c) => c.SetKeySerializer(Serializers.Utf8)); rider.UsingKafka((context, k) => { k.Host("localhost:9092"); k.TopicEndpoint <string, KafkaMessage>(Topic, nameof(ReceiveWithPayload_Specs), c => { c.CreateIfMissing(); c.ConfigureConsumer <KafkaMessageConsumer>(context); c.SetKeyDeserializer(Deserializers.Utf8); }); }); }); }); var provider = services.BuildServiceProvider(); var busControl = provider.GetRequiredService <IBusControl>(); var observer = GetConsumeObserver(); busControl.ConnectConsumeObserver(observer); await busControl.StartAsync(TestCancellationToken); try { var producer = provider.GetRequiredService <ITopicProducer <string, KafkaMessage> >(); var key = NewId.NextGuid().ToString(); await producer.Produce(key, new { }, TestCancellationToken); ConsumeContext <KafkaMessage> result = await taskCompletionSource.Task; Assert.IsTrue(result.TryGetPayload(out KafkaConsumeContext <string> _)); Assert.AreEqual(key, result.GetKey <string>()); Assert.That(await observer.Messages.Any <KafkaMessage>()); } finally { await busControl.StopAsync(TestCancellationToken); await provider.DisposeAsync(); } }