hermann 0.16.0 → 0.17.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: 8194f73012572376c8cd14ae68042da11fc79dfc
4
- data.tar.gz: 355dacd9317c634b430e4a7f32216aaccf07a308
3
+ metadata.gz: b08abedfd6c15b1c7c1aa5dfe66315501c212512
4
+ data.tar.gz: 3bf7306d482a260fd73004e4d8087cd5f3a1f063
5
5
  SHA512:
6
- metadata.gz: a1d4dd0e592433519e086d889b4362ff1e69f805f121517812bffd4b67ea1a77fb1d941fe0e017968ad791fe23506371831070a905259600f7154f8adca2cd7b
7
- data.tar.gz: db0b9f012f34e31c23268b4a93cbf40ea38a2b8239c3fe4fb7ca140d339259adffec0aa31f6098466ed57e107149c537ed43630694c6cea852c4048512266db9
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
- r.rspec_opts = '--tag ~type:integration'
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
- task :default => [:clean, :build, :spec]
40
+
41
+ if RUBY_PLATFORM == 'java'
42
+ task :default => [:clean, :spec]
43
+ else
44
+ task :default => [:clean, :build, :spec]
45
+ end
33
46
 
@@ -1,5 +1,8 @@
1
1
  require 'hermann'
2
- require 'hermann_lib'
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
- @internal = Hermann::Lib::Consumer.new(topic, brokers, partition)
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
@@ -1,6 +1,12 @@
1
1
  require 'hermann'
2
2
  require 'hermann/result'
3
- require 'hermann_lib'
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
- @internal = Hermann::Lib::Producer.new(topic, brokers)
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
- @internal.push_single(value, result)
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
@@ -1,3 +1,3 @@
1
1
  module Hermann
2
- VERSION = '0.16.0'
2
+ VERSION = '0.17.0'
3
3
  end
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
@@ -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.16.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-09-12 00:00:00 Z
13
+ date: 2014-10-10 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: mini_portile
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.6.0
21
+ version: 0.7.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: *id001
25
- description: Ruby gem wrapper for librdkafka
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
- - &id002
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
- - *id002
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 based on the librdkafka C library.
97
+ summary: A Kafka consumer/producer gem supporting both MRI and JRuby
75
98
  test_files: []
76
99