kafkat 0.0.10 → 0.0.11
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 +8 -8
 - data/.gitignore +1 -0
 - data/.rspec +2 -0
 - data/.simplecov +5 -0
 - data/.travis.yml +10 -0
 - data/Gemfile.lock +49 -12
 - data/README.md +3 -0
 - data/Rakefile +22 -5
 - data/_kafkat +21 -0
 - data/kafkat.gemspec +6 -0
 - data/lib/kafkat/command.rb +1 -0
 - data/lib/kafkat/command/drain.rb +94 -0
 - data/lib/kafkat/command/reassign.rb +1 -15
 - data/lib/kafkat/utility.rb +1 -0
 - data/lib/kafkat/utility/command_io.rb +21 -0
 - data/lib/kafkat/version.rb +1 -1
 - data/spec/factories/topic.rb +39 -0
 - data/spec/lib/kafkat/command/drain_spec.rb +59 -0
 - data/spec/spec_helper.rb +102 -0
 - metadata +85 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,15 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            !binary "U0hBMQ==":
         
     | 
| 
       3 
3 
     | 
    
         
             
              metadata.gz: !binary |-
         
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
      
 4 
     | 
    
         
            +
                NjhlMGY5MzIyYWFhZjdlZmE3YjlmM2M3MTc3MGU0MjQyYzQ2YjA5Zg==
         
     | 
| 
       5 
5 
     | 
    
         
             
              data.tar.gz: !binary |-
         
     | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
      
 6 
     | 
    
         
            +
                NDNlMjdjNDAxMjc4NTcyZDE2YzliNjI5OTBkNmJkMDA2OGM3Yjc0Zg==
         
     | 
| 
       7 
7 
     | 
    
         
             
            SHA512:
         
     | 
| 
       8 
8 
     | 
    
         
             
              metadata.gz: !binary |-
         
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
      
 9 
     | 
    
         
            +
                MDdkOWI2ZjBhNjU2ZWM3NmI5YTMwNTFjYTA3MjQ5NjJiNDVjOTFiMGRkMDMw
         
     | 
| 
      
 10 
     | 
    
         
            +
                ZmNkNThiNGJhYzYyNjIwYzczOTY0MjNhY2ZlYzA1MTQ2Y2Y4YTQxZDcwNTVm
         
     | 
| 
      
 11 
     | 
    
         
            +
                NWU4YjA0NGYzMDQ1Mjc3ZjBiMGUxMTllM2U0N2QwMDdkODYzOGQ=
         
     | 
| 
       12 
12 
     | 
    
         
             
              data.tar.gz: !binary |-
         
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
      
 13 
     | 
    
         
            +
                MzU2ODcyZWFmY2VjMmFiM2NkMDMxNDRjNmQ4NGU5Y2JhOTE5MDczMzYzZGFj
         
     | 
| 
      
 14 
     | 
    
         
            +
                MjhmOGE5MjVjNzViZWM3ZDJjMTkzZmZhZGYxMjI1Y2Q1NWEzMDU3ODc5MWUy
         
     | 
| 
      
 15 
     | 
    
         
            +
                NzAyMTBlNmExN2E5M2U2MGM5YWZkY2FkNTkxZTAyMjY3NDE2ZTI=
         
     | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/.simplecov
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            PATH
         
     | 
| 
       2 
2 
     | 
    
         
             
              remote: .
         
     | 
| 
       3 
3 
     | 
    
         
             
              specs:
         
     | 
