// GetAllTopicConsumers returns group -> client-id -> consumed-partitions-list // mapping for a particular topic. Warning, the function performs scan of all // consumer groups registered in ZooKeeper and therefore can take a lot of time. func (a *T) GetAllTopicConsumers(topic string) (map[string]map[string][]int32, error) { zookeeperClt, _, err := zk.Connect(a.cfg.ZooKeeper.SeedPeers, 1*time.Second) if err != nil { return nil, ErrSetup(fmt.Errorf("failed to create zk.Conn: err=(%v)", err)) } defer zookeeperClt.Close() groupsPath := fmt.Sprintf("%s/consumers", a.cfg.ZooKeeper.Chroot) groups, _, err := zookeeperClt.Children(groupsPath) if err != nil { return nil, NewErrQuery(err, "failed to fetch consumer groups") } consumers := make(map[string]map[string][]int32) for _, group := range groups { groupConsumers, err := a.GetTopicConsumers(group, topic) if err != nil { if _, ok := err.(ErrInvalidParam); ok { continue } return nil, NewErrQuery(err, "failed to fetch group `%s` data", group) } if len(groupConsumers) > 0 { consumers[group] = groupConsumers } } return consumers, nil }
// NewKazoo creates a new connection instance func NewKazoo(servers []string, conf *Config) (*Kazoo, error) { if conf == nil { conf = NewConfig() } conn, _, err := zk.Connect(servers, conf.Timeout) if err != nil { return nil, err } return &Kazoo{conn, conf}, nil }
// GetTopicConsumers returns client-id -> consumed-partitions-list mapping // for a clients from a particular consumer group and a particular topic. func (a *T) GetTopicConsumers(group, topic string) (map[string][]int32, error) { zookeeperClt, _, err := zk.Connect(a.cfg.ZooKeeper.SeedPeers, 1*time.Second) if err != nil { return nil, ErrSetup(fmt.Errorf("failed to create zk.Conn: err=(%v)", err)) } defer zookeeperClt.Close() consumedPartitionsPath := fmt.Sprintf("%s/consumers/%s/owners/%s", a.cfg.ZooKeeper.Chroot, group, topic) partitionNodes, _, err := zookeeperClt.Children(consumedPartitionsPath) if err != nil { if err == zk.ErrNoNode { return nil, ErrInvalidParam(fmt.Errorf("either group or topic is incorrect")) } return nil, NewErrQuery(err, "failed to fetch partition owners data") } consumers := make(map[string][]int32) for _, partitionNode := range partitionNodes { partition, err := strconv.Atoi(partitionNode) if err != nil { return nil, NewErrQuery(err, "invalid partition id: %s", partitionNode) } partitionPath := fmt.Sprintf("%s/%s", consumedPartitionsPath, partitionNode) partitionNodeData, _, err := zookeeperClt.Get(partitionPath) if err != nil { return nil, NewErrQuery(err, "failed to fetch partition owner") } clientID := string(partitionNodeData) consumers[clientID] = append(consumers[clientID], int32(partition)) } for _, partitions := range consumers { sort.Sort(int32Slice(partitions)) } return consumers, nil }