kazoo-ruby 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec91cf4af491cd9c00ad11b459c64b92884d9289
4
- data.tar.gz: 585ba40ab883b2bc70014ae38ece4fb7f4240bcf
3
+ metadata.gz: 8459c642f0d085f68811488f9d6ab92f186fd296
4
+ data.tar.gz: 2f187078b0e87d345e71277195750ebecbd3b5b4
5
5
  SHA512:
6
- metadata.gz: 3f7021a9e7f42e3315d9c7386db8113619c555881535c1ddc44e2c4aec07983acd02d3f49442b3654090376f2d33f3b95a463cc375c5b2e1eab9a9778a054928
7
- data.tar.gz: 10bc6041afe7942eeaaa214ef9609ff391e1b8eef6daa723b626f6994bf3cb9dd875c5bf5bf3e68a80c66c7e489c8999ec293c03b5f2f7279cc9935280a0f3c8
6
+ metadata.gz: e22aa111a85057bd295d80485371c46c84b1306d89160e04e2d2a21b985c407da14c59c4936d49239232f53e0309fb59fd9ca71f8affcc6cab8dd3f428ab55b7
7
+ data.tar.gz: 570508f6fe5f8d10bb8081b06c43f44b5f20da4e28d57801fcc5c6204f97a1f4557ac7234fd67bc72c7173111d145a42f6a5eabc5479267ccf9eb27095706fac
data/README.md CHANGED
@@ -1,31 +1,60 @@
1
1
  # Kazoo
2
2
 
3
- TODO: Write a gem description
3
+ Ruby library to access and manipulate Kafka metadata in Zookeeper
4
4
 
5
- ## Installation
5
+ ## Usage
6
6
 
7
- Add this line to your application's Gemfile:
7
+ First, make kazoo available by adding it to your Gemfile
8
8
 
9
- ```ruby
10
- gem 'kazoo'
9
+ ``` ruby
10
+ gem 'kazoo-ruby', require: 'kazoo'
11
11
  ```
12
12
 
13
- And then execute:
13
+ Now, you can interact with the cluster metadata as follows:
14
14
 
15
- $ bundle
15
+ ``` ruby
16
+ # Connect to the Zookeeper cluster that backs your Kafka cluster
17
+ cluster = Kazoo::Cluster.new('zookeeper1:2181,zookeeper2:2181/chroot')
16
18
 
17
- Or install it yourself as:
19
+ # List the brokers that form the Kafka cluster
20
+ cluster.brokers.each do |id, broker|
21
+ puts "Broker #{broker.id}: #{broker.addr}"
22
+ end
18
23
 
19
- $ gem install kazoo
24
+ # Inspect topic/partition metadata
25
+ cluster.topics.each do |name, topic|
26
+ puts "#{name}: #{topic.partitions.length} partitions"
27
+ end
20
28
 
