hermann 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +15 -2
- data/lib/hermann/consumer.rb +7 -2
- data/lib/hermann/discovery/zookeeper.rb +80 -0
- data/lib/hermann/producer.rb +18 -3
- data/lib/hermann/provider/java_producer.rb +64 -0
- data/lib/hermann/version.rb +1 -1
- data/lib/hermann.rb +18 -0
- data/lib/hermann_jars.rb +15 -0
- metadata +33 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b08abedfd6c15b1c7c1aa5dfe66315501c212512
|
4
|
+
data.tar.gz: 3bf7306d482a260fd73004e4d8087cd5f3a1f063
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 901a4eecf276229c561186f5be901b6ed87313d35d6878365621ee0302328870f24fe02661620d633f4e55462aaf953a8036c3da88d5d6e6d66c7e71e9e6a9d4
|
7
|
+
data.tar.gz: 300db74c52df5be4f01078b6098c9a0cd528da811c4681e2fb0dde337c7b5b9bfe1cbe645769f9c616adbc9cfe5a841d9413f2d51208518e2dd1a20a4fce57cf
|
data/Rakefile
CHANGED
@@ -12,7 +12,15 @@ Rake::ExtensionTask.new do |t|
|
|
12
12
|
end
|
13
13
|
|
14
14
|
RSpec::Core::RakeTask.new(:spec) do |r|
|
15
|
-
|
15
|
+
options = ['--tag ~type:integration']
|
16
|
+
|
17
|
+
if RUBY_PLATFORM == 'java'
|
18
|
+
options << '--tag ~platform:mri'
|
19
|
+
else
|
20
|
+
options << '--tag ~platform:java'
|
21
|
+
end
|
22
|
+
|
23
|
+
r.rspec_opts = options.join(' ')
|
16
24
|
end
|
17
25
|
|
18
26
|
namespace :spec do
|
@@ -29,5 +37,10 @@ end
|
|
29
37
|
|
30
38
|
task :build => [:compile]
|
31
39
|
task :clean => [:removetmp]
|
32
|
-
|
40
|
+
|
41
|
+
if RUBY_PLATFORM == 'java'
|
42
|
+
task :default => [:clean, :spec]
|
43
|
+
else
|
44
|
+
task :default => [:clean, :build, :spec]
|
45
|
+
end
|
33
46
|
|
data/lib/hermann/consumer.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'hermann'
|
2
|
-
|
2
|
+
|
3
|
+
unless Hermann.jruby?
|
4
|
+
require 'hermann_lib'
|
5
|
+
end
|
3
6
|
|
4
7
|
module Hermann
|
5
8
|
class Consumer
|
@@ -9,7 +12,9 @@ module Hermann
|
|
9
12
|
@topic = topic
|
10
13
|
@brokers = brokers
|
11
14
|
@partition = partition
|
12
|
-
|
15
|
+
unless Hermann.jruby?
|
16
|
+
@internal = Hermann::Lib::Consumer.new(topic, brokers, partition)
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
20
|
def consume(&block)
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'hermann'
|
2
|
+
require 'zk'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Hermann
|
6
|
+
module Discovery
|
7
|
+
class NoBrokersError < StandardError; end
|
8
|
+
|
9
|
+
# Communicates with Zookeeper to discover kafka broker ids
|
10
|
+
#
|
11
|
+
class Zookeeper
|
12
|
+
attr_reader :zookeepers
|
13
|
+
|
14
|
+
BROKERS_PATH = "/brokers/ids".freeze
|
15
|
+
|
16
|
+
def initialize(zookeepers)
|
17
|
+
@zookeepers = zookeepers
|
18
|
+
end
|
19
|
+
|
20
|
+
# Gets comma separated string of brokers
|
21
|
+
#
|
22
|
+
# @param [Fixnum] timeout to connect to zookeeper, "2 times the
|
23
|
+
# tickTime (as set in the server configuration) and a maximum
|
24
|
+
# of 20 times the tickTime2 times the tick time set on server"
|
25
|
+
#
|
26
|
+
# @return [String] comma separated list of brokers
|
27
|
+
def get_brokers(timeout=0)
|
28
|
+
brokers = []
|
29
|
+
ZK.open(zookeepers, {:timeout => timeout}) do |zk|
|
30
|
+
brokers = fetch_brokers(zk)
|
31
|
+
end
|
32
|
+
raise NoBrokersError if brokers.empty?
|
33
|
+
brokers.join(',')
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Gets an Array of broker strings
|
39
|
+
#
|
40
|
+
# @param [ZK::Client] zookeeper client
|
41
|
+
#
|
42
|
+
# @return array of broker strings
|
43
|
+
def fetch_brokers(zk)
|
44
|
+
brokers = []
|
45
|
+
zk.children(BROKERS_PATH).each do |id|
|
46
|
+
node = fetch_znode(zk, id)
|
47
|
+
next if node.nil? # whatever error could happen from ZK#get
|
48
|
+
brokers << format_broker_from_znode(node)
|
49
|
+
end
|
50
|
+
brokers.compact
|
51
|
+
end
|
52
|
+
|
53
|
+
# Gets node from zookeeper
|
54
|
+
#
|
55
|
+
# @param [ZK::Client] zookeeper client
|
56
|
+
# @param [Fixnum] kafka broker
|
57
|
+
#
|
58
|
+
# @return [String] node data
|
59
|
+
def fetch_znode(zk, id)
|
60
|
+
zk.get("#{BROKERS_PATH}/#{id}")[0]
|
61
|
+
rescue ZK::Exceptions::NoNode
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
# Formats the node data into string
|
66
|
+
#
|
67
|
+
# @param [String] node data
|
68
|
+
#
|
69
|
+
# @return [String] formatted node data or empty string if error
|
70
|
+
def format_broker_from_znode(znode)
|
71
|
+
hash = JSON.parse(znode)
|
72
|
+
host = hash['host']
|
73
|
+
port = hash['port']
|
74
|
+
host && port ? "#{host}:#{port}" : nil
|
75
|
+
rescue JSON::ParserError
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/hermann/producer.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'hermann'
|
2
2
|
require 'hermann/result'
|
3
|
-
|
3
|
+
|
4
|
+
|
5
|
+
if RUBY_PLATFORM == "java"
|
6
|
+
require 'hermann/provider/java_producer'
|
7
|
+
else
|
8
|
+
require 'hermann_lib'
|
9
|
+
end
|
4
10
|
|
5
11
|
module Hermann
|
6
12
|
class Producer
|
@@ -9,7 +15,11 @@ module Hermann
|
|
9
15
|
def initialize(topic, brokers)
|
10
16
|
@topic = topic
|
11
17
|
@brokers = brokers
|
12
|
-
|
18
|
+
if RUBY_PLATFORM == "java"
|
19
|
+
@internal = Hermann::Provider::JavaProducer.new(topic, brokers)
|
20
|
+
else
|
21
|
+
@internal = Hermann::Lib::Producer.new(topic, brokers)
|
22
|
+
end
|
13
23
|
# We're tracking children so we can make sure that at Producer exit we
|
14
24
|
# make a reasonable attempt to clean up outstanding result objects
|
15
25
|
@children = []
|
@@ -43,7 +53,12 @@ module Hermann
|
|
43
53
|
if value.kind_of? Array
|
44
54
|
return value.map { |e| self.push(e) }
|
45
55
|
else
|
46
|
-
|
56
|
+
if RUBY_PLATFORM == "java"
|
57
|
+
result = @internal.push_single(value)
|
58
|
+
@children << result
|
59
|
+
else
|
60
|
+
@internal.push_single(value, result)
|
61
|
+
end
|
47
62
|
end
|
48
63
|
|
49
64
|
return result
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'hermann'
|
2
|
+
require 'concurrent'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Hermann
|
6
|
+
module Provider
|
7
|
+
|
8
|
+
# This class simulates the kafka producer class within a java environment.
|
9
|
+
# If the producer throw an exception within the Promise a call to +.value!+
|
10
|
+
# will raise the exception and the rejected flag will be set to true
|
11
|
+
#
|
12
|
+
class JavaProducer
|
13
|
+
attr_accessor :topic, :producer
|
14
|
+
|
15
|
+
def initialize(topic, brokers)
|
16
|
+
@topic = topic
|
17
|
+
properties = create_properties(:brokers => brokers)
|
18
|
+
config = create_config(properties)
|
19
|
+
@producer = JavaApiUtil::Producer.new(config)
|
20
|
+
end
|
21
|
+
|
22
|
+
DEFAULTS = {
|
23
|
+
:string_encoder => 'kafka.serializer.StringEncoder',
|
24
|
+
:partitioner => 'kafka.producer.DefaultPartitioner',
|
25
|
+
:required_acks => "1"
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
# Push a value onto the Kafka topic passed to this +Producer+
|
29
|
+
#
|
30
|
+
# @param [Object] value A single object to push
|
31
|
+
#
|
32
|
+
# @return +Concurrent::Promise+ Representa a promise to send the
|
33
|
+
# data to the kafka broker. Upon execution the Promise's status
|
34
|
+
# will be set
|
35
|
+
def push_single(msg)
|
36
|
+
Concurrent::Promise.execute {
|
37
|
+
data = ProducerUtil::KeyedMessage.new(@topic, msg)
|
38
|
+
@producer.send(data)
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
# @return [ProducerConfig] - packaged config for +Producer+
|
44
|
+
def create_config(properties)
|
45
|
+
ProducerUtil::ProducerConfig.new(properties)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Properties] properties object for creating +ProducerConfig+
|
49
|
+
def create_properties(args={})
|
50
|
+
brokers = args[:brokers]
|
51
|
+
str_encoder = DEFAULTS[:string_encoder]
|
52
|
+
partitioner = DEFAULTS[:partitioner]
|
53
|
+
acks = DEFAULTS[:required_acks]
|
54
|
+
|
55
|
+
properties = JavaUtil::Properties.new
|
56
|
+
properties.put('metadata.broker.list', brokers)
|
57
|
+
properties.put('serializer.class', str_encoder)
|
58
|
+
properties.put('partitioner.class', partitioner)
|
59
|
+
properties.put('request.required.acks', acks)
|
60
|
+
properties
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/hermann/version.rb
CHANGED
data/lib/hermann.rb
CHANGED
@@ -1,2 +1,20 @@
|
|
1
1
|
module Hermann
|
2
|
+
def self.jruby?
|
3
|
+
return RUBY_PLATFORM == "java"
|
4
|
+
end
|
5
|
+
|
6
|
+
if self.jruby?
|
7
|
+
require 'java'
|
8
|
+
require 'hermann_jars'
|
9
|
+
|
10
|
+
module JavaUtil
|
11
|
+
include_package 'java.util'
|
12
|
+
end
|
13
|
+
module ProducerUtil
|
14
|
+
include_package 'kafka.producer'
|
15
|
+
end
|
16
|
+
module JavaApiUtil
|
17
|
+
include_package 'kafka.javaapi.producer'
|
18
|
+
end
|
19
|
+
end
|
2
20
|
end
|
data/lib/hermann_jars.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# this is a generated file, to avoid over-writing it just delete this comment
|
2
|
+
require 'jar_dependencies'
|
3
|
+
|
4
|
+
require_jar( 'org.slf4j', 'slf4j-api', '1.7.2' )
|
5
|
+
require_jar( 'org.scala-lang', 'scala-library', '2.10.1' )
|
6
|
+
require_jar( 'log4j', 'log4j', '1.2.14' )
|
7
|
+
require_jar( 'com.yammer.metrics', 'metrics-core', '2.2.0' )
|
8
|
+
require_jar( 'org.apache.zookeeper', 'zookeeper', '3.3.4' )
|
9
|
+
require_jar( 'net.sf.jopt-simple', 'jopt-simple', '3.2' )
|
10
|
+
require_jar( 'org.apache.kafka', 'kafka_2.10', '0.8.1.1' )
|
11
|
+
require_jar( 'jline', 'jline', '0.9.94' )
|
12
|
+
require_jar( 'com.101tec', 'zkclient', '0.3' )
|
13
|
+
require_jar( 'org.mod4j.org.eclipse.xtext', 'log4j', '1.2.15' )
|
14
|
+
require_jar( 'junit', 'junit', '3.8.1' )
|
15
|
+
require_jar( 'org.xerial.snappy', 'snappy-java', '1.0.5' )
|
metadata
CHANGED
@@ -1,31 +1,51 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hermann
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Stan Campbell
|
8
7
|
- R. Tyler Croy
|
8
|
+
- Stan Campbell
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-10-10 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: concurrent-ruby
|
17
17
|
requirement: &id001 !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.7.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: *id001
|
25
|
-
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: zk
|
27
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.9.4
|
32
|
+
type: :runtime
|
33
|
+
prerelease: false
|
34
|
+
version_requirements: *id002
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: mini_portile
|
37
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.6.0
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: *id003
|
45
|
+
description: Ruby gem for talking to Kafka
|
26
46
|
email:
|
27
|
-
- stan.campbell3@gmail.com
|
28
47
|
- rtyler.croy@lookout.com
|
48
|
+
- stan.campbell3@gmail.com
|
29
49
|
executables: []
|
30
50
|
|
31
51
|
extensions:
|
@@ -40,11 +60,14 @@ files:
|
|
40
60
|
- ext/patches/librdkafka/0006-Update-some-headers-to-include-the-right-headers-to-.patch
|
41
61
|
- lib/hermann.rb
|
42
62
|
- lib/hermann/consumer.rb
|
63
|
+
- lib/hermann/discovery/zookeeper.rb
|
43
64
|
- lib/hermann/errors.rb
|
44
65
|
- lib/hermann/producer.rb
|
66
|
+
- lib/hermann/provider/java_producer.rb
|
45
67
|
- lib/hermann/result.rb
|
46
68
|
- lib/hermann/timeout.rb
|
47
69
|
- lib/hermann/version.rb
|
70
|
+
- lib/hermann_jars.rb
|
48
71
|
homepage: https://github.com/lookout/Hermann
|
49
72
|
licenses:
|
50
73
|
- MIT
|
@@ -58,19 +81,19 @@ require_paths:
|
|
58
81
|
- ext/hermann
|
59
82
|
required_ruby_version: !ruby/object:Gem::Requirement
|
60
83
|
requirements:
|
61
|
-
- &
|
84
|
+
- &id004
|
62
85
|
- ">="
|
63
86
|
- !ruby/object:Gem::Version
|
64
87
|
version: "0"
|
65
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
89
|
requirements:
|
67
|
-
- *
|
90
|
+
- *id004
|
68
91
|
requirements: []
|
69
92
|
|
70
93
|
rubyforge_project:
|
71
94
|
rubygems_version: 2.4.1
|
72
95
|
signing_key:
|
73
96
|
specification_version: 3
|
74
|
-
summary: A Kafka consumer/producer gem
|
97
|
+
summary: A Kafka consumer/producer gem supporting both MRI and JRuby
|
75
98
|
test_files: []
|
76
99
|
|