fluent-plugin-droonga 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +40 -0
  5. data/LICENSE.txt +14 -0
  6. data/README.md +18 -0
  7. data/Rakefile +25 -0
  8. data/benchmark/benchmark.rb +123 -0
  9. data/benchmark/utils.rb +243 -0
  10. data/benchmark/watch/benchmark-notify.rb +143 -0
  11. data/benchmark/watch/benchmark-notify.sh +19 -0
  12. data/benchmark/watch/benchmark-publish.rb +120 -0
  13. data/benchmark/watch/benchmark-scan.rb +210 -0
  14. data/benchmark/watch/catalog.json +32 -0
  15. data/benchmark/watch/fluentd.conf +12 -0
  16. data/bin/grn2jsons +85 -0
  17. data/fluent-plugin-droonga.gemspec +41 -0
  18. data/lib/droonga/adapter.rb +156 -0
  19. data/lib/droonga/catalog.rb +153 -0
  20. data/lib/droonga/command_mapper.rb +45 -0
  21. data/lib/droonga/engine.rb +83 -0
  22. data/lib/droonga/executor.rb +289 -0
  23. data/lib/droonga/handler.rb +140 -0
  24. data/lib/droonga/handler_plugin.rb +35 -0
  25. data/lib/droonga/job_queue.rb +83 -0
  26. data/lib/droonga/job_queue_schema.rb +65 -0
  27. data/lib/droonga/logger.rb +34 -0
  28. data/lib/droonga/plugin.rb +41 -0
  29. data/lib/droonga/plugin/adapter/groonga/select.rb +88 -0
  30. data/lib/droonga/plugin/adapter_groonga.rb +40 -0
  31. data/lib/droonga/plugin/handler/groonga/column_create.rb +103 -0
  32. data/lib/droonga/plugin/handler/groonga/table_create.rb +100 -0
  33. data/lib/droonga/plugin/handler_add.rb +44 -0
  34. data/lib/droonga/plugin/handler_forward.rb +70 -0
  35. data/lib/droonga/plugin/handler_groonga.rb +52 -0
  36. data/lib/droonga/plugin/handler_proxy.rb +82 -0
  37. data/lib/droonga/plugin/handler_search.rb +33 -0
  38. data/lib/droonga/plugin/handler_watch.rb +102 -0
  39. data/lib/droonga/proxy.rb +371 -0
  40. data/lib/droonga/searcher.rb +415 -0
  41. data/lib/droonga/server.rb +112 -0
  42. data/lib/droonga/sweeper.rb +42 -0
  43. data/lib/droonga/watch_schema.rb +88 -0
  44. data/lib/droonga/watcher.rb +256 -0
  45. data/lib/droonga/worker.rb +51 -0
  46. data/lib/fluent/plugin/out_droonga.rb +56 -0
  47. data/lib/groonga_command_converter.rb +137 -0
  48. data/sample/cluster/catalog.json +43 -0
  49. data/sample/cluster/fluentd.conf +12 -0
  50. data/sample/fluentd.conf +8 -0
  51. data/test/fixtures/catalog.json +43 -0
  52. data/test/fixtures/document.grn +23 -0
  53. data/test/helper.rb +24 -0
  54. data/test/helper/fixture.rb +28 -0
  55. data/test/helper/sandbox.rb +73 -0
  56. data/test/helper/stub_worker.rb +27 -0
  57. data/test/helper/watch_helper.rb +35 -0
  58. data/test/plugin/adapter/groonga/test_select.rb +176 -0
  59. data/test/plugin/handler/groonga/test_column_create.rb +127 -0
  60. data/test/plugin/handler/groonga/test_table_create.rb +140 -0
  61. data/test/plugin/handler/test_handler_add.rb +135 -0
  62. data/test/plugin/handler/test_handler_groonga.rb +64 -0
  63. data/test/plugin/handler/test_handler_search.rb +512 -0
  64. data/test/plugin/handler/test_handler_watch.rb +168 -0
  65. data/test/run-test.rb +55 -0
  66. data/test/test_adapter.rb +48 -0
  67. data/test/test_catalog.rb +59 -0
  68. data/test/test_command_mapper.rb +44 -0
  69. data/test/test_groonga_command_converter.rb +242 -0
  70. data/test/test_handler.rb +53 -0
  71. data/test/test_job_queue_schema.rb +45 -0
  72. data/test/test_output.rb +99 -0
  73. data/test/test_sweeper.rb +95 -0
  74. data/test/test_watch_schema.rb +57 -0
  75. data/test/test_watcher.rb +336 -0
  76. data/test/test_worker.rb +144 -0
  77. metadata +299 -0
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 droonga project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ module Droonga
19
+ class HandlerPlugin
20
+ @@plugins = {}
21
+ class << self
22
+ def register(name, handler_class)
23
+ @@plugins[name] = handler_class
24
+ end
25
+ end
26
+
27
+ def initialize(name)
28
+ @name = name
29
+ end
30
+
31
+ def instantiate(*args)
32
+ @@plugins[@name].new(*args)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,83 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 droonga project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "droonga/job_queue_schema"
19
+ require "msgpack"
20
+
21
+ module Droonga
22
+ class JobQueue
23
+ class << self
24
+ def ensure_schema(database_path, queue_name)
25
+ schema = JobQueueSchema.new(database_path, queue_name)
26
+ schema.ensure_created
27
+ end
28
+
29
+ def open(database_path, queue_name)
30
+ job_queue = new(database_path, queue_name)
31
+ job_queue.open
32
+ job_queue
33
+ end
34
+ end
35
+
36
+ def initialize(database_path, queue_name)
37
+ @database_path = database_path
38
+ @queue_name = queue_name
39
+ end
40
+
41
+ def open
42
+ @context = Groonga::Context.new
43
+ @database = @context.open_database(@database_path)
44
+ @context.encoding = :none
45
+
46
+ @queue = @context[@queue_name]
47
+ end
48
+
49
+ def push_message(message)
50
+ $log.trace("#{log_tag}: push_message: start")
51
+ packed_message = message.to_msgpack
52
+ @queue.push do |record|
53
+ record.message = packed_message
54
+ end
55
+ $log.trace("#{log_tag}: push_message: done")
56
+ end
57
+
58
+ def pull_message
59
+ packed_message = nil
60
+ @queue.pull do |record|
61
+ if record
62
+ packed_message = record.message
63
+ record.delete
64
+ end
65
+ end
66
+ return nil unless packed_message
67
+ MessagePack.unpack(packed_message)
68
+ end
69
+
70
+ def close
71
+ @queue = nil
72
+ if @database
73
+ @database.close
74
+ @context.close
75
+ @database = @context = nil
76
+ end
77
+ end
78
+
79
+ def log_tag
80
+ "[#{Process.ppid}][#{Process.pid}] job_queue"
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 droonga project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "fileutils"
19
+
20
+ require "groonga"
21
+
22
+ module Droonga
23
+ class JobQueueSchema
24
+ def initialize(database_path, queue_name)
25
+ @database_path = database_path
26
+ @queue_name = queue_name
27
+ end
28
+
29
+ def ensure_created
30
+ ensure_database
31
+ ensure_queue
32
+ end
33
+
34
+ private
35
+ def ensure_database
36
+ return if File.exist?(@database_path)
37
+ FileUtils.mkdir_p(File.dirname(@database_path))
38
+ create_context do |context|
39
+ context.create_database(@database_path) do
40
+ end
41
+ end
42
+ end
43
+
44
+ def ensure_queue
45
+ create_context do |context|
46
+ context.open_database(@database_path) do
47
+ Groonga::Schema.define(:context => context) do |schema|
48
+ schema.create_table(@queue_name, :type => :array) do |table|
49
+ table.text("message")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def create_context
57
+ context = Groonga::Context.new
58
+ begin
59
+ yield(context)
60
+ ensure
61
+ context.close
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 droonga project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ module Droonga
19
+ module Logger
20
+ module_function
21
+ def info(message)
22
+ if $log
23
+ $log.info(message)
24
+ end
25
+ end
26
+
27
+ def error(message, additional_information={})
28
+ if $log
29
+ $log.error(message, additional_information)
30
+ $log.error_backtrace
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 droonga project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ module Droonga
19
+ class Plugin
20
+ class << self
21
+ def load_all
22
+ $LOAD_PATH.each do |load_path|
23
+ Dir.glob("#{load_path}/droonga/plugin/*_*.rb") do |path|
24
+ type, name = File.basename(path, ".rb").split(/_/, 2)
25
+ plugin = new(type, name)
26
+ plugin.load
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def initialize(type, name)
33
+ @type = type
34
+ @name = name
35
+ end
36
+
37
+ def load
38
+ require "droonga/plugin/#{@type}_#{@name}"
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright (C) 2013 droonga project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ module Droonga
17
+ class GroongaAdapter
18
+ class Select
19
+ def convert_request(select_request)
20
+ table = select_request["table"]
21
+ result_name = table + "_result"
22
+ match_columns = select_request["match_columns"]
23
+ match_to = match_columns
24
+ query = select_request["query"]
25
+ output_columns = select_request["output_columns"]
26
+ attributes = output_columns.split(/, */)
27
+
28
+ search_request = {
29
+ "queries" => {
30
+ result_name => {
31
+ "source" => table,
32
+ "output" => {
33
+ "elements" => [
34
+ "startTime",
35
+ "elapsedTime",
36
+ "count",
37
+ "attributes",
38
+ "records",
39
+ ],
40
+ "attributes" => attributes,
41
+ },
42
+ }
43
+ }
44
+ }
45
+ if query
46
+ condition = {
47
+ "query" => query,
48
+ "matchTo"=> match_to,
49
+ "defaultOperator"=> "&&",
50
+ "allowPragma"=> false,
51
+ "allowColumn"=> true,
52
+ }
53
+ search_request["queries"][result_name]["condition"] = condition
54
+ end
55
+ search_request
56
+ end
57
+
58
+ def convert_response(search_response)
59
+ select_responses = search_response.collect do |key, value|
60
+ status_code = 0
61
+
62
+ start_time = value["startTime"]
63
+ start_time_in_unix_time = if start_time
64
+ Time.parse(start_time).to_f
65
+ else
66
+ Time.now.to_f
67
+ end
68
+ elapsed_time = value["elapsedTime"] || 0
69
+ count = value["count"]
70
+
71
+ attributes = value["attributes"] || []
72
+ converted_attributes = attributes.collect do |attribute|
73
+ name = attribute["name"]
74
+ type = attribute["type"]
75
+ [name, type]
76
+ end
77
+
78
+ header = [status_code, start_time_in_unix_time, elapsed_time]
79
+ results = [[count], converted_attributes, value["records"]]
80
+ body = [results]
81
+
82
+ [header, body]
83
+ end
84
+ select_responses.first
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2013 droonga project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "groonga"
17
+
18
+ require "droonga/adapter"
19
+
20
+ module Droonga
21
+ class GroongaAdapter < Droonga::Adapter
22
+ # TODO: AdapterPlugin or something should be defined to avoid conflicts.
23
+ Droonga::HandlerPlugin.register("select", self)
24
+ command :select
25
+ def select(select_request)
26
+ command = Select.new
27
+ search_request = command.convert_request(select_request)
28
+ add_route("select_response")
29
+ post(search_request, "search")
30
+ end
31
+
32
+ command :select_response
33
+ def select_response(search_response)
34
+ command = Select.new
35
+ emit(command.convert_response(search_response))
36
+ end
37
+ end
38
+ end
39
+
40
+ require "droonga/plugin/adapter/groonga/select"
@@ -0,0 +1,103 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 droonga project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "groonga"
19
+ require "groonga/command/column-create"
20
+
21
+ module Droonga
22
+ class GroongaHandler
23
+ class ColumnCreate
24
+ def initialize(context)
25
+ @context = context
26
+ end
27
+
28
+ def execute(request)
29
+ command_class = Groonga::Command.find("column_create")
30
+ @command = command_class.new("column_create", request)
31
+
32
+ if @command.column_index?
33
+ define_index
34
+ else
35
+ define_column
36
+ end
37
+ end
38
+
39
+ private
40
+ def define_column
41
+ table_name = @command["table"]
42
+ column_name = @command["name"]
43
+ column_type = @command["type"]
44
+
45
+ options = create_column_options
46
+ Groonga::Schema.define(:context => @context) do |schema|
47
+ schema.change_table(table_name) do |table|
48
+ table.column(column_name, column_type, options)
49
+ end
50
+ end
51
+ [true]
52
+ end
53
+
54
+ def create_column_options
55
+ options = {}
56
+ create_column_options_flags(options)
57
+ options
58
+ end
59
+
60
+ def create_column_options_flags(options)
61
+ options[:type] = :scalar
62
+ if @command.column_scalar?
63
+ options[:type] = :scalar
64
+ elsif @command.column_vector?
65
+ options[:type] = :vector
66
+ end
67
+ options
68
+ end
69
+
70
+ def define_index
71
+ table_name = @command["table"]
72
+ target_table = @command["type"]
73
+ target_column = @command["source"]
74
+
75
+ options = create_index_options
76
+ Groonga::Schema.define(:context => @context) do |schema|
77
+ schema.change_table(table_name) do |table|
78
+ table.index("#{target_table}.#{target_column}", options)
79
+ end
80
+ end
81
+ [true]
82
+ end
83
+
84
+ def create_index_options
85
+ options = {}
86
+ create_index_options_name(options)
87
+ create_index_options_flags(options)
88
+ options
89
+ end
90
+
91
+ def create_index_options_name(options)
92
+ options[:name] = @command["name"]
93
+ end
94
+
95
+ def create_index_options_flags(options)
96
+ options[:with_section] = true if @command.with_section?
97
+ options[:with_weight] = true if @command.with_weight?
98
+ options[:with_position] = true if @command.with_position?
99
+ options
100
+ end
101
+ end
102
+ end
103
+ end