Пример #1
0
// 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
}
Пример #2
0
// 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
}
Пример #3
0
// 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
}