21
- ## Usage
29
+ # List consumers
30
+ cluster.consumergroups.each do |name, group|
31
+ puts "Consumer #{name}: #{group.instances.length} running instances"
32
+ end
33
+ ```
22
34
 
23
- TODO: Write usage instructions here
35
+ ## Binary
36
+
37
+ This gem also comes with a simple `kazoo` binary to inspect your kafka cluster:
38
+
39
+ ```
40
+ # Describe the brokers that compose the cluster
41
+ $ kazoo cluster --zookeeper zk1:2181,zk2:2181,zk3:2181/chroot
42
+
43
+ # List all topics or partitions in the cluster
44
+ $ kazoo topics --zookeeper zk1:2181,zk2:2181,zk3:2181/chroot
45
+ $ kazoo partitions --topic=access_log --zookeeper zk1:2181,zk2:2181,zk3:2181/chroot
46
+
47
+ ```
24
48
 
25
49
  ## Contributing
26
50
 
27
- 1. Fork it ( https://github.com/[my-github-username]/kazoo/fork )
51
+ 1. Fork it ( https://github.com/wvanbergen/kazoo/fork )
28
52
  2. Create your feature branch (`git checkout -b my-new-feature`)
29
53
  3. Commit your changes (`git commit -am 'Add some feature'`)
30
54
  4. Push to the branch (`git push origin my-new-feature`)
31
55
  5. Create a new Pull Request
56
+
57
+ ## See also
58
+
59
+ - [kafka-consumer](https://github.com/wvanbergen/kafka-consumer): a high-level
60
+ Kafka consumer library that coordinates running instances using Zookeeper.
data/kazoo-ruby.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Kazoo::VERSION
9
9
  spec.authors = ["Willem van Bergen"]
10
10
  spec.email = ["willem@vanbergen.org"]
11
- spec.summary = %q{Library to access Kafka metadata in Zookeeper}
12
- spec.description = %q{Library to access Kafka metadata in Zookeeper}
11
+ spec.summary = %q{Library to access and manipulate Kafka metadata in Zookeeper}
12
+ spec.description = %q{Library to access and manipulate Kafka metadata in Zookeeper}
13
13
  spec.homepage = "https://github.com/wvanbergen/kazoo"
14
14
  spec.license = "MIT"
15
15
 
data/lib/kazoo.rb CHANGED
@@ -1,12 +1,21 @@
1
1
  require 'zookeeper'
2
2
  require 'json'
3
3
  require 'thread'
4
+ require 'socket'
5
+ require 'securerandom'
4
6
 
5
7
  module Kazoo
8
+ Error = Class.new(StandardError)
9
+
10
+ NoClusterRegistered = Class.new(Kazoo::Error)
11
+ ConsumerInstanceRegistrationFailed = Class.new(Kazoo::Error)
12
+ PartitionAlreadyClaimed = Class.new(Kazoo::Error)
13
+ ReleasePartitionFailure = Class.new(Kazoo::Error)
6
14
  end
7
15
 
8
16
  require 'kazoo/cluster'
9
17
  require 'kazoo/broker'
10
18
  require 'kazoo/topic'
11
19
  require 'kazoo/partition'
20
+ require 'kazoo/consumergroup'
12
21
  require 'kazoo/version'
data/lib/kazoo/broker.rb CHANGED
@@ -61,6 +61,10 @@ module Kazoo
61
61
  [self.cluster, self.id].hash
62
62
  end
63
63
 
64
+ def inspect
65
+ "#<Kazoo::Broker id=#{id} addr=#{addr}>"
66
+ end
67
+
64
68
  def self.from_json(cluster, id, json)
65
69
  new(cluster, id.to_i, json.fetch('host'), json.fetch('port'), jmx_port: json.fetch('jmx_port', nil))
66
70
  end
data/lib/kazoo/cli.rb CHANGED
@@ -3,8 +3,7 @@ require 'thor'
3
3
 
4
4
  module Kazoo
5
5
  class CLI < Thor
6
- class_option :zookeeper, :type => :string, :default => ENV['ZOOKEEPER_PEERS']
7
- class_option :chroot, :type => :string, :default => ""
6
+ class_option :zookeeper, :type => :string, :default => ENV['ZOOKEEPER']
8
7
 
9
8
  desc "cluster", "Describes the Kafka cluster as registered in Zookeeper"
10
9
  def cluster
@@ -57,7 +56,7 @@ module Kazoo
57
56
 
58
57
  def validate_class_options!
59
58
  if options[:zookeeper].nil? || options[:zookeeper] == ''
60
- raise Thor::InvocationError, "Please supply --zookeeper argument, or set the ZOOKEEPER_PEERS environment variable"
59
+ raise Thor::InvocationError, "Please supply --zookeeper argument, or set the ZOOKEEPER environment variable"
61
60
  end
62
61
  end
63
62
 
@@ -73,7 +72,7 @@ module Kazoo
73
72
  end
74
73
 
75
74
  def kafka_cluster
76
- @kafka_cluster ||= Kazoo::Cluster.new(options[:zookeeper], chroot: options[:chroot])
75
+ @kafka_cluster ||= Kazoo::Cluster.new(options[:zookeeper])
77
76
  end
78
77
  end
79
78
  end
data/lib/kazoo/cluster.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  module Kazoo
2
2
  class Cluster
3
3
 
4
- attr_reader :zookeeper, :chroot
4
+ attr_reader :zookeeper
5
5
 
6
- def initialize(zookeeper, chroot: "")
7
- @zookeeper, @chroot = zookeeper, chroot
6
+ def initialize(zookeeper)
7
+ @zookeeper = zookeeper
8
8
  @zk_mutex, @brokers_mutex, @topics_mutex = Mutex.new, Mutex.new, Mutex.new
9
9
  end
10
10
 
@@ -17,11 +17,18 @@ module Kazoo
17
17
  def brokers
18
18
  @brokers_mutex.synchronize do
19
19
  @brokers ||= begin
20
- brokers = zk.get_children(path: node_with_chroot("/brokers/ids"))
20
+ brokers = zk.get_children(path: "/brokers/ids")
21
+
22
+ if brokers.fetch(:rc) != Zookeeper::Constants::ZOK
23
+ raise NoClusterRegistered, "No Kafka cluster registered on this Zookeeper location."
24
+ end
25
+
21
26
  result, threads, mutex = {}, ThreadGroup.new, Mutex.new
22
27
  brokers.fetch(:children).map do |id|
23
28
  t = Thread.new do
24
- broker_info = zk.get(path: node_with_chroot("/brokers/ids/#{id}"))
29
+ broker_info = zk.get(path: "/brokers/ids/#{id}")
30
+ raise Kazoo::Error, "Failed to retrieve broker info. Error code: #{broker_info.fetch(:rc)}" unless broker_info.fetch(:rc) == Zookeeper::Constants::ZOK
31
+
25
32
  broker = Kazoo::Broker.from_json(self, id, JSON.parse(broker_info.fetch(:data)))
26
33
  mutex.synchronize { result[id.to_i] = broker }
27
34
  end
@@ -33,14 +40,25 @@ module Kazoo
33
40
  end
34
41
  end
35
42
 
43
+ def consumergroups
44
+ @consumergroups ||= begin
45
+ consumers = zk.get_children(path: "/consumers")
46
+ consumers.fetch(:children).map { |name| Kazoo::Consumergroup.new(self, name) }
47
+ end
48
+ end
49
+
36
50
  def topics
37
51
  @topics_mutex.synchronize do
38
52
  @topics ||= begin
39
- topics = zk.get_children(path: node_with_chroot("/brokers/topics"))
53
+ topics = zk.get_children(path: "/brokers/topics")
54
+ raise Kazoo::Error, "Failed to list topics. Error code: #{topics.fetch(:rc)}" unless topics.fetch(:rc) == Zookeeper::Constants::ZOK
55
+
40
56
  result, threads, mutex = {}, ThreadGroup.new, Mutex.new
41
57
  topics.fetch(:children).each do |name|
42
58
  t = Thread.new do
43
- topic_info = zk.get(path: node_with_chroot("/brokers/topics/#{name}"))
59
+ topic_info = zk.get(path: "/brokers/topics/#{name}")
60
+ raise Kazoo::Error, "Failed to get topic info. Error code: #{topic_info.fetch(:rc)}" unless topic_info.fetch(:rc) == Zookeeper::Constants::ZOK
61
+
44
62
  topic = Kazoo::Topic.from_json(self, name, JSON.parse(topic_info.fetch(:data)))
45
63
  mutex.synchronize { result[name] = topic }
46
64
  end
@@ -64,8 +82,8 @@ module Kazoo
64
82
  partitions.any?(&:under_replicated?)
65
83
  end
66
84
 
67
- def node_with_chroot(path)
68
- "#{@chroot}#{path}"
85
+ def close
86
+ zk.close
69
87
  end
70
88
  end
71
89
  end
@@ -0,0 +1,215 @@
1
+ module Kazoo
2
+ class Consumergroup
3
+ attr_reader :cluster, :name
4
+
5
+ def initialize(cluster, name)
6
+ @cluster, @name = cluster, name
7
+ end
8
+
9
+ def create
10
+ cluster.zk.create(path: "/consumers/#{name}")
11
+ cluster.zk.create(path: "/consumers/#{name}/ids")
12
+ cluster.zk.create(path: "/consumers/#{name}/owners")
13
+ cluster.zk.create(path: "/consumers/#{name}/offsets")
14
+ end
15
+
16
+ def exists?
17
+ stat = cluster.zk.stat(path: "/consumers/#{name}")
18
+ stat.fetch(:stat).exists?
19
+ end
20
+
21
+
22
+ def instantiate(id: nil)
23
+ Instance.new(self, id: id)
24
+ end
25
+
26
+ def instances
27
+ instances = cluster.zk.get_children(path: "/consumers/#{name}/ids")
28
+ instances.fetch(:children).map { |id| Instance.new(self, id: id) }
29
+ end
30
+
31
+ def watch_instances(&block)
32
+ cb = Zookeeper::Callbacks::WatcherCallback.create(&block)
33
+ result = cluster.zk.get_children(path: "/consumers/#{name}/ids", watcher: cb)
34
+
35
+ if result.fetch(:rc) != Zookeeper::Constants::ZOK
36
+ raise Kazoo::Error, "Failed to watch instances. Error code: #{result.fetch(:rc)}"
37
+ end
38
+
39
+ instances = result.fetch(:children).map { |id| Instance.new(self, id: id) }
40
+ [instances, cb]
41
+ end
42
+
43
+
44
+ def watch_partition_claim(partition, &block)
45
+ cb = Zookeeper::Callbacks::WatcherCallback.create(&block)
46
+
47
+ result = cluster.zk.get(path: "/consumers/#{name}/owners/#{partition.topic.name}/#{partition.id}", watcher: cb)
48
+
49
+ case result.fetch(:rc)
50
+ when Zookeeper::Constants::ZNONODE # Nobody is claiming this partition yet
51
+ [nil, nil]
52
+ when Zookeeper::Constants::ZOK
53
+ [Kazoo::Consumergroup::Instance.new(self, id: result.fetch(:data)), cb]
54
+ else
55
+ raise Kazoo::Error, "Failed set watch for partition claim of #{partition.topic.name}/#{partition.id}. Error code: #{result.fetch(:rc)}"
56
+ end
57
+ end
58
+
59
+ def retrieve_offset(partition)
60
+ result = cluster.zk.get(path: "/consumers/#{name}/offsets/#{partition.topic.name}/#{partition.id}")
61
+ case result.fetch(:rc)
62
+ when Zookeeper::Constants::ZOK;
63
+ result.fetch(:data).to_i
64
+ when Zookeeper::Constants::ZNONODE;
65
+ nil
66
+ else
67
+ raise Kazoo::Error, "Failed to retrieve offset for partition #{partition.topic.name}/#{partition.id}. Error code: #{result.fetch(:rc)}"
68
+ end
69
+ end
70
+
71
+ def commit_offset(partition, offset)
72
+ result = cluster.zk.set(path: "/consumers/#{name}/offsets/#{partition.topic.name}/#{partition.id}", data: (offset + 1).to_s)
73
+ if result.fetch(:rc) == Zookeeper::Constants::ZNONODE
74
+ result = cluster.zk.create(path: "/consumers/#{name}/offsets/#{partition.topic.name}")
75
+ case result.fetch(:rc)
76
+ when Zookeeper::Constants::ZOK, Zookeeper::Constants::ZNODEEXISTS
77
+ else
78
+ raise Kazoo::Error, "Failed to commit offset #{offset} for partition #{partition.topic.name}/#{partition.id}. Error code: #{result.fetch(:rc)}"
79
+ end
80
+
81
+ result = cluster.zk.create(path: "/consumers/#{name}/offsets/#{partition.topic.name}/#{partition.id}", data: (offset + 1).to_s)
82
+ end
83
+
84
+ if result.fetch(:rc) != Zookeeper::Constants::ZOK
85
+ raise Kazoo::Error, "Failed to commit offset #{offset} for partition #{partition.topic.name}/#{partition.id}. Error code: #{result.fetch(:rc)}"
86
+ end
87
+ end
88
+
89
+ def reset_offsets
90
+ result = cluster.zk.get_children(path: "/consumers/#{name}/offsets")
91
+ raise Kazoo::Error unless result.fetch(:rc) == Zookeeper::Constants::ZOK
92
+
93
+ result.fetch(:children).each do |topic|
94
+ result = cluster.zk.get_children(path: "/consumers/#{name}/offsets/#{topic}")
95
+ raise Kazoo::Error unless result.fetch(:rc) == Zookeeper::Constants::ZOK
96
+
97
+ result.fetch(:children).each do |partition|
98
+ cluster.zk.delete(path: "/consumers/#{name}/offsets/#{topic}/#{partition}")
99
+ raise Kazoo::Error unless result.fetch(:rc) == Zookeeper::Constants::ZOK
100
+ end
101
+
102
+ cluster.zk.delete(path: "/consumers/#{name}/offsets/#{topic}")
103
+ raise Kazoo::Error unless result.fetch(:rc) == Zookeeper::Constants::ZOK
104
+ end
105
+ end
106
+
107
+ def inspect
108
+ "#<Kazoo::Consumergroup name=#{name}>"
109
+ end
110
+
111
+ def eql?(other)
112
+ other.kind_of?(Kazoo::Consumergroup) && cluster == other.cluster && name == other.name
113
+ end
114
+
115
+ alias_method :==, :eql?
116
+
117
+ def hash
118
+ [cluster, name].hash
119
+ end
120
+
121
+ class Instance
122
+
123
+ def self.generate_id
124
+ "#{Socket.gethostname}:#{SecureRandom.uuid}"
125
+ end
126
+
127
+ attr_reader :group, :id
128
+
129
+ def initialize(group, id: nil)
130
+ @group = group
131
+ @id = id || self.class.generate_id
132
+ end
133
+
134
+ def registered?
135
+ stat = cluster.zk.stat(path: "/consumers/#{group.name}/ids/#{id}")
136
+ stat.fetch(:stat).exists?
137
+ end
138
+
139
+ def register(subscription)
140
+ result = cluster.zk.create(
141
+ path: "/consumers/#{group.name}/ids/#{id}",
142
+ ephemeral: true,
143
+ data: JSON.generate({
144
+ version: 1,
145
+ timestamp: Time.now.to_i,
146
+ pattern: "static",
147
+ subscription: Hash[*subscription.flat_map { |topic| [topic.name, 1] } ]
148
+ })
149
+ )
150
+
151
+ if result.fetch(:rc) != Zookeeper::Constants::ZOK
152
+ raise Kazoo::ConsumerInstanceRegistrationFailed, "Failed to register instance #{id} for consumer group #{group.name}! Error code: #{result.fetch(:rc)}"
153
+ end
154
+
155
+ subscription.each do |topic|
156
+ stat = cluster.zk.stat(path: "/consumers/#{group.name}/owners/#{topic.name}")
157
+ unless stat.fetch(:stat).exists?
158
+ result = cluster.zk.create(path: "/consumers/#{group.name}/owners/#{topic.name}")
159
+ if result.fetch(:rc) != Zookeeper::Constants::ZOK
160
+ raise Kazoo::ConsumerInstanceRegistrationFailed, "Failed to register subscription of #{topic.name} for consumer group #{group.name}! Error code: #{result.fetch(:rc)}"
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ def deregister
167
+ cluster.zk.delete(path: "/consumers/#{group.name}/ids/#{id}")
168
+ end
169
+
170
+ def claim_partition(partition)
171
+ result = cluster.zk.create(
172
+ path: "/consumers/#{group.name}/owners/#{partition.topic.name}/#{partition.id}",
173
+ ephemeral: true,
174
+ data: id,
175
+ )
176
+
177
+ case result.fetch(:rc)
178
+ when Zookeeper::Constants::ZOK
179
+ return true
180
+ when Zookeeper::Constants::ZNODEEXISTS
181
+ raise Kazoo::PartitionAlreadyClaimed, "Partition #{partition.topic.name}/#{partition.id} is already claimed!"
182
+ else
183
+ raise Kazoo::Error, "Failed to claim partition #{partition.topic.name}/#{partition.id}. Error code: #{result.fetch(:rc)}"
184
+ end
185
+ end
186
+
187
+ def release_partition(partition)
188
+ result = cluster.zk.delete(path: "/consumers/#{group.name}/owners/#{partition.topic.name}/#{partition.id}")
189
+ if result.fetch(:rc) != Zookeeper::Constants::ZOK
190
+ raise Kazoo::Error, "Failed to release partition #{partition.topic.name}/#{partition.id}. Error code: #{result.fetch(:rc)}"
191
+ end
192
+ end
193
+
194
+ def inspect
195
+ "#<Kazoo::Consumergroup::Instance group=#{group.name} id=#{id}>"
196
+ end
197
+
198
+ def hash
199
+ [group, id].hash
200
+ end
201
+
202
+ def eql?(other)
203
+ other.kind_of?(Kazoo::Consumergroup::Instance) && group == other.group && id == other.id
204
+ end
205
+
206
+ alias_method :==, :eql?
207
+
208
+ private
209
+
210
+ def cluster
211
+ group.cluster
212
+ end
213
+ end
214
+ end
215
+ end
@@ -33,10 +33,26 @@ module Kazoo
33
33
  isr.length < replication_factor
34
34
  end
35
35
 
36
+ def inspect
37
+ "#<Kazoo::Partition #{topic.name}/#{id}>"
38
+ end
39
+
40
+ def eql?(other)
41
+ other.kind_of?(Kazoo::Partition) && topic == other.topic && id == other.id
42
+ end
43
+
44
+ alias_method :==, :eql?
45
+
46
+ def hash
47
+ [topic, id].hash
48
+ end
49
+
36
50
  protected
37
51
 
38
52
  def refresh_state
39
- state_json = cluster.zk.get(path: cluster.node_with_chroot("/brokers/topics/#{topic.name}/partitions/#{id}/state"))
53
+ state_json = cluster.zk.get(path: "/brokers/topics/#{topic.name}/partitions/#{id}/state")
54
+ raise Kazoo::Error, "Failed to get partition state. Error code: #{state_json.fetch(:rc)}" unless state_json.fetch(:rc) == Zookeeper::Constants::ZOK
55
+
40
56
  set_state(JSON.parse(state_json.fetch(:data)))
41
57
  end
42
58
 
data/lib/kazoo/topic.rb CHANGED
@@ -28,5 +28,19 @@ module Kazoo
28
28
  def under_replicated?
29
29
  partitions.any?(:under_replicated?)
30
30
  end
31
+
32
+ def inspect
33
+ "#<Kazoo::Topic #{name}>"
34
+ end
35
+
36
+ def eql?(other)
37
+ other.kind_of?(Kazoo::Topic) && cluster == other.cluster && name == other.name
38
+ end
39
+
40
+ alias_method :==, :eql?
41
+
42
+ def hash
43
+ [cluster, name].hash
44
+ end
31
45
  end
32
46
  end
data/lib/kazoo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kazoo
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/test/broker_test.rb CHANGED
@@ -42,4 +42,16 @@ class BrokerTest < Minitest::Test
42
42
  assert_equal 2, @cluster.brokers[2].led_partitions.length
43
43
  assert_equal 1, @cluster.brokers[3].led_partitions.length
44
44
  end
45
+
46
+ def test_inspect
47
+ assert_equal "#<Kazoo::Broker id=1 addr=example.com:9091>", @cluster.brokers[1].inspect
48
+ end
49
+
50
+ def test_equality
51
+ b1 = @cluster.brokers[1]
52
+ b2 = Kazoo::Broker.new(@cluster, 1, 'example.com', 9091)
53
+
54
+ assert_equal b1, b2
55
+ assert_equal b1.hash, b2.hash
56
+ end
45
57
  end
@@ -17,9 +17,24 @@ class PartitionTest < Minitest::Test
17
17
  partition.unstub(:isr)
18
18
 
19
19
  json_payload = '{"controller_epoch":157,"leader":1,"version":1,"leader_epoch":8,"isr":[3,2,1]}'
20
- @cluster.zk.expects(:get).with(path: "/brokers/topics/test.1/partitions/0/state").returns(data: json_payload)
20
+ @cluster.zk.expects(:get).with(path: "/brokers/topics/test.1/partitions/0/state").returns(data: json_payload, rc: 0)
21
21
 
22
22
  assert_equal 1, partition.leader.id
23
23
  assert_equal [3,2,1], partition.isr.map(&:id)
24
24
  end
25
+
26
+ def test_inspect
27
+ assert_equal "#<Kazoo::Partition test.1/0>", @cluster.topics['test.1'].partition(0).inspect
28
+ end
29
+
30
+ def test_equality
31
+ topic = @cluster.topics['test.1']
32
+ p1 = topic.partition(0)
33
+ p2 = Kazoo::Partition.new(topic, 0)
34
+
35
+ assert_equal p1, p2
36
+ assert p1 != Kazoo::Partition.new(topic, 1)
37
+ assert p1 != Kazoo::Partition.new(@cluster.topics['test.4'], 0)
38
+ assert_equal p1.hash, p2.hash
39
+ end
25
40
  end
data/test/topic_test.rb CHANGED
@@ -37,4 +37,17 @@ class TopicTest < Minitest::Test
37
37
  assert @cluster.topics['test.1'].partitions[0].under_replicated?
38
38
  assert @cluster.topics['test.1'].under_replicated?
39
39
  end
40
+
41
+ def test_inspect
42
+ assert_equal "#<Kazoo::Topic test.1>", @cluster.topics['test.1'].inspect
43
+ end
44
+
45
+ def test_equality
46
+ t1 = @cluster.topics['test.1']
47
+ t2 = Kazoo::Topic.new(@cluster, 'test.1')
48
+
49
+ assert_equal t1, t2
50
+ assert t1 != Kazoo::Topic.new(@cluster, 'test.2')
51
+ assert_equal t1.hash, t2.hash
52
+ end
40
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kazoo-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Bergen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-12 00:00:00.000000000 Z
11
+ date: 2015-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '5'
97
- description: Library to access Kafka metadata in Zookeeper
97
+ description: Library to access and manipulate Kafka metadata in Zookeeper
98
98
  email:
99
99
  - willem@vanbergen.org
100
100
  executables:
@@ -114,6 +114,7 @@ files:
114
114
  - lib/kazoo/broker.rb
115
115
  - lib/kazoo/cli.rb
116
116
  - lib/kazoo/cluster.rb
117
+ - lib/kazoo/consumergroup.rb
117
118
  - lib/kazoo/partition.rb
118
119
  - lib/kazoo/topic.rb
119
120
  - lib/kazoo/version.rb
@@ -145,7 +146,7 @@ rubyforge_project:
145
146
  rubygems_version: 2.0.14
146
147
  signing_key:
147
148
  specification_version: 4
148
- summary: Library to access Kafka metadata in Zookeeper
149
+ summary: Library to access and manipulate Kafka metadata in Zookeeper
149
150
  test_files:
150
151
  - test/broker_test.rb
151
152
  - test/cluster_test.rb