public Partition(string topic, int partId, Replica leader = null, HashSet<Replica> assignedReplicas = null,
     HashSet<Replica> inSyncReplica = null, HashSet<Replica> catchUpReplicas = null, HashSet<Replica> reassignedReplicas = null)
 {
     this.Topic = topic;
     this.Leader = leader;
     this.PartId = partId;
     this.AssignedReplicas = assignedReplicas ?? new HashSet<Replica>();
     this.InSyncReplicas = inSyncReplica ?? new HashSet<Replica>();
     this.CatchUpReplicas = catchUpReplicas ?? new HashSet<Replica>();
     this.ReassignedReplicas = reassignedReplicas ?? new HashSet<Replica>();
 }
Example #2
0
 public Partition(string topic,
                  int partId,
                  Replica leader = null,
                  HashSet <Replica> assignedReplicas   = null,
                  HashSet <Replica> inSyncReplica      = null,
                  HashSet <Replica> catchUpReplicas    = null,
                  HashSet <Replica> reassignedReplicas = null)
 {
     Topic              = topic;
     Leader             = leader;
     PartId             = partId;
     AssignedReplicas   = assignedReplicas ?? new HashSet <Replica>();
     InSyncReplicas     = inSyncReplica ?? new HashSet <Replica>();
     CatchUpReplicas    = catchUpReplicas ?? new HashSet <Replica>();
     ReassignedReplicas = reassignedReplicas ?? new HashSet <Replica>();
 }
 public void ShouldHandleEvents()
 {
     var partitioner = new Mock<IPartitioner<string>>();
     var config = new ProducerConfiguration(new List<BrokerConfiguration>());
     var pool = new Mock<ISyncProducerPool>();
     var producer = new Mock<ISyncProducer>();
     var partitionMetadatas = new List<PartitionMetadata>()
     {
         new PartitionMetadata(0, new Broker(0, "host1", 1234), Enumerable.Empty<Broker>(),
             Enumerable.Empty<Broker>())
     };
     var metadatas = new List<TopicMetadata>() { new TopicMetadata("test", partitionMetadatas, ErrorMapping.NoError) };
     producer.SetupGet(p => p.Config)
             .Returns(
                 () =>
                     new SyncProducerConfiguration(new ProducerConfiguration(new List<BrokerConfiguration>()), 0,
                         "host1", 1234));
     producer.Setup(p => p.Send(It.IsAny<TopicMetadataRequest>())).Returns(() => metadatas);
     var statuses = new Dictionary<TopicAndPartition, ProducerResponseStatus>();
     statuses[new TopicAndPartition("test", 0)] = new ProducerResponseStatus();
     producer.Setup(p => p.Send(It.IsAny<ProducerRequest>()))
             .Returns(
                 () =>
                     new ProducerResponse(1, statuses));
     pool.Setup(p => p.GetShuffledProducers()).Returns(() => new List<ISyncProducer>() { producer.Object });
     pool.Setup(p => p.GetProducer(It.IsAny<int>())).Returns(() => producer.Object);
     var mockPartitionInfo = new Mock<IBrokerPartitionInfo>();
     mockPartitionInfo.Setup(m => m.GetBrokerPartitionInfo(0, string.Empty, It.IsAny<int>(), "test"))
                      .Returns(() =>
                      {
                          var partition = new Partition("test", 0);
                          var replica = new Replica(0, "test");
                          partition.Leader = replica;
                          return new List<Partition>() { partition };
                      });
     var handler = new DefaultCallbackHandler<string, Message>(config, partitioner.Object, new DefaultEncoder(), mockPartitionInfo.Object, pool.Object);
     handler.Handle(new List<ProducerData<string, Message>>() { new ProducerData<string, Message>("test", new Message(new byte[100])) });
     pool.Verify(p => p.GetProducer(0));
 }
        /// <summary>
        /// Force get topic metadata and update 
        /// </summary>
        public void UpdateInfo(short versionId, int correlationId, string clientId, string topic)
        {
            Logger.InfoFormat("Will update metadata for topic:{0}", topic);
            Guard.NotNullNorEmpty(topic, "topic");
            var shuffledBrokers = this.syncProducerPool.GetShuffledProducers();
            var i = 0;
            var hasFetchedInfo = false;
            while (i < shuffledBrokers.Count && !hasFetchedInfo)
            {
                ISyncProducer producer = shuffledBrokers[i++];

                try
                {
                    var topicMetadataRequest = TopicMetadataRequest.Create(new List<string>() { topic }, versionId,
                                                                           correlationId, clientId);
                    var topicMetadataList = producer.Send(topicMetadataRequest);
                    var topicMetadata = topicMetadataList.Any() ? topicMetadataList.First() : null;
                    if (topicMetadata != null)
                    {
                        if (topicMetadata.Error != ErrorMapping.NoError)
                        {
                            Logger.WarnFormat("Try get metadata of topic {0} from {1}({2}) . Got error: {3}", topic, producer.Config.BrokerId, producer.Config.Host, topicMetadata.Error.ToString());
                        }
                        else
                        {
                            this.topicPartitionInfo[topic] = topicMetadata;
                            this.topicPartitionInfoLastUpdateTime[topic] = DateTime.UtcNow;
                            Logger.InfoFormat("Will  Update  metadata info, topic {0} ", topic);

                            //TODO:  For all partitions which has metadata, here return the sorted list.
                            //But sometimes kafka didn't return metadata for all topics.
                            this.topicPartitionInfoList[topic] = topicMetadata.PartitionsMetadata.Select(m =>
                                                        {
                                                            Partition partition = new Partition(topic, m.PartitionId);
                                                            if (m.Leader != null)
                                                            {
                                                                var leaderReplica = new Replica(m.Leader.Id, topic);
                                                                partition.Leader = leaderReplica;
                                                                Logger.InfoFormat("Topic {0} partition {1} has leader {2}", topic,
                                                                                   m.PartitionId, m.Leader.Id);

                                                                return partition;
                                                            }

                                                            Logger.WarnFormat("Topic {0} partition {1} does not have a leader yet", topic,
                                                                m.PartitionId);

                                                            return partition;
                                                        }
                                                        ).OrderBy(x => x.PartId).ToList(); ;
                            hasFetchedInfo = true;
                            Logger.InfoFormat("Finish  Update  metadata info, topic {0}  Partitions:{1}  No leader:{2}", topic, this.topicPartitionInfoList[topic].Count, this.topicPartitionInfoList[topic].Where(r => r.Leader == null).Count());

                            //In very weired case, the kafka broker didn't return metadata of all broker. need break and retry.  https://issues.apache.org/jira/browse/KAFKA-1998
                            // http://qnalist.com/questions/5899394/topicmetadata-response-miss-some-partitions-information-sometimes
                            if (zkClient != null)
                            {
                                Dictionary<int, int[]> topicMetaDataInZookeeper = ZkUtils.GetTopicMetadataInzookeeper(this.zkClient, topic);
                                if (topicMetaDataInZookeeper != null && topicMetaDataInZookeeper.Any())
                                {
                                    topicDataInZookeeper[topic] = topicMetaDataInZookeeper;
                                    if (this.topicPartitionInfoList[topic].Count != topicMetaDataInZookeeper.Count)
                                    {
                                        Logger.ErrorFormat("NOT all partition has metadata.  Topic partition in zookeeper :{0} topics has partition metadata: {1}", topicMetaDataInZookeeper.Count, this.topicPartitionInfoList[topic].Count);
                                        throw new UnavailableProducerException(string.Format("Please make sure every partition at least has one broker running and retry again.   NOT all partition has metadata.  Topic partition in zookeeper :{0} topics has partition metadata: {1}", topicMetaDataInZookeeper.Count, this.topicPartitionInfoList[topic].Count));
                                    }
                                }
                            }

                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.ErrorFormat("Try get metadata of topic {0} from {1}({2}) . Got error: {3}", topic, producer.Config.BrokerId, producer.Config.Host, e.FormatException());
                }
            }
        }