fluent-plugin-groonga 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/doc/text/news.md +15 -0
- data/fluent-plugin-groonga.gemspec +1 -1
- data/lib/fluent/plugin/in_groonga.rb +124 -9
- data/test/test_input.rb +9 -2
- data/test/test_output.rb +12 -15
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 5947627fa2f465811a846d3cd3ced7a8ac367674
         | 
| 4 | 
            +
              data.tar.gz: cc846ea63eca88bdadbb9d5dceab7b806e36762d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 386b7122fc93b2bba7f8fdfea1648ce66b7ad4e20929ad1ea7ea7fae0fd731d6168e6aac8c18567af14cfb621bbe1b95fe8d9903f11e7e2a78aaf53db18bf6a3
         | 
| 7 | 
            +
              data.tar.gz: f56bf5c5848837eca8cc8de484c8493aad1467a3655594963670118ca3dfa14aa6fa326927f3e557fdb58175982beac9a39fda56f263ca852fa7ddb8bc4e2e8a
         | 
    
        data/doc/text/news.md
    CHANGED
    
    | @@ -2,6 +2,21 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            # News
         | 
| 4 4 |  | 
| 5 | 
            +
            ## 1.1.3: 2016-09-02
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ### Improvements
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * Supported Fluentd 0.14.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * Stopped to emit requests when real Groonga server returns error
         | 
| 12 | 
            +
              responses. `load` request and `object_remove` request are
         | 
| 13 | 
            +
              exceptions. They are always emitted if real Groonga server returns
         | 
| 14 | 
            +
              error responses. Because they may be effected when Groonga server
         | 
| 15 | 
            +
              returns error responses.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            * Updated the default emit target command list to reflect the recent
         | 
| 18 | 
            +
              Groonga command list.
         | 
| 19 | 
            +
             | 
| 5 20 | 
             
            ## 1.1.2: 2016-06-05
         | 
| 6 21 |  | 
| 7 22 | 
             
            ### Improvements
         | 
| @@ -17,7 +17,7 @@ | |
| 17 17 |  | 
| 18 18 | 
             
            Gem::Specification.new do |spec|
         | 
| 19 19 | 
             
              spec.name = "fluent-plugin-groonga"
         | 
| 20 | 
            -
              spec.version = "1.1. | 
| 20 | 
            +
              spec.version = "1.1.3"
         | 
| 21 21 | 
             
              spec.authors = ["Kouhei Sutou"]
         | 
| 22 22 | 
             
              spec.email = ["kou@clear-code.com"]
         | 
| 23 23 | 
             
              spec.summary = "Fluentd plugin to store data into Groonga and implement Groonga replication system."
         | 
| @@ -24,6 +24,7 @@ require "http_parser" | |
| 24 24 | 
             
            require "gqtp"
         | 
| 25 25 | 
             
            require "groonga/command/parser"
         | 
| 26 26 |  | 
| 27 | 
            +
            require "fluent/input"
         | 
| 27 28 | 
             
            require "fluent/process"
         | 
| 28 29 |  | 
| 29 30 | 
             
            module Fluent
         | 
| @@ -55,10 +56,12 @@ module Fluent | |
| 55 56 | 
             
                end
         | 
| 56 57 |  | 
| 57 58 | 
             
                def start
         | 
| 59 | 
            +
                  super
         | 
| 58 60 | 
             
                  @input.start
         | 
| 59 61 | 
             
                end
         | 
| 60 62 |  | 
| 61 63 | 
             
                def shutdown
         | 
| 64 | 
            +
                  super
         | 
| 62 65 | 
             
                  @input.shutdown
         | 
| 63 66 | 
             
                end
         | 
| 64 67 |  | 
| @@ -86,13 +89,29 @@ module Fluent | |
| 86 89 | 
             
                  config_param :real_host, :string
         | 
| 87 90 | 
             
                  config_param :real_port, :integer, :default => nil
         | 