| 
       4 
     | 
    
         
            -
                kafkat (0.0. 
     | 
| 
      
 4 
     | 
    
         
            +
                kafkat (0.0.11)
         
     | 
| 
       5 
5 
     | 
    
         
             
                  colored (~> 1.2)
         
     | 
| 
       6 
6 
     | 
    
         
             
                  highline (~> 1.6, >= 1.6.21)
         
     | 
| 
       7 
7 
     | 
    
         
             
                  retryable (~> 1.3, >= 1.3.5)
         
     | 
| 
         @@ -11,22 +11,59 @@ PATH 
     | 
|
| 
       11 
11 
     | 
    
         
             
            GEM
         
     | 
| 
       12 
12 
     | 
    
         
             
              remote: https://rubygems.org/
         
     | 
| 
       13 
13 
     | 
    
         
             
              specs:
         
     | 
| 
      
 14 
     | 
    
         
            +
                activesupport (4.2.1)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  i18n (~> 0.7)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  json (~> 1.7, >= 1.7.7)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  minitest (~> 5.1)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  thread_safe (~> 0.3, >= 0.3.4)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  tzinfo (~> 1.1)
         
     | 
| 
       14 
20 
     | 
    
         
             
                colored (1.2)
         
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
       16 
     | 
    
         
            -
                 
     | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
       18 
     | 
    
         
            -
                   
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                 
     | 
| 
       21 
     | 
    
         
            -
                 
     | 
| 
       22 
     | 
    
         
            -
                 
     | 
| 
       23 
     | 
    
         
            -
                 
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
      
 21 
     | 
    
         
            +
                diff-lcs (1.2.5)
         
     | 
| 
      
 22 
     | 
    
         
            +
                docile (1.1.5)
         
     | 
| 
      
 23 
     | 
    
         
            +
                factory_girl (4.5.0)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  activesupport (>= 3.0.0)
         
     | 
| 
      
 25 
     | 
    
         
            +
                highline (1.7.2)
         
     | 
| 
      
 26 
     | 
    
         
            +
                i18n (0.7.0)
         
     | 
| 
      
 27 
     | 
    
         
            +
                json (1.8.3)
         
     | 
| 
      
 28 
     | 
    
         
            +
                minitest (5.7.0)
         
     | 
| 
      
 29 
     | 
    
         
            +
                multi_json (1.11.1)
         
     | 
| 
      
 30 
     | 
    
         
            +
                rake (10.4.2)
         
     | 
| 
      
 31 
     | 
    
         
            +
                retryable (1.3.6)
         
     | 
| 
      
 32 
     | 
    
         
            +
                rspec (3.2.0)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  rspec-core (~> 3.2.0)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  rspec-expectations (~> 3.2.0)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  rspec-mocks (~> 3.2.0)
         
     | 
| 
      
 36 
     | 
    
         
            +
                rspec-collection_matchers (1.1.2)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  rspec-expectations (>= 2.99.0.beta1)
         
     | 
| 
      
 38 
     | 
    
         
            +
                rspec-core (3.2.3)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  rspec-support (~> 3.2.0)
         
     | 
| 
      
 40 
     | 
    
         
            +
                rspec-expectations (3.2.1)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  rspec-support (~> 3.2.0)
         
     | 
| 
      
 43 
     | 
    
         
            +
                rspec-mocks (3.2.1)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  rspec-support (~> 3.2.0)
         
     | 
| 
      
 46 
     | 
    
         
            +
                rspec-support (3.2.2)
         
     | 
| 
      
 47 
     | 
    
         
            +
                simplecov (0.9.0)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  docile (~> 1.1.0)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  multi_json
         
     | 
| 
      
 50 
     | 
    
         
            +
                  simplecov-html (~> 0.8.0)
         
     | 
| 
      
 51 
     | 
    
         
            +
                simplecov-html (0.8.0)
         
     | 
| 
      
 52 
     | 
    
         
            +
                thread_safe (0.3.5)
         
     | 
| 
      
 53 
     | 
    
         
            +
                trollop (2.1.2)
         
     | 
| 
      
 54 
     | 
    
         
            +
                tzinfo (1.2.2)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  thread_safe (~> 0.1)
         
     | 
| 
      
 56 
     | 
    
         
            +
                zk (1.9.6)
         
     | 
| 
       25 
57 
     | 
    
         
             
                  zookeeper (~> 1.4.0)
         
     | 
| 
       26 
     | 
    
         
            -
                zookeeper (1.4. 
     | 
| 
      
 58 
     | 
    
         
            +
                zookeeper (1.4.11)
         
     | 
| 
       27 
59 
     | 
    
         | 
| 
       28 
60 
     | 
    
         
             
            PLATFORMS
         
     | 
| 
       29 
61 
     | 
    
         
             
              ruby
         
     | 
| 
       30 
62 
     | 
    
         | 
| 
       31 
63 
     | 
    
         
             
            DEPENDENCIES
         
     | 
| 
      
 64 
     | 
    
         
            +
              factory_girl (~> 4.5.0)
         
     | 
| 
       32 
65 
     | 
    
         
             
              kafkat!
         
     | 
| 
      
 66 
     | 
    
         
            +
              rake
         
     | 
| 
      
 67 
     | 
    
         
            +
              rspec (~> 3.2.0)
         
     | 
| 
      
 68 
     | 
    
         
            +
              rspec-collection_matchers (~> 1.1.0)
         
     | 
| 
      
 69 
     | 
    
         
            +
              simplecov
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            [](https://travis-ci.org/airbnb/kafkat)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            kafkat
         
     | 
| 
       2 
4 
     | 
    
         
             
            ======
         
     | 
| 
       3 
5 
     | 
    
         | 
| 
         @@ -52,6 +54,7 @@ Here's a list of supported commands: 
     | 
|
| 
       52 
54 
     | 
    
         
             
              set-replication-factor [topic] [--newrf <n>] [--brokers id[,id]]    Set the replication factor of
         
     | 
| 
       53 
55 
     | 
    
         
             
              shutdown <broker id>                                                Gracefully remove leaderships from a broker (requires JMX).
         
     | 
| 
       54 
56 
     | 
    
         
             
              topics                                                              Print all topics.
         
     | 
| 
      
 57 
     | 
    
         
            +
              drain <broker id> [--topic <t>] [--brokers <ids>]                   Reassign partitions from a specific broker to other brokers.
         
     | 
| 
       55 
58 
     | 
    
         | 
| 
       56 
59 
     | 
    
         
             
            ```
         
     | 
| 
       57 
60 
     | 
    
         | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,8 +1,25 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            require 'bundler/gem_tasks'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'rspec/core/rake_task'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rake/clean'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            CLEAN << 'reports'
         
     | 
| 
      
 7 
     | 
    
         
            +
            CLOBBER << FileList['kafkat*.gem']
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            desc 'Run all specs'
         
     | 
| 
      
 10 
     | 
    
         
            +
            RSpec::Core::RakeTask.new :spec do |t|
         
     | 
| 
      
 11 
     | 
    
         
            +
              t.pattern = ['spec/**/*_spec.rb']
         
     | 
| 
      
 12 
     | 
    
         
            +
              t.rspec_opts = %w{--order random --format documentation --color --format html --out reports/specs.html}
         
     | 
| 
      
 13 
     | 
    
         
            +
              t.rspec_opts << "--backtrace" if ENV['backtrace']
         
     | 
| 
      
 14 
     | 
    
         
            +
              t.verbose = true
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            desc 'Run all specs and generate spec and coverage reports'
         
     | 
| 
      
 19 
     | 
    
         
            +
            task :coverage do
         
     | 
| 
      
 20 
     | 
    
         
            +
              ENV['COVERAGE'] = 'true'
         
     | 
| 
      
 21 
     | 
    
         
            +
              Rake::Task['spec'].invoke
         
     | 
| 
       8 
22 
     | 
    
         
             
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            task :test => :spec
         
     | 
| 
      
 25 
     | 
    
         
            +
            task :default => :coverage
         
     | 
    
        data/_kafkat
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Run kafkat from source, specifically for testing stuff without doing a rake install.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 6 
     | 
    
         
            +
            $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') << File.join(File.dirname(__FILE__), 'addon')
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require 'kafkat/version'
         
     | 
| 
      
 9 
     | 
    
         
            +
            spec = Gem::Specification.load(File.join(File.dirname(__FILE__), 'kafkat.gemspec'))
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # To avoid a warning about the version_requirements deprecation, we use this method inline.
         
     | 
| 
      
 12 
     | 
    
         
            +
            def version_required(gem_def)
         
     | 
| 
      
 13 
     | 
    
         
            +
              return Gem::Dependency.instance_methods.map(&:to_sym).include?(:requirement) ? gem_def.requirement : gem_def.version_requirements
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
      
 15 
     | 
    
         
            +
            spec.dependencies.each do |dep|
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem dep.name, version_required(dep) if dep.type == :runtime
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
            Gem.loaded_specs['kafkat'] = spec # Prevents RubyGem from loading files from installed kafkat gems
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            require 'kafkat'
         
     | 
| 
      
 21 
     | 
    
         
            +
            Kafkat::CLI.run!
         
     | 
    
        data/kafkat.gemspec
    CHANGED
    
    | 
         @@ -23,4 +23,10 @@ Gem::Specification.new do |s| 
     | 
|
| 
       23 
23 
     | 
    
         
             
              s.add_runtime_dependency 'highline', '~> 1.6', '>= 1.6.21'
         
     | 
| 
       24 
24 
     | 
    
         
             
              s.add_runtime_dependency 'retryable', '~> 1.3', '>= 1.3.5'
         
     | 
| 
       25 
25 
     | 
    
         
             
              s.add_runtime_dependency 'colored', '~> 1.2'
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              s.add_development_dependency 'rake'
         
     | 
| 
      
 28 
     | 
    
         
            +
              s.add_development_dependency 'simplecov'
         
     | 
| 
      
 29 
     | 
    
         
            +
              s.add_development_dependency 'rspec', '~> 3.2.0'
         
     | 
| 
      
 30 
     | 
    
         
            +
              s.add_development_dependency 'rspec-collection_matchers', '~> 1.1.0'
         
     | 
| 
      
 31 
     | 
    
         
            +
              s.add_development_dependency 'factory_girl', '~> 4.5.0'
         
     | 
| 
       26 
32 
     | 
    
         
             
            end
         
     | 
    
        data/lib/kafkat/command.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kafkat
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Command
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Drain < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  register_as 'drain'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  usage 'drain <broker id> [--topic <t>] [--brokers <ids>]',
         
     | 
| 
      
 7 
     | 
    
         
            +
                        'Reassign partitions from a specific broker to destination brokers.'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  # For each partition (of speicified topic) on the source broker, the command is to
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # assign the partition to one of the destination brokers that does not already have
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # this partition, along with existing brokers to achieve minimal movement of data.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # To help distribute data evenly, if there are more than one destination brokers
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # meet the requirement, the command will always choose the brokers with the lowest
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # number of partitions of the involving topic.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # In order to find out the broker with lowest number of partitions, the command maintain
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # a hash table with broker id as key and number of partitions as value. The hash table
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # will be updated along with assignment.
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 20 
     | 
    
         
            +
                    source_broker = ARGV[0] && ARGV.shift.to_i
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if source_broker.nil?
         
     | 
| 
      
 22 
     | 
    
         
            +
                      puts "You must specify a broker ID."
         
     | 
| 
      
 23 
     | 
    
         
            +
                      exit 1
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    opts = Trollop.options do
         
     | 
| 
      
 27 
     | 
    
         
            +
                      opt :brokers, "destination broker IDs", type: :string
         
     | 
| 
      
 28 
     | 
    
         
            +
                      opt :topic,   "topic name to reassign", type: :string
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    topic_name = opts[:topic]
         
     | 
| 
      
 32 
     | 
    
         
            +
                    topics = topic_name && zookeeper.get_topics([topic_name])
         
     | 
| 
      
 33 
     | 
    
         
            +
                    topics ||= zookeeper.get_topics
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    destination_brokers = opts[:brokers] && opts[:brokers].split(',').map(&:to_i)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    destination_brokers ||= zookeeper.get_brokers.values.map(&:id)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    destination_brokers.delete(source_broker)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    active_brokers = zookeeper.get_brokers.values.map(&:id)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    unless (inactive_brokers = destination_brokers - active_brokers).empty?
         
     | 
| 
      
 42 
     | 
    
         
            +
                      print "ERROR: Broker #{inactive_brokers} are not currently active.\n"
         
     | 
| 
      
 43 
     | 
    
         
            +
                      exit 1
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    assignments =
         
     | 
| 
      
 47 
     | 
    
         
            +
                      generate_assignments(source_broker, topics, destination_brokers)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    prompt_and_execute_assignments(assignments)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def generate_assignments(source_broker, topics, destination_brokers)
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    assignments = []
         
     | 
| 
      
 54 
     | 
    
         
            +
                    topics.each do |_, t|
         
     | 
| 
      
 55 
     | 
    
         
            +
                      partitions_by_broker = build_partitions_by_broker(t, destination_brokers)
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                      t.partitions.each do |p|
         
     | 
| 
      
 58 
     | 
    
         
            +
                        if p.replicas.include? source_broker
         
     | 
| 
      
 59 
     | 
    
         
            +
                          replicas = p.replicas - [source_broker]
         
     | 
| 
      
 60 
     | 
    
         
            +
                          potential_broker_ids = destination_brokers - replicas
         
     | 
| 
      
 61 
     | 
    
         
            +
                          if potential_broker_ids.empty?
         
     | 
| 
      
 62 
     | 
    
         
            +
                            print "ERROR: Not enough destination brokers to reassign topic \"#{t.name}\".\n"
         
     | 
| 
      
 63 
     | 
    
         
            +
                            exit 1
         
     | 
| 
      
 64 
     | 
    
         
            +
                          end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                          num_partitions_on_potential_broker =
         
     | 
| 
      
 67 
     | 
    
         
            +
                            partitions_by_broker.select { |id, _| potential_broker_ids.include? id }
         
     | 
| 
      
 68 
     | 
    
         
            +
                          assigned_broker_id = num_partitions_on_potential_broker.min_by{ |id, num| num }[0]
         
     | 
| 
      
 69 
     | 
    
         
            +
                          replicas << assigned_broker_id
         
     | 
| 
      
 70 
     | 
    
         
            +
                          partitions_by_broker[assigned_broker_id] += 1
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                          assignments << Assignment.new(t.name, p.id, replicas)
         
     | 
| 
      
 73 
     | 
    
         
            +
                        end
         
     | 
| 
      
 74 
     | 
    
         
            +
                      end
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    assignments
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  # Build a hash map from broker id to number of partitions on it to facilitate
         
     | 
| 
      
 81 
     | 
    
         
            +
                  # finding the broker with lowest number of partitions to help balance brokers.
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def build_partitions_by_broker(topic, destination_brokers)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    partitions_by_broker = Hash.new(0)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    destination_brokers.each { |id| partitions_by_broker[id] = 0 }
         
     | 
| 
      
 85 
     | 
    
         
            +
                    topic.partitions.each do |p|
         
     | 
| 
      
 86 
     | 
    
         
            +
                      p.replicas.each do |r|
         
     | 
| 
      
 87 
     | 
    
         
            +
                        partitions_by_broker[r] += 1
         
     | 
| 
      
 88 
     | 
    
         
            +
                      end
         
     | 
| 
      
 89 
     | 
    
         
            +
                    end
         
     | 
| 
      
 90 
     | 
    
         
            +
                    partitions_by_broker
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -68,21 +68,7 @@ module Kafkat 
     | 
|
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                    # ****************
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                     
     | 
| 
       72 
     | 
    
         
            -
                    print_assignment_header
         
     | 
| 
       73 
     | 
    
         
            -
                    assignments.each { |a| print_assignment(a) }
         
     | 
| 
       74 
     | 
    
         
            -
                    print "\n"
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                    return unless agree("Proceed (y/n)?")
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                    result = nil
         
     | 
| 
       79 
     | 
    
         
            -
                    begin
         
     | 
| 
       80 
     | 
    
         
            -
                      print "\nBeginning.\n"
         
     | 
| 
       81 
     | 
    
         
            -
                      result = admin.reassign!(assignments)
         
     | 
| 
       82 
     | 
    
         
            -
                      print "Started.\n"
         
     | 
| 
       83 
     | 
    
         
            -
                    rescue Interface::Admin::ExecutionFailedError
         
     | 
| 
       84 
     | 
    
         
            -
                      print result
         
     | 
| 
       85 
     | 
    
         
            -
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                    prompt_and_execute_assignments(assignments)
         
     | 
| 
       86 
72 
     | 
    
         
             
                  end
         
     | 
| 
       87 
73 
     | 
    
         
             
                end
         
     | 
| 
       88 
74 
     | 
    
         
             
              end
         
     | 
    
        data/lib/kafkat/utility.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kafkat
         
     | 
| 
      
 2 
     | 
    
         
            +
              module CommandIO
         
     | 
| 
      
 3 
     | 
    
         
            +
                def prompt_and_execute_assignments(assignments)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  print "This operation executes the following assignments:\n\n"
         
     | 
| 
      
 5 
     | 
    
         
            +
                  print_assignment_header
         
     | 
| 
      
 6 
     | 
    
         
            +
                  assignments.each { |a| print_assignment(a) }
         
     | 
| 
      
 7 
     | 
    
         
            +
                  print "\n"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  return unless agree("Proceed (y/n)?")
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  result = nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 13 
     | 
    
         
            +
                    print "\nBeginning.\n"
         
     | 
| 
      
 14 
     | 
    
         
            +
                    result = admin.reassign!(assignments)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    print "Started.\n"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  rescue Interface::Admin::ExecutionFailedError
         
     | 
| 
      
 17 
     | 
    
         
            +
                    print result
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/kafkat/version.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kafkat
         
     | 
| 
      
 2 
     | 
    
         
            +
              FactoryGirl.define do
         
     | 
| 
      
 3 
     | 
    
         
            +
                factory :topic, class:Topic do
         
     | 
| 
      
 4 
     | 
    
         
            +
                  name "topic_name"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  factory :topic_with_one_empty_broker do
         
     | 
| 
      
 7 
     | 
    
         
            +
                    partitions {[Partition.new(name, 0, [0], 0, 0),
         
     | 
| 
      
 8 
     | 
    
         
            +
                                 Partition.new(name, 1, [1], 1, 1),
         
     | 
| 
      
 9 
     | 
    
         
            +
                                 Partition.new(name, 2, [0], 0, 0),
         
     | 
| 
      
 10 
     | 
    
         
            +
                                 Partition.new(name, 3, [0], 0, 0),
         
     | 
| 
      
 11 
     | 
    
         
            +
                                 Partition.new(name, 4, [1], 1, 1)]}
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  factory :topic_rep_factor_one do
         
     | 
| 
      
 15 
     | 
    
         
            +
                    partitions {[Partition.new(name, 0, [0], 0, 0),
         
     | 
| 
      
 16 
     | 
    
         
            +
                                 Partition.new(name, 1, [1], 1, 1),
         
     | 
| 
      
 17 
     | 
    
         
            +
                                 Partition.new(name, 2, [2], 2, 2),
         
     | 
| 
      
 18 
     | 
    
         
            +
                                 Partition.new(name, 3, [0], 0, 0),
         
     | 
| 
      
 19 
     | 
    
         
            +
                                 Partition.new(name, 4, [1], 1, 1)]}
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  factory :topic_rep_factor_two do
         
     | 
| 
      
 23 
     | 
    
         
            +
                    partitions {[Partition.new(name, 0, [0, 1], 0, 0),
         
     | 
| 
      
 24 
     | 
    
         
            +
                                 Partition.new(name, 1, [0, 2], 2, 2),
         
     | 
| 
      
 25 
     | 
    
         
            +
                                 Partition.new(name, 2, [1, 2], 1, 1),
         
     | 
| 
      
 26 
     | 
    
         
            +
                                 Partition.new(name, 3, [0, 1], 0, 0),
         
     | 
| 
      
 27 
     | 
    
         
            +
                                 Partition.new(name, 4, [0, 2], 2, 2)]}
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  factory :topic_rep_factor_three do
         
     | 
| 
      
 31 
     | 
    
         
            +
                    partitions {[Partition.new(name, 0, [0, 1, 2], 0, 0),
         
     | 
| 
      
 32 
     | 
    
         
            +
                                 Partition.new(name, 1, [0, 1, 2], 1, 1),
         
     | 
| 
      
 33 
     | 
    
         
            +
                                 Partition.new(name, 2, [0, 1, 2], 2, 2),
         
     | 
| 
      
 34 
     | 
    
         
            +
                                 Partition.new(name, 3, [0, 1, 2], 0, 0),
         
     | 
| 
      
 35 
     | 
    
         
            +
                                 Partition.new(name, 4, [0, 1, 2], 1, 1)]}
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Kafkat
         
     | 
| 
      
 4 
     | 
    
         
            +
              RSpec.describe Command::Drain do
         
     | 
| 
      
 5 
     | 
    
         
            +
                let(:drain) { Command::Drain.new({}) }
         
     | 
| 
      
 6 
     | 
    
         
            +
                let(:broker_id) { 0 }
         
     | 
| 
      
 7 
     | 
    
         
            +
                let(:destination_broker_ids) { [1, 2] }
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                context 'three nodes with replication factor 1' do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  let(:topic_rep_factor_one) { FactoryGirl.build(:topic_rep_factor_one) }
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  it 'should put replicas to broker with lowest number of replicas' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                    assignments = drain.generate_assignments(broker_id,
         
     | 
| 
      
 14 
     | 
    
         
            +
                                                             {"topic_name" => topic_rep_factor_one},
         
     | 
| 
      
 15 
     | 
    
         
            +
                                                             destination_broker_ids)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    expect(assignments).to have_exactly(2).Partition
         
     | 
| 
      
 17 
     | 
    
         
            +
                    expect(assignments[0].replicas).to eq([2])
         
     | 
| 
      
 18 
     | 
    
         
            +
                    expect(assignments[1].replicas).to eq([1])
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                context 'three nodes with replication factor 2' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  let(:topic_rep_factor_two) { FactoryGirl.build(:topic_rep_factor_two) }
         
     | 
| 
      
 24 
     | 
    
         
            +
                  it 'should put replicas to broker with lowest number of replicas' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                    assignments = drain.generate_assignments(broker_id,
         
     | 
| 
      
 26 
     | 
    
         
            +
                                                             {"topic_name" => topic_rep_factor_two},
         
     | 
| 
      
 27 
     | 
    
         
            +
                                                             destination_broker_ids)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    expect(assignments).to have_exactly(4).Partition
         
     | 
| 
      
 29 
     | 
    
         
            +
                    expect(assignments[0].replicas).to eq([1, 2])
         
     | 
| 
      
 30 
     | 
    
         
            +
                    expect(assignments[1].replicas).to eq([2, 1])
         
     | 
| 
      
 31 
     | 
    
         
            +
                    expect(assignments[2].replicas).to eq([1, 2])
         
     | 
| 
      
 32 
     | 
    
         
            +
                    expect(assignments[3].replicas).to eq([2, 1])
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                context 'not enough brokers to keep all replicas' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  let(:topic_rep_factor_three) { FactoryGirl.build(:topic_rep_factor_three) }
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  it 'should raise SystemExit' do
         
     | 
| 
      
 40 
     | 
    
         
            +
                    expect do
         
     | 
| 
      
 41 
     | 
    
         
            +
                      drain.generate_assignments(broker_id,
         
     | 
| 
      
 42 
     | 
    
         
            +
                                                 {"topic_name" => topic_rep_factor_three},
         
     | 
| 
      
 43 
     | 
    
         
            +
                                                 destination_broker_ids)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end.to raise_error(SystemExit)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                context 'one destination broker is empty' do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  let(:topic_with_one_empty_broker) { FactoryGirl.build(:topic_with_one_empty_broker) }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  it 'should not raise exception' do
         
     | 
| 
      
 51 
     | 
    
         
            +
                    expect do
         
     | 
| 
      
 52 
     | 
    
         
            +
                      drain.generate_assignments(broker_id,
         
     | 
| 
      
 53 
     | 
    
         
            +
                                                 {"topic_name" => topic_with_one_empty_broker},
         
     | 
| 
      
 54 
     | 
    
         
            +
                                                 destination_broker_ids)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end.not_to raise_error
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This file was generated by the `rspec --init` command. Conventionally, all
         
     | 
| 
      
 2 
     | 
    
         
            +
            # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # The generated `.rspec` file contains `--require spec_helper` which will cause
         
     | 
| 
      
 4 
     | 
    
         
            +
            # this file to always be loaded, without a need to explicitly require it in any
         
     | 
| 
      
 5 
     | 
    
         
            +
            # files.
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Given that it is always loaded, you are encouraged to keep this file as
         
     | 
| 
      
 8 
     | 
    
         
            +
            # light-weight as possible. Requiring heavyweight dependencies from this file
         
     | 
| 
      
 9 
     | 
    
         
            +
            # will add to the boot time of your test suite on EVERY test run, even for an
         
     | 
| 
      
 10 
     | 
    
         
            +
            # individual file that may not need all of that loaded. Instead, consider making
         
     | 
| 
      
 11 
     | 
    
         
            +
            # a separate helper file that requires the additional dependencies and performs
         
     | 
| 
      
 12 
     | 
    
         
            +
            # the additional setup, and require it from the spec files that actually need
         
     | 
| 
      
 13 
     | 
    
         
            +
            # it.
         
     | 
| 
      
 14 
     | 
    
         
            +
            #
         
     | 
| 
      
 15 
     | 
    
         
            +
            # The `.rspec` file also contains a few flags that are not defaults but that
         
     | 
| 
      
 16 
     | 
    
         
            +
            # users commonly want.
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
         
     | 
| 
      
 19 
     | 
    
         
            +
            if ENV['COVERAGE']
         
     | 
| 
      
 20 
     | 
    
         
            +
                require 'simplecov'
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
            require 'kafkat'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'factory_girl'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'rspec/collection_matchers'
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            require_relative '../spec/factories/topic'
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 29 
     | 
    
         
            +
              # rspec-expectations config goes here. You can use an alternate
         
     | 
| 
      
 30 
     | 
    
         
            +
              # assertion/expectation library such as wrong or the stdlib/minitest
         
     | 
| 
      
 31 
     | 
    
         
            +
              # assertions if you prefer.
         
     | 
| 
      
 32 
     | 
    
         
            +
              config.expect_with :rspec do |expectations|
         
     | 
| 
      
 33 
     | 
    
         
            +
                # This option will default to `true` in RSpec 4. It makes the `description`
         
     | 
| 
      
 34 
     | 
    
         
            +
                # and `failure_message` of custom matchers include text for helper methods
         
     | 
| 
      
 35 
     | 
    
         
            +
                # defined using `chain`, e.g.:
         
     | 
| 
      
 36 
     | 
    
         
            +
                #     be_bigger_than(2).and_smaller_than(4).description
         
     | 
| 
      
 37 
     | 
    
         
            +
                #     # => "be bigger than 2 and smaller than 4"
         
     | 
| 
      
 38 
     | 
    
         
            +
                # ...rather than:
         
     | 
| 
      
 39 
     | 
    
         
            +
                #     # => "be bigger than 2"
         
     | 
| 
      
 40 
     | 
    
         
            +
                expectations.include_chain_clauses_in_custom_matcher_descriptions = true
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              # rspec-mocks config goes here. You can use an alternate test double
         
     | 
| 
      
 44 
     | 
    
         
            +
              # library (such as bogus or mocha) by changing the `mock_with` option here.
         
     | 
| 
      
 45 
     | 
    
         
            +
              config.mock_with :rspec do |mocks|
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Prevents you from mocking or stubbing a method that does not exist on
         
     | 
| 
      
 47 
     | 
    
         
            +
                # a real object. This is generally recommended, and will default to
         
     | 
| 
      
 48 
     | 
    
         
            +
                # `true` in RSpec 4.
         
     | 
| 
      
 49 
     | 
    
         
            +
                mocks.verify_partial_doubles = true
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              config.include FactoryGirl::Syntax::Methods
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            # The settings below are suggested to provide a good initial experience
         
     | 
| 
      
 55 
     | 
    
         
            +
            # with RSpec, but feel free to customize to your heart's content.
         
     | 
| 
      
 56 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 57 
     | 
    
         
            +
              # These two settings work together to allow you to limit a spec run
         
     | 
| 
      
 58 
     | 
    
         
            +
              # to individual examples or groups you care about by tagging them with
         
     | 
| 
      
 59 
     | 
    
         
            +
              # `:focus` metadata. When nothing is tagged with `:focus`, all examples
         
     | 
| 
      
 60 
     | 
    
         
            +
              # get run.
         
     | 
| 
      
 61 
     | 
    
         
            +
              config.filter_run :focus
         
     | 
| 
      
 62 
     | 
    
         
            +
              config.run_all_when_everything_filtered = true
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              # Limits the available syntax to the non-monkey patched syntax that is
         
     | 
| 
      
 65 
     | 
    
         
            +
              # recommended. For more details, see:
         
     | 
| 
      
 66 
     | 
    
         
            +
              #   - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
         
     | 
| 
      
 67 
     | 
    
         
            +
              #   - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
         
     | 
| 
      
 68 
     | 
    
         
            +
              #   - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
         
     | 
| 
      
 69 
     | 
    
         
            +
              config.disable_monkey_patching!
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              # This setting enables warnings. It's recommended, but in some cases may
         
     | 
| 
      
 72 
     | 
    
         
            +
              # be too noisy due to issues in dependencies.
         
     | 
| 
      
 73 
     | 
    
         
            +
              config.warnings = true
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              # Many RSpec users commonly either run the entire suite or an individual
         
     | 
| 
      
 76 
     | 
    
         
            +
              # file, and it's useful to allow more verbose output when running an
         
     | 
| 
      
 77 
     | 
    
         
            +
              # individual spec file.
         
     | 
| 
      
 78 
     | 
    
         
            +
              if config.files_to_run.one?
         
     | 
| 
      
 79 
     | 
    
         
            +
                # Use the documentation formatter for detailed output,
         
     | 
| 
      
 80 
     | 
    
         
            +
                # unless a formatter has already been configured
         
     | 
| 
      
 81 
     | 
    
         
            +
                # (e.g. via a command-line flag).
         
     | 
| 
      
 82 
     | 
    
         
            +
                config.default_formatter = 'doc'
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              # Print the 10 slowest examples and example groups at the
         
     | 
| 
      
 86 
     | 
    
         
            +
              # end of the spec run, to help surface which specs are running
         
     | 
| 
      
 87 
     | 
    
         
            +
              # particularly slow.
         
     | 
| 
      
 88 
     | 
    
         
            +
              config.profile_examples = 10
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              # Run specs in random order to surface order dependencies. If you find an
         
     | 
| 
      
 91 
     | 
    
         
            +
              # order dependency and want to debug it, you can fix the order by providing
         
     | 
| 
      
 92 
     | 
    
         
            +
              # the seed, which is printed after each run.
         
     | 
| 
      
 93 
     | 
    
         
            +
              #     --seed 1234
         
     | 
| 
      
 94 
     | 
    
         
            +
              config.order = :random
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              # Seed global randomization in this process using the `--seed` CLI option.
         
     | 
| 
      
 97 
     | 
    
         
            +
              # Setting this allows you to use `--seed` to deterministically reproduce
         
     | 
| 
      
 98 
     | 
    
         
            +
              # test failures related to randomization by passing the same `--seed` value
         
     | 
| 
      
 99 
     | 
    
         
            +
              # as the one that triggered the failure.
         
     | 
| 
      
 100 
     | 
    
         
            +
              Kernel.srand config.seed
         
     | 
| 
      
 101 
     | 
    
         
            +
            =end
         
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: kafkat
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.11
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Nelson Gauthier
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2016-01-26 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: zk
         
     | 
| 
         @@ -98,6 +98,76 @@ dependencies: 
     | 
|
| 
       98 
98 
     | 
    
         
             
                - - ~>
         
     | 
| 
       99 
99 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       100 
100 
     | 
    
         
             
                    version: '1.2'
         
     | 
| 
      
 101 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 102 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 103 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 104 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 105 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 106 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 107 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 108 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 109 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 110 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 111 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 112 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 113 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 114 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 115 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 116 
     | 
    
         
            +
              name: simplecov
         
     | 
| 
      
 117 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 118 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 119 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 120 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 121 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 122 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 123 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 124 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 125 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 126 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 127 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 128 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 129 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 130 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 131 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 132 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 133 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 134 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 135 
     | 
    
         
            +
                    version: 3.2.0
         
     | 
| 
      
 136 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 137 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 138 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 139 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 140 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 141 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 142 
     | 
    
         
            +
                    version: 3.2.0
         
     | 
| 
      
 143 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 144 
     | 
    
         
            +
              name: rspec-collection_matchers
         
     | 
| 
      
 145 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 146 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 147 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 148 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 149 
     | 
    
         
            +
                    version: 1.1.0
         
     | 
| 
      
 150 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 151 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 152 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 153 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 154 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 155 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 156 
     | 
    
         
            +
                    version: 1.1.0
         
     | 
| 
      
 157 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 158 
     | 
    
         
            +
              name: factory_girl
         
     | 
| 
      
 159 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 160 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 161 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 162 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 163 
     | 
    
         
            +
                    version: 4.5.0
         
     | 
| 
      
 164 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 165 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 166 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 167 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 168 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 169 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 170 
     | 
    
         
            +
                    version: 4.5.0
         
     | 
| 
       101 
171 
     | 
    
         
             
            description: Simplified command-line administration for Kafka brokers
         
     | 
| 
       102 
172 
     | 
    
         
             
            email:
         
     | 
| 
       103 
173 
     | 
    
         
             
            - nelson@airbnb.com
         
     | 
| 
         @@ -107,11 +177,15 @@ extensions: [] 
     | 
|
| 
       107 
177 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       108 
178 
     | 
    
         
             
            files:
         
     | 
| 
       109 
179 
     | 
    
         
             
            - .gitignore
         
     | 
| 
      
 180 
     | 
    
         
            +
            - .rspec
         
     | 
| 
      
 181 
     | 
    
         
            +
            - .simplecov
         
     | 
| 
      
 182 
     | 
    
         
            +
            - .travis.yml
         
     | 
| 
       110 
183 
     | 
    
         
             
            - Gemfile
         
     | 
| 
       111 
184 
     | 
    
         
             
            - Gemfile.lock
         
     | 
| 
       112 
185 
     | 
    
         
             
            - LICENSE.txt
         
     | 
| 
       113 
186 
     | 
    
         
             
            - README.md
         
     | 
| 
       114 
187 
     | 
    
         
             
            - Rakefile
         
     | 
| 
      
 188 
     | 
    
         
            +
            - _kafkat
         
     | 
| 
       115 
189 
     | 
    
         
             
            - bin/kafkat
         
     | 
| 
       116 
190 
     | 
    
         
             
            - kafkat.gemspec
         
     | 
| 
       117 
191 
     | 
    
         
             
            - lib/kafkat.rb
         
     | 
| 
         @@ -125,6 +199,7 @@ files: 
     | 
|
| 
       125 
199 
     | 
    
         
             
            - lib/kafkat/command/brokers.rb
         
     | 
| 
       126 
200 
     | 
    
         
             
            - lib/kafkat/command/clean-indexes.rb
         
     | 
| 
       127 
201 
     | 
    
         
             
            - lib/kafkat/command/controller.rb
         
     | 
| 
      
 202 
     | 
    
         
            +
            - lib/kafkat/command/drain.rb
         
     | 
| 
       128 
203 
     | 
    
         
             
            - lib/kafkat/command/elect-leaders.rb
         
     | 
| 
       129 
204 
     | 
    
         
             
            - lib/kafkat/command/partitions.rb
         
     | 
| 
       130 
205 
     | 
    
         
             
            - lib/kafkat/command/reassign.rb
         
     | 
| 
         @@ -138,8 +213,12 @@ files: 
     | 
|
| 
       138 
213 
     | 
    
         
             
            - lib/kafkat/interface/kafka_logs.rb
         
     | 
| 
       139 
214 
     | 
    
         
             
            - lib/kafkat/interface/zookeeper.rb
         
     | 
| 
       140 
215 
     | 
    
         
             
            - lib/kafkat/utility.rb
         
     | 
| 
      
 216 
     | 
    
         
            +
            - lib/kafkat/utility/command_io.rb
         
     | 
| 
       141 
217 
     | 
    
         
             
            - lib/kafkat/utility/formatting.rb
         
     | 
| 
       142 
218 
     | 
    
         
             
            - lib/kafkat/version.rb
         
     | 
| 
      
 219 
     | 
    
         
            +
            - spec/factories/topic.rb
         
     | 
| 
      
 220 
     | 
    
         
            +
            - spec/lib/kafkat/command/drain_spec.rb
         
     | 
| 
      
 221 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
       143 
222 
     | 
    
         
             
            homepage: https://github.com/airbnb/kafkat
         
     | 
| 
       144 
223 
     | 
    
         
             
            licenses:
         
     | 
| 
       145 
224 
     | 
    
         
             
            - Apache-v2
         
     | 
| 
         @@ -164,4 +243,7 @@ rubygems_version: 2.4.1 
     | 
|
| 
       164 
243 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       165 
244 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       166 
245 
     | 
    
         
             
            summary: Simplified command-line administration for Kafka brokers
         
     | 
| 
       167 
     | 
    
         
            -
            test_files: 
     | 
| 
      
 246 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 247 
     | 
    
         
            +
            - spec/factories/topic.rb
         
     | 
| 
      
 248 
     | 
    
         
            +
            - spec/lib/kafkat/command/drain_spec.rb
         
     | 
| 
      
 249 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     |