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 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