protected void PreSend(ProducerMessage message)
 {
     var partitionNo = partitioningAlgo.ComputePartitionNo(
                           message.PartitionKey, 
                           metaService.ListPartitionsByTopic(message.Topic).Count);
     message.Partition = partitionNo;
 }
예제 #2
0
        public static void Main(string[] args)
        {
            Config fallbackConfig = ConfigurationFactory.ParseString(@"
                    akka.suppress-json-serializer-warning=true
                    akka.loglevel = DEBUG
                ").WithFallback(ConfigurationFactory.FromResource <ConsumerSettings <object, object> >("Akka.Streams.Kafka.reference.conf"));

            var system       = ActorSystem.Create("TestKafka", fallbackConfig);
            var materializer = system.Materializer();

            var producerSettings = ProducerSettings <Null, string> .Create(system, null, null)
                                   .WithBootstrapServers("localhost:29092");

            Source
            .Cycle(() => Enumerable.Range(1, 100).GetEnumerator())
            .Select(c => c.ToString())
            .Select(elem => ProducerMessage.Single(new ProducerRecord <Null, string>("akka100", elem)))
            .Via(KafkaProducer.FlexiFlow <Null, string, NotUsed>(producerSettings))
            .Select(result =>
            {
                var response = result as Result <Null, string, NotUsed>;
                Console.WriteLine($"Producer: {response.Metadata.Topic}/{response.Metadata.Partition} {response.Metadata.Offset}: {response.Metadata.Value}");
                return(result);
            })
            .RunWith(Sink.Ignore <IResults <Null, string, NotUsed> >(), materializer);

            // TODO: producer as a Commitable Sink

            // TODO: Sharing KafkaProducer

            Console.ReadLine();
        }
        public async Task Transactional_source_with_sink_Should_work()
        {
            var       settings        = CreateConsumerSettings <string>(CreateGroup(1));
            var       sourceTopic     = CreateTopic(1);
            var       targetTopic     = CreateTopic(2);
            var       transactionalId = Guid.NewGuid().ToString();
            const int totalMessages   = 10;

            var control = KafkaConsumer.TransactionalSource(settings, Subscriptions.Topics(sourceTopic))
                          .Via(Business <TransactionalMessage <Null, string> >())
                          .Select(message =>
            {
                return(ProducerMessage.Single(
                           new ProducerRecord <Null, string>(targetTopic, message.Record.Key, message.Record.Value),
                           passThrough: message.PartitionOffset));
            })
                          .ToMaterialized(KafkaProducer.TransactionalSink(ProducerSettings, transactionalId), Keep.Both)
                          .MapMaterializedValue(DrainingControl <NotUsed> .Create)
                          .Run(Materializer);

            var consumer = ConsumeStrings(targetTopic, totalMessages);

            await ProduceStrings(sourceTopic, Enumerable.Range(1, totalMessages), ProducerSettings);

            AssertTaskCompletesWithin(TimeSpan.FromSeconds(totalMessages), consumer.IsShutdown);
            AssertTaskCompletesWithin(TimeSpan.FromSeconds(totalMessages), control.DrainAndShutdown());

            consumer.DrainAndShutdown().Result.Should().HaveCount(totalMessages);
        }
예제 #4
0
 public void Finish(ProducerMessage message)
 {
     using (var command = database.GetSqlStringCommand(FINISH_SQL))
     {
         database.AddInParameter(command, "@messageid", DbType.AnsiString, message.Base.MessageId);
         database.ExecuteNonQuery(command);
     }
 }
        public void ProduceMessage(ProducerMessage eventMessage)
        {
            var body = Encoding.UTF8.GetBytes(eventMessage.Content);

            channel.BasicPublish(exchange: "",
                                 routingKey: QueueConfiguration.AggregatedTopicsQueueName,
                                 basicProperties: null,
                                 body: body);
        }
예제 #6
0
 public void Error(ProducerMessage message, int status)
 {
     using (var command = database.GetSqlStringCommand(ERROR_SQL))
     {
         database.AddInParameter(command, "@status", DbType.Int16, status);
         database.AddInParameter(command, "@updatetime", DbType.DateTime, DateTime.Now);
         database.AddInParameter(command, "@messageid", DbType.AnsiString, message.Base.MessageId);
         database.ExecuteNonQuery(command);
     }
 }
예제 #7
0
 public void Save(ProducerMessage message)
 {
     using (var command = database.GetSqlStringCommand(INSERT_SQL))
     {
         database.AddInParameter(command, "@messageid", DbType.AnsiString, message.Base.MessageId);
         database.AddInParameter(command, "@content", DbType.String, message.Base.ToString());
         database.AddInParameter(command, "@createtime", DbType.DateTime, DateTime.Now);
         database.ExecuteNonQuery(command);
     }
 }
예제 #8
0
        public async Task SendWithAkka(SequenceFlowInput inputMessage)
        {
            var producerSettings = ProducerSettings <Null, string> .Create(Context.System, null, null)
                                   .WithBootstrapServers(KafkaEndpoint);

            await Source
            .Single("Akka: " + inputMessage.ProcessInstanceId.ToString())
            .Select(kafkaMessage => ProducerMessage.Single(new ProducerRecord <Null, string>(TopicName, kafkaMessage)))
            .Via(KafkaProducer.FlexiFlow <Null, string, NotUsed>(producerSettings))
            .RunWith(Sink.Ignore <IResults <Null, string, NotUsed> >(), Materializer);
        }
예제 #9
0
 private void enrichPartitionKey(ProducerMessage msg, String ip)
 {
     if (string.IsNullOrEmpty(msg.PartitionKey))
     {
         if (logEnrichInfo)
         {
             log.Info(string.Format("Parition key not set, will set ip as partition key(topic={0}, ip={1})", msg.Topic, ip));
         }
         msg.PartitionKey = ip;
     }
 }
예제 #10
0
 private void enrichRefKey(ProducerMessage msg)
 {
     if (string.IsNullOrEmpty(msg.Key))
     {
         String refKey = System.Guid.NewGuid().ToString();
         if (logEnrichInfo)
         {
             log.Info(string.Format("Ref key not set, will set uuid as ref key(topic={0}, ref key={1})", msg.Topic, refKey));
         }
         msg.Key = refKey;
     }
 }
        public byte[] Encode(ProducerMessage message, byte version)
        {
            var bodyCodec = PayloadCodecFactory.GetCodecByTopicName(message.Topic);
            var body = bodyCodec.Encode(message.Topic, message.GetBody<object>());
            var buf = IoBuffer.Allocate(body.Length + 150);
            buf.AutoExpand = true;
            Magic.WriteMagic(buf);
            buf.Put(version);
            Encode(message, buf, body, bodyCodec.Type);

            return null;
        }
예제 #12
0
 public DefaultMessageHolder(
     string topic, 
     string partitionKey, 
     object body,
     IPipeline<IFuture<SendResult>> pipeline,
     ISystemClockService systemClockService)
 {
     this.message = new ProducerMessage(topic, body);
     this.message.PartitionKey = partitionKey;
     this.pipeline = pipeline;
     this.systemClockService = systemClockService;
 }
        public IProducerMessage ToProducerMessage <TKey, TAggregate>(IEvent <TKey, TAggregate> @event) where TAggregate : IAggregate <TKey>
        {
            @event.Subject = GetSubject(@event);

            var message = new ProducerMessage()
            {
                MessageBytes = Serializer.Serialize(@event),
                Subject      = @event.Subject,
                MessageType  = @event.GetType()
            };

            return(message);
        }
예제 #14
0
        [InlineData(20, 10)] //20 개의 메시지를 생산하고,소비한다,테스트는 10초이내에 완료되어야함(완료시 종료됨)
        public void Test1(int limit, int cutoff)
        {
            string lastSignal          = Guid.NewGuid().ToString();
            int    readyTimeForConsume = 3;
            int    recCnt = 0;

            KafkaConsumer.CommittableSource(consumerSettings, subscription)
            .RunForeach(result =>
            {
                Console.WriteLine($"Consumer: {result.Record.Topic}/{result.Record.Partition} {result.Record.Offset}: {result.Record.Value}");
                if (lastSignal == result.Record.Value)
                {
                    probe.Tell("처리모두완료");
                }

                result.CommitableOffset.Commit();
            }, materializer_consumer);

            Source <int, NotUsed> source = Source.From(Enumerable.Range(1, limit));

            source
            .Throttle(2, TimeSpan.FromSeconds(1), 1, ThrottleMode.Shaping)          //출력 조절 : 초당 2개처리
            .Select(c =>
            {
                var result = $"No:{c.ToString()}";
                if (c == limit)
                {
                    result = lastSignal;
                }
                return(result);
            })
            .Select(elem => ProducerMessage.Single(new ProducerRecord <Null, string>(testTopic, elem)))
            .Via(KafkaProducer.FlexiFlow <Null, string, NotUsed>(producerSettings))
            .Select(result =>
            {
                var response = result as Result <Null, string, NotUsed>;
                Console.WriteLine($"Producer: {response.Metadata.Topic}/{response.Metadata.Partition} {response.Metadata.Offset}: {response.Metadata.Value}");
                return(result);
            })
            .RunWith(Sink.Ignore <IResults <Null, string, NotUsed> >(), materializer_producer);

            Within(TimeSpan.FromSeconds(cutoff), () =>
            {
                probe.ExpectMsg("처리모두완료", TimeSpan.FromSeconds(cutoff));
            });
        }
예제 #15
0
        public void AddMessage(ProducerMessage message, SettableFuture<SendResult> future)
        {
            Validate(message);
            message.SequenceNo = msgCounter.AtomicIncrementAndGet();
            if (message.IsPriority)
            {
                messages.TryAdd(0, new List<ProducerMessage>());
                messages[0].Add(message);
            }
            else
            {
                messages.TryAdd(1, new List<ProducerMessage>());
                messages[1].Add(message);
            }

            futures[message.SequenceNo] = future;
        }
예제 #16
0
        public void SinkMessage(string producerName, string topic, List <string> message, int tps)
        {
            int maxBuster = 1;  //메시지가 해당값에 도달하면, TPS 제약기가 발동합니다.
            ProducerSettings <Null, string> producerSettings = producerList[producerName];
            Source <string, NotUsed>        source           = Source.From(message);

            source
            .Select(c =>
            {
                return(c);
            })
            .Select(elem => ProducerMessage.Single(new ProducerRecord <Null, string>(topic, elem)))
            .Throttle(tps, TimeSpan.FromSeconds(1), maxBuster, ThrottleMode.Shaping)      //TPS
            .Via(KafkaProducer.FlexiFlow <Null, string, NotUsed>(producerSettings))
            .Select(result =>
            {
                var response = result as Result <Null, string, NotUsed>;
                Console.WriteLine($"[{DateTime.Now}] Producer: {response.Metadata.Topic}/{response.Metadata.Partition} {response.Metadata.Offset}: {response.Metadata.Value}");
                return(result);
            })
            .RunWith(Sink.Ignore <IResults <Null, string, NotUsed> >(), materializer_producer);
        }
예제 #17
0
        static async Task Main(string[] args)
        {
            Config fallbackConfig = ConfigurationFactory.ParseString(@"
                    akka.suppress-json-serializer-warning=true
                    akka.loglevel = DEBUG
                ").WithFallback(ConfigurationFactory.FromResource <ConsumerSettings <object, object> >("Akka.Streams.Kafka.reference.conf"));

            var system       = ActorSystem.Create("TestKafka", fallbackConfig);
            var materializer = system.Materializer();

            var producerSettings = ProducerSettings <Null, string> .Create(system, null, null)
                                   .WithBootstrapServers($"{EventHubNamespace}.servicebus.windows.net:9093")
                                   .WithProperties(new Dictionary <string, string>
            {
                { "security.protocol", "SASL_SSL" },
                { "sasl.mechanism", "PLAIN" },
                { "sasl.username", "$ConnectionString" },
                { "sasl.password", EventHubConnectionString },
            });

            await Source.From(Enumerable.Range(1, 100))
            .Select(c => c.ToString())
            .Select(elem => ProducerMessage.Single(new ProducerRecord <Null, string>(EventHubName, elem)))
            .Via(KafkaProducer.FlexiFlow <Null, string, NotUsed>(producerSettings))
            .Select(result =>
            {
                var response = result as Result <Null, string, NotUsed>;
                Console.WriteLine($"Producer: {response.Metadata.Topic}/{response.Metadata.Partition} {response.Metadata.Offset}: {response.Metadata.Value}");
                return(result);
            })
            .RunWith(Sink.Ignore <IResults <Null, string, NotUsed> >(), materializer);

            Console.ReadKey();

            await system.Terminate();
        }
        private void Encode(ProducerMessage message, IoBuffer buf, byte[] body, string codecType)
        {
            var codec = new HermesPrimitiveCodec(buf);
            var indexBeginning = buf.Position;
            codec.WriteInt(-1); // placeholder for whole length
            var indexAfterWholeLen = buf.Position;
            codec.WriteInt(-1); // placeholder for header length
            codec.WriteInt(-1); // placeholder for body length
            var indexBeforeHeader = buf.Position;

            // header begin
            codec.WriteString(message.Key);
            codec.WriteLong(message.BornTime);
            codec.WriteInt(0); //remaining retries
            codec.WriteString(codecType);

            var propertiesHolder = message.PropertiesHolder;
            WriteProperties(propertiesHolder.DurableProperties, buf, codec);
            WriteProperties(propertiesHolder.VolatileProperties, buf, codec);
            // header end

            var headerLen = buf.Position - indexBeforeHeader;

            //body begin
            var indexBeforeBody = buf.Position;
            buf.Put(body);
            var bodyLen = buf.Position - indexBeforeBody;
            //body end

            //crc
            codec.WriteLong(ChecksumUtil.Crc32(buf.GetSlice(indexBeforeHeader, headerLen + bodyLen)));
            var indexEnd = buf.Position;

            var wholeLen = indexEnd - indexAfterWholeLen;

            // refill whole length
            buf.Position = indexBeginning;
            codec.WriteInt(wholeLen);

            // refill header length
            codec.WriteInt(headerLen);

            // refill body length
            codec.WriteInt(bodyLen);

            buf.Position = indexEnd;
        }
 protected abstract IFuture<SendResult> DoSend(ProducerMessage message);
 public IFuture<SendResult> Send(ProducerMessage message)
 {
     PreSend(message);
     return DoSend(message);
 }
예제 #21
0
        private void Validate(ProducerMessage message)
        {
            if (string.IsNullOrEmpty(Topic))
                throw new ArgumentNullException("SendMessageCommand.Topic");

            if (string.IsNullOrEmpty(message.Topic))
                throw new ArgumentNullException("ProducerMessage.Topic");

            if (!Topic.Equals(message.Topic, StringComparison.OrdinalIgnoreCase)
                || Partition != message.Partition)
            {
                throw new ArgumentException(string.Format("Illegal message[topic={0}, partition={1}] try to add to SendMessageCommand[topic={0}, partition={1}]",
                        message.Topic, message.Partition, Topic, Partition));
            }
        }
        public async Task ProducerFlowWithContext_should_work_with_source_with_context()
        {
            bool Duplicate(string value) => value == "1";
            bool Ignore(string value) => value == "2";

            var consumerSettings  = CreateConsumerSettings <string, string>(CreateGroup(1));
            var topic1            = CreateTopic(1);
            var topic2            = CreateTopic(2);
            var topic3            = CreateTopic(3);
            var topic4            = CreateTopic(4);
            var producerSettings  = BuildProducerSettings <string, string>();
            var committerSettings = CommitterSettings;
            var totalMessages     = 10;
            var totalConsumed     = 0;

            await ProduceStrings(topic1, Enumerable.Range(1, totalMessages), producerSettings);

            var(control2, result) = KafkaConsumer.PlainSource(consumerSettings, Subscriptions.Topics(topic2, topic3, topic4))
                                    .Scan(0, (c, _) => c + 1)
                                    .Select(consumed =>
            {
                totalConsumed = consumed;
                return(consumed);
            })
                                    .ToMaterialized(Sink.Last <int>(), Keep.Both)
                                    .Run(Materializer);

            var control = KafkaConsumer.SourceWithOffsetContext(consumerSettings, Subscriptions.Topics(topic1))
                          .Select(record =>
            {
                IEnvelope <string, string, NotUsed> output;
                if (Duplicate(record.Message.Value))
                {
                    output = ProducerMessage.Multi(new[]
                    {
                        new ProducerRecord <string, string>(topic2, record.Message.Key, record.Message.Value),
                        new ProducerRecord <string, string>(topic3, record.Message.Key, record.Message.Value)
                    }.ToImmutableSet());
                }
                else if (Ignore(record.Message.Value))
                {
                    output = ProducerMessage.PassThrough <string, string>();
                }
                else
                {
                    output = ProducerMessage.Single(new ProducerRecord <string, string>(topic4, record.Message.Key, record.Message.Value));
                }

                Log.Debug($"Giving message of type {output.GetType().Name}");
                return(output);
            })
                          .Via(KafkaProducer.FlowWithContext <string, string, ICommittableOffset>(producerSettings))
                          .AsSource()
                          .Log("Produced messages", r => $"Committing {r.Item2.Offset.Topic}:{r.Item2.Offset.Partition}[{r.Item2.Offset.Offset}]")
                          .ToMaterialized(Committer.SinkWithOffsetContext <IResults <string, string, ICommittableOffset> >(committerSettings), Keep.Both)
                          .MapMaterializedValue(tuple => DrainingControl <NotUsed> .Create(tuple.Item1, tuple.Item2))
                          .Run(Materializer);

            // One by one, wait while all `totalMessages` will be consumed
            for (var i = 1; i < totalMessages; ++i)
            {
                var consumedExpect = i;
                Log.Info($"Waiting for {consumedExpect} to be consumed...");
                try
                {
                    await AwaitConditionAsync(() => totalConsumed >= consumedExpect, TimeSpan.FromSeconds(30));
                }
                finally
                {
                    Log.Info($"Finished waiting for {consumedExpect} messages. Total: {totalConsumed}");
                }
                Log.Info($"Confirmed that {consumedExpect} messages are consumed");
            }

            AssertTaskCompletesWithin(TimeSpan.FromSeconds(10), control.DrainAndShutdown());
            AssertTaskCompletesWithin(TimeSpan.FromSeconds(10), control2.Shutdown());
            AssertTaskCompletesWithin(TimeSpan.FromSeconds(10), result).Should().Be(totalConsumed);
        }
예제 #23
0
		public byte[] Encode (ProducerMessage message)
		{
			return CURRENT_VERSION.Handler.Encode (message, CURRENT_VERSION.Version);
		}
예제 #24
0
		public void Encode (ProducerMessage message, IoBuffer buf)
		{
			Magic.WriteMagic (buf);
			buf.Put (CURRENT_VERSION.Version);
			CURRENT_VERSION.Handler.Encode (message, buf);
		}
예제 #25
0
 public JMCEngine()
 {
     producerMessage = new ProducerMessage(uri, userName, passWord, exChange);
 }
예제 #26
0
        public async Task SupervisionStrategy_Decider_on_complex_stream_should_work()
        {
            var topic                   = CreateTopic(1);
            var group                   = CreateGroup(1);
            var topicPartition          = new TopicPartition(topic, 0);
            var committedTopicPartition = new TopicPartition($"{topic}-done", 0);
            var callCount               = 0;

            Directive Decider(Exception cause)
            {
                callCount++;
                return(Directive.Resume);
            }

            var committerSettings = CommitterSettings.Create(Sys);
            var consumerSettings  = CreateConsumerSettings <string>(group);
            var counter           = 0;

            // arrange
            await Source.From(Enumerable.Range(1, 10))
            .Select(elem => new ProducerRecord <Null, string>(topicPartition, elem.ToString()))
            .RunWith(KafkaProducer.PlainSink(ProducerSettings), Materializer);

            // act
            var drainingControl = KafkaConsumer.CommittableSource(consumerSettings, Subscriptions.Assignment(topicPartition))
                                  .Via(Flow.Create <CommittableMessage <Null, string> >().Select(x =>
            {
                counter++;
                // Exception happened here, fail once, when counter is 5
                if (counter == 5)
                {
                    throw new Exception("BOOM!");
                }
                return(x);
            }))
                                  .WithAttributes(Attributes.CreateName("CommitableSource").And(ActorAttributes.CreateSupervisionStrategy(Decider)))
                                  .Select(c => (c.Record.Topic, c.Record.Message.Value, c.CommitableOffset))
                                  .SelectAsync(1, async t =>
            {
                Log.Info($"[{t.Topic}]: {t.Value}");
                // simulate a request-response call that takes 10ms to complete here
                await Task.Delay(10);
                return(t);
            })
                                  .Select(t => ProducerMessage.Single(new ProducerRecord <Null, string>(committedTopicPartition, t.Value),
                                                                      t.CommitableOffset))
                                  .Via(KafkaProducer.FlexiFlow <Null, string, ICommittableOffset>(ProducerSettings)).WithAttributes(Attributes.CreateName("FlexiFlow"))
                                  .Select(m => (ICommittable)m.PassThrough)
                                  .AlsoToMaterialized(Committer.Sink(committerSettings), DrainingControl <NotUsed> .Create)
                                  .To(Flow.Create <ICommittable>()
                                      .Async()
                                      .GroupedWithin(1000, TimeSpan.FromSeconds(1))
                                      .Select(c => c.Count())
                                      .Log("MsgCount").AddAttributes(Attributes.CreateLogLevels(LogLevel.InfoLevel))
                                      .To(Sink.Ignore <int>()))
                                  .Run(Sys.Materializer());

            await Task.Delay(TimeSpan.FromSeconds(5));

            await GuardWithTimeoutAsync(drainingControl.DrainAndShutdown(), TimeSpan.FromSeconds(10));

            // There should be only 1 decider call
            callCount.Should().Be(1);

            // Assert that all of the messages, except for those that failed in the stage, got committed
            var settings = CreateConsumerSettings <Null, string>(group);
            var probe    = KafkaConsumer
                           .PlainSource(settings, Subscriptions.Assignment(committedTopicPartition))
                           .Select(c => c.Message.Value)
                           .RunWith(this.SinkProbe <string>(), Materializer);

            probe.Request(9);
            var messages = new List <string>();

            for (var i = 0; i < 9; ++i)
            {
                var message = probe.RequestNext();
                messages.Add(message);
            }

            // Message "5" is missing because the exception happened downstream of the source and we chose to
            // ignore it in the decider
            messages.Should().BeEquivalentTo(new[] { "1", "2", "3", "4", "6", "7", "8", "9", "10" });
            probe.Cancel();
        }
 public void Encode(ProducerMessage message, IoBuffer buf)
 {
     var bodyCodec = PayloadCodecFactory.GetCodecByTopicName(message.Topic);
     var body = bodyCodec.Encode(message.Topic, message.GetBody<object>());
     Encode(message, buf, body, bodyCodec.Type);
 }
예제 #28
0
 private void enrichMessageProperties(ProducerMessage msg, String ip)
 {
     msg.AddDurableSysProperty(MessagePropertyNames.PRODUCER_IP, ip);
 }