| 88 91 | 
             
                  DEFAULT_EMIT_COMMANDS = [
         | 
| 89 | 
            -
                     | 
| 90 | 
            -
                     | 
| 92 | 
            +
                    "clearlock",
         | 
| 93 | 
            +
                    "column_copy",
         | 
| 94 | 
            +
                    "column_create",
         | 
| 95 | 
            +
                    "column_remove",
         | 
| 96 | 
            +
                    "column_rename",
         | 
| 97 | 
            +
                    "config_delete",
         | 
| 98 | 
            +
                    "config_set",
         | 
| 91 99 | 
             
                    "delete",
         | 
| 92 | 
            -
                     | 
| 100 | 
            +
                    "load",
         | 
| 101 | 
            +
                    "lock_acquire",
         | 
| 102 | 
            +
                    "lock_clear",
         | 
| 103 | 
            +
                    "lock_release",
         | 
| 104 | 
            +
                    "logical_table_remove",
         | 
| 105 | 
            +
                    "object_remove",
         | 
| 106 | 
            +
                    "plugin_register",
         | 
| 107 | 
            +
                    "plugin_unregister",
         | 
| 93 108 | 
             
                    "register",
         | 
| 109 | 
            +
                    "reindex",
         | 
| 110 | 
            +
                    "table_copy",
         | 
| 111 | 
            +
                    "table_create",
         | 
| 112 | 
            +
                    "table_remove",
         | 
| 113 | 
            +
                    "table_rename",
         | 
| 94 114 | 
             
                    "truncate",
         | 
| 95 | 
            -
                    "load",
         | 
| 96 115 | 
             
                  ]
         | 
| 97 116 | 
             
                  config_param :emit_commands, :default => DEFAULT_EMIT_COMMANDS do |value|
         | 
| 98 117 | 
             
                    commands = value.split(/\s*,\s*/)
         | 
| @@ -152,8 +171,9 @@ module Fluent | |
| 152 171 | 
             
                  end
         | 
| 153 172 |  | 
| 154 173 | 
             
                  def emit(command, params)
         | 
| 155 | 
            -
                     | 
| 156 | 
            -
                     | 
| 174 | 
            +
                    normalized_command = command.split(".")[0]
         | 
| 175 | 
            +
                    return unless emit_command?(normalized_command)
         | 
| 176 | 
            +
                    @input_plugin.router.emit("groonga.command.#{normalized_command}",
         | 
| 157 177 | 
             
                                              Engine.now,
         | 
| 158 178 | 
             
                                              params)
         | 
| 159 179 | 
             
                  end
         | 
| @@ -191,13 +211,17 @@ module Fluent | |
| 191 211 | 
             
                    end
         | 
| 192 212 |  | 
| 193 213 | 
             
                    def on_connect
         | 
| 194 | 
            -
                      @parser = HTTP::Parser.new(self)
         | 
| 195 214 | 
             
                      @repeater = @input.create_repeater(self)
         | 
| 215 | 
            +
                      @repeater.on_connect_failed do
         | 
| 216 | 
            +
                        close
         | 
| 217 | 
            +
                      end
         | 
| 218 | 
            +
                      @request_handler = RequestHandler.new(@input, @repeater)
         | 
| 219 | 
            +
                      @response_handler = ResponseHandler.new(self)
         | 
| 196 220 | 
             
                    end
         | 
| 197 221 |  | 
| 198 222 | 
             
                    def on_read(data)
         | 
| 199 223 | 
             
                      begin
         | 
| 200 | 
            -
                        @ | 
| 224 | 
            +
                        @request_handler << data
         | 
| 201 225 | 
             
                      rescue HTTP::Parser::Error
         | 
| 202 226 | 
             
                        $log.error("[input][groonga][error] " +
         | 
| 203 227 | 
             
                                   "failed to parse HTTP request:",
         | 
| @@ -207,8 +231,55 @@ module Fluent | |
| 207 231 | 
             
                      end
         | 
| 208 232 | 
             
                    end
         | 
| 209 233 |  | 
| 234 | 
            +
                    def write(data)
         | 
| 235 | 
            +
                      @response_handler << data
         | 
| 236 | 
            +
                      super
         | 
| 237 | 
            +
                    end
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                    def on_response_complete(response)
         | 
| 240 | 
            +
                      if need_emit?(response)
         | 
| 241 | 
            +
                        @input.emit(@request_handler.command,
         | 
| 242 | 
            +
                                    @request_handler.params)
         | 
| 243 | 
            +
                      end
         | 
| 244 | 
            +
                      on_write_complete do
         | 
| 245 | 
            +
                        @repeater.close
         | 
| 246 | 
            +
                      end
         | 
| 247 | 
            +
                    end
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                    private
         | 
| 250 | 
            +
                    def need_emit?(response)
         | 
| 251 | 
            +
                      case @request_handler.command
         | 
| 252 | 
            +
                      when "load", "object_remove"
         | 
| 253 | 
            +
                        return true
         | 
| 254 | 
            +
                      end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                      case response
         | 
| 257 | 
            +
                      when Array
         | 
| 258 | 
            +
                        return_code = response[0][0]
         | 
| 259 | 
            +
                        return_code.zero?
         | 
| 260 | 
            +
                      else
         | 
| 261 | 
            +
                        false
         | 
| 262 | 
            +
                      end
         | 
| 263 | 
            +
                    end
         | 
| 264 | 
            +
                  end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                  class RequestHandler
         | 
| 267 | 
            +
                    attr_reader :command
         | 
| 268 | 
            +
                    attr_reader :params
         | 
| 269 | 
            +
                    def initialize(input, repeater)
         | 
| 270 | 
            +
                      @input = input
         | 
| 271 | 
            +
                      @repeater = repeater
         | 
| 272 | 
            +
                      @parser = Http::Parser.new(self)
         | 
| 273 | 
            +
                    end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                    def <<(chunk)
         | 
| 276 | 
            +
                      @parser << chunk
         | 
| 277 | 
            +
                    end
         | 
| 278 | 
            +
             | 
| 210 279 | 
             
                    def on_message_begin
         | 
| 211 280 | 
             
                      @body = ""
         | 
| 281 | 
            +
                      @command = nil
         | 
| 282 | 
            +
                      @params = nil
         | 
| 212 283 | 
             
                    end
         | 
| 213 284 |  | 
| 214 285 | 
             
                    def on_headers_complete(headers)
         | 
| @@ -244,8 +315,52 @@ module Fluent | |
| 244 315 | 
             
                        if command == "load"
         | 
| 245 316 | 
             
                          params["values"] = @body unless @body.empty?
         | 
| 246 317 | 
             
                        end
         | 
| 247 | 
            -
                        @ | 
| 318 | 
            +
                        @command = command
         | 
| 319 | 
            +
                        @params = params
         | 
| 320 | 
            +
                      end
         | 
| 321 | 
            +
                    end
         | 
| 322 | 
            +
                  end
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                  class ResponseHandler
         | 
| 325 | 
            +
                    def initialize(handler)
         | 
| 326 | 
            +
                      @handler = handler
         | 
| 327 | 
            +
                      @parser = Http::Parser.new(self)
         | 
| 328 | 
            +
                    end
         | 
| 329 | 
            +
             | 
| 330 | 
            +
                    def <<(chunk)
         | 
| 331 | 
            +
                      @parser << chunk
         | 
| 332 | 
            +
                    end
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                    def on_message_begin
         | 
| 335 | 
            +
                      @body = ""
         | 
| 336 | 
            +
                      @content_type = nil
         | 
| 337 | 
            +
                    end
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                    def on_headers_complete(headers)
         | 
| 340 | 
            +
                      headers.each do |name, value|
         | 
| 341 | 
            +
                        case name
         | 
| 342 | 
            +
                        when /\AContent-Type\z/i
         | 
| 343 | 
            +
                          @content_type = value
         | 
| 344 | 
            +
                        end
         | 
| 345 | 
            +
                      end
         | 
| 346 | 
            +
                    end
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                    def on_body(chunk)
         | 
| 349 | 
            +
                      @body << chunk
         | 
| 350 | 
            +
                    end
         | 
| 351 | 
            +
             | 
| 352 | 
            +
                    def on_message_complete
         | 
| 353 | 
            +
                      case @content_type
         | 
| 354 | 
            +
                      when /\Aapplication\/json\z/
         | 
| 355 | 
            +
                        response = JSON.parse(@body)
         | 
| 356 | 
            +
                      when /\Aapplication\/x-msgpack\z/
         | 
| 357 | 
            +
                        response = MessagePack.unpack(@body)
         | 
| 358 | 
            +
                      when /\Atext\/x-groonga-command-list/
         | 
| 359 | 
            +
                        response = @body
         | 
| 360 | 
            +
                      else
         | 
| 361 | 
            +
                        response = nil
         | 
| 248 362 | 
             
                      end
         | 
| 363 | 
            +
                      @handler.on_response_complete(response)
         | 
| 249 364 | 
             
                    end
         | 
| 250 365 | 
             
                  end
         | 
| 251 366 | 
             
                end
         | 
    
        data/test/test_input.rb
    CHANGED
    
    | @@ -101,11 +101,16 @@ EOC | |
| 101 101 | 
             
                end
         | 
| 102 102 |  | 
| 103 103 | 
             
                def test_target_command
         | 
| 104 | 
            +
                  @real_response["Content-Type"] = "application/json"
         | 
| 105 | 
            +
                  @real_response.body = JSON.generate([[0, 0.0, 0.0], true])
         | 
| 104 106 | 
             
                  @driver.expect_emit("groonga.command.table_create",
         | 
| 105 107 | 
             
                                      @now,
         | 
| 106 | 
            -
                                      { | 
| 108 | 
            +
                                      {
         | 
| 109 | 
            +
                                        "name" => "Users",
         | 
| 110 | 
            +
                                        "flags" => "TABLE_NO_KEY",
         | 
| 111 | 
            +
                                      })
         | 
| 107 112 | 
             
                  @driver.run do
         | 
| 108 | 
            -
                    get("/d/table_create", "name" => "Users")
         | 
| 113 | 
            +
                    get("/d/table_create", "name" => "Users", "flags" => "TABLE_NO_KEY")
         | 
| 109 114 | 
             
                    assert_equal("200", @last_response.code)
         | 
| 110 115 | 
             
                  end
         | 
| 111 116 | 
             
                end
         | 
| @@ -119,6 +124,8 @@ EOC | |
| 119 124 | 
             
                end
         | 
| 120 125 |  | 
| 121 126 | 
             
                def test_load
         | 
| 127 | 
            +
                  @real_response["Content-Type"] = "application/json"
         | 
| 128 | 
            +
                  @real_response.body = JSON.generate([[0, 0.0, 0.0], 2])
         | 
| 122 129 | 
             
                  json = <<-EOJ
         | 
| 123 130 | 
             
            [
         | 
| 124 131 | 
             
            {"name": "Alice"},
         | 
    
        data/test/test_output.rb
    CHANGED
    
    | @@ -34,7 +34,8 @@ class GroongaOutputTest < Test::Unit::TestCase | |
| 34 34 |  | 
| 35 35 | 
             
              private
         | 
| 36 36 | 
             
              def create_driver(tag)
         | 
| 37 | 
            -
                driver = Fluent::Test:: | 
| 37 | 
            +
                driver = Fluent::Test::BufferedOutputTestDriver.new(Fluent::GroongaOutput,
         | 
| 38 | 
            +
                                                                    tag)
         | 
| 38 39 | 
             
                driver.configure(configuration)
         | 
| 39 40 | 
             
                driver
         | 
| 40 41 | 
             
              end
         | 
| @@ -99,9 +100,8 @@ EOC | |
| 99 100 | 
             
                    @response_body = JSON.generate([[0, 0.0, 0.0], true])
         | 
| 100 101 | 
             
                    driver = create_driver("groonga.command.table_create")
         | 
| 101 102 | 
             
                    time = Time.parse("2012-10-26T08:45:42Z").to_i
         | 
| 102 | 
            -
                    driver. | 
| 103 | 
            -
             | 
| 104 | 
            -
                    end
         | 
| 103 | 
            +
                    driver.emit({"name" => "Users"}, time)
         | 
| 104 | 
            +
                    driver.run
         | 
| 105 105 | 
             
                    assert_equal("/d/table_create?name=Users",
         | 
| 106 106 | 
             
                                 @request_parser.request_url)
         | 
| 107 107 | 
             
                  end
         | 
| @@ -119,9 +119,8 @@ EOC | |
| 119 119 | 
             
                    @response_body = JSON.generate([[0, 0.0, 0.0], [1]])
         | 
| 120 120 | 
             
                    driver = create_driver("log")
         | 
| 121 121 | 
             
                    time = Time.parse("2012-10-26T08:45:42Z").to_i
         | 
| 122 | 
            -
                    driver. | 
| 123 | 
            -
             | 
| 124 | 
            -
                    end
         | 
| 122 | 
            +
                    driver.emit({"message" => "1st message"}, time)
         | 
| 123 | 
            +
                    driver.run
         | 
| 125 124 | 
             
                    assert_equal("/d/load?table=Logs",
         | 
| 126 125 | 
             
                                 @request_parser.request_url)
         | 
| 127 126 | 
             
                    assert_equal([{"message" => "1st message"}],
         | 
| @@ -132,10 +131,9 @@ EOC | |
| 132 131 | 
             
                    @response_body = JSON.generate([[0, 0.0, 0.0], [2]])
         | 
| 133 132 | 
             
                    driver = create_driver("log")
         | 
| 134 133 | 
             
                    time = Time.parse("2012-10-26T08:45:42Z").to_i
         | 
| 135 | 
            -
                    driver. | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
                    end
         | 
| 134 | 
            +
                    driver.emit({"message" => "1st message"}, time)
         | 
| 135 | 
            +
                    driver.emit({"message" => "2nd message"}, time + 1)
         | 
| 136 | 
            +
                    driver.run
         | 
| 139 137 | 
             
                    assert_equal("/d/load?table=Logs",
         | 
| 140 138 | 
             
                                 @request_parser.request_url)
         | 
| 141 139 | 
             
                    assert_equal([
         | 
| @@ -232,10 +230,9 @@ EOC | |
| 232 230 | 
             
                class CommandTest < self
         | 
| 233 231 | 
             
                  def test_basic_command
         | 
| 234 232 | 
             
                    driver = create_driver("groonga.command.table_create")
         | 
| 235 | 
            -
                    time = Time.parse("2012-10-26T08:45:42Z")
         | 
| 236 | 
            -
                    driver. | 
| 237 | 
            -
             | 
| 238 | 
            -
                    end
         | 
| 233 | 
            +
                    time = Time.parse("2012-10-26T08:45:42Z").to_i
         | 
| 234 | 
            +
                    driver.emit({"name" => "Users"}, time)
         | 
| 235 | 
            +
                    driver.run
         | 
| 239 236 | 
             
                    assert_equal([
         | 
| 240 237 | 
             
                                   [
         | 
| 241 238 | 
             
                                     "--input-fd", actual_input_fd,
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: fluent-plugin-groonga
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.1. | 
| 4 | 
            +
              version: 1.1.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Kouhei Sutou
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-09-02 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: fluentd
         |