fluent-plugin-droonga 0.9.0 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/Gemfile +8 -1
  4. data/fluent-plugin-droonga.gemspec +2 -2
  5. data/lib/droonga/adapter.rb +39 -0
  6. data/lib/droonga/adapter_runner.rb +99 -0
  7. data/lib/droonga/catalog/base.rb +11 -11
  8. data/lib/droonga/catalog/dataset.rb +54 -0
  9. data/lib/droonga/catalog/version1.rb +1 -1
  10. data/lib/droonga/collector.rb +5 -7
  11. data/lib/droonga/collector_plugin.rb +7 -7
  12. data/lib/droonga/command.rb +36 -0
  13. data/lib/droonga/{plugin/input_adapter/crud.rb → command_repository.rb} +14 -8
  14. data/lib/droonga/dispatcher.rb +86 -54
  15. data/lib/droonga/distributed_command_planner.rb +183 -0
  16. data/lib/droonga/distributor.rb +43 -17
  17. data/lib/droonga/handler.rb +13 -72
  18. data/lib/droonga/handler_message.rb +5 -5
  19. data/lib/droonga/handler_messenger.rb +4 -1
  20. data/lib/droonga/handler_plugin.rb +2 -2
  21. data/lib/droonga/handler_runner.rb +104 -0
  22. data/lib/droonga/input_message.rb +4 -4
  23. data/lib/droonga/legacy_pluggable.rb +66 -0
  24. data/lib/droonga/{input_adapter.rb → legacy_plugin.rb} +27 -22
  25. data/lib/droonga/{plugin_repository.rb → legacy_plugin_repository.rb} +2 -4
  26. data/lib/droonga/message_matcher.rb +101 -0
  27. data/lib/droonga/{input_adapter_plugin.rb → planner.rb} +14 -10
  28. data/lib/droonga/planner_plugin.rb +54 -0
  29. data/lib/droonga/pluggable.rb +9 -45
  30. data/lib/droonga/plugin.rb +9 -33
  31. data/lib/droonga/plugin/collector/basic.rb +2 -0
  32. data/lib/droonga/plugin/collector/search.rb +31 -37
  33. data/lib/droonga/plugin/{handler/groonga/table_remove.rb → metadata/adapter_message.rb} +23 -18
  34. data/lib/droonga/plugin/{handler/search.rb → metadata/handler_action.rb} +19 -15
  35. data/lib/droonga/plugin/metadata/input_message.rb +39 -0
  36. data/lib/droonga/plugin/planner/crud.rb +49 -0
  37. data/lib/droonga/plugin/{distributor → planner}/distributed_search_planner.rb +62 -70
  38. data/lib/droonga/plugin/{distributor → planner}/groonga.rb +11 -32
  39. data/lib/droonga/plugin/{distributor → planner}/search.rb +5 -5
  40. data/lib/droonga/plugin/{distributor → planner}/watch.rb +15 -6
  41. data/lib/droonga/plugin_loader.rb +10 -0
  42. data/lib/droonga/plugin_registerable.rb +34 -10
  43. data/lib/droonga/plugin_registry.rb +58 -0
  44. data/lib/droonga/plugins/crud.rb +124 -0
  45. data/lib/droonga/plugins/error.rb +50 -0
  46. data/lib/droonga/{output_adapter_plugin.rb → plugins/groonga.rb} +9 -13
  47. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  48. data/lib/droonga/plugins/groonga/generic_command.rb +65 -0
  49. data/lib/droonga/{plugin/output_adapter/groonga.rb → plugins/groonga/generic_response.rb} +16 -15
  50. data/lib/droonga/plugins/groonga/select.rb +124 -0
  51. data/lib/droonga/plugins/groonga/table_create.rb +106 -0
  52. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  53. data/lib/droonga/plugins/search.rb +40 -0
  54. data/lib/droonga/plugins/watch.rb +156 -0
  55. data/lib/droonga/processor.rb +8 -10
  56. data/lib/droonga/searcher.rb +14 -4
  57. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  58. data/lib/droonga/session.rb +5 -5
  59. data/lib/droonga/test.rb +1 -1
  60. data/lib/droonga/test/stub_handler_message.rb +1 -1
  61. data/lib/droonga/test/{stub_distributor.rb → stub_planner.rb} +1 -1
  62. data/lib/droonga/worker.rb +7 -8
  63. data/lib/fluent/plugin/out_droonga.rb +0 -1
  64. data/sample/cluster/catalog.json +2 -4
  65. data/sample/mecab_filter/data.grn +7 -0
  66. data/sample/mecab_filter/ddl.grn +7 -0
  67. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  68. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  69. data/test/command/config/default/catalog.json +2 -5
  70. data/test/command/suite/search/error/no-query.expected +13 -0
  71. data/test/command/suite/search/error/no-query.test +7 -0
  72. data/test/command/suite/search/error/unknown-source.expected +26 -0
  73. data/test/command/suite/watch/subscribe.expected +3 -3
  74. data/test/command/suite/watch/unsubscribe.expected +3 -3
  75. data/test/unit/catalog/test_dataset.rb +385 -0
  76. data/test/unit/catalog/test_version1.rb +111 -45
  77. data/test/unit/fixtures/catalog/version1.json +0 -3
  78. data/test/unit/helper.rb +2 -1
  79. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  80. data/test/unit/plugin/collector/test_basic.rb +233 -376
  81. data/test/unit/plugin/collector/test_search.rb +8 -17
  82. data/test/unit/plugin/planner/search_planner/test_basic.rb +120 -0
  83. data/test/unit/plugin/planner/search_planner/test_group_by.rb +573 -0
  84. data/test/unit/plugin/planner/search_planner/test_output.rb +388 -0
  85. data/test/unit/plugin/planner/search_planner/test_sort_by.rb +938 -0
  86. data/test/unit/plugin/{distributor → planner}/test_search.rb +20 -75
  87. data/test/unit/{plugin/handler → plugins/crud}/test_add.rb +11 -11
  88. data/test/unit/plugins/groonga/select/test_adapter_input.rb +213 -0
  89. data/test/unit/{plugin/output_adapter/groonga/test_select.rb → plugins/groonga/select/test_adapter_output.rb} +12 -13
  90. data/test/unit/{plugin/handler → plugins}/groonga/test_column_create.rb +20 -5
  91. data/test/unit/{plugin/handler → plugins}/groonga/test_table_create.rb +5 -0
  92. data/test/unit/{plugin/handler → plugins}/groonga/test_table_remove.rb +8 -1
  93. data/test/unit/{plugin/handler → plugins}/test_groonga.rb +5 -5
  94. data/test/unit/{plugin/handler → plugins}/test_search.rb +21 -5
  95. data/test/unit/{plugin/handler → plugins}/test_watch.rb +29 -10
  96. data/{lib/droonga/command_mapper.rb → test/unit/test_command_repository.rb} +16 -22
  97. data/test/unit/{test_plugin.rb → test_legacy_plugin.rb} +3 -3
  98. data/test/unit/{test_plugin_repository.rb → test_legacy_plugin_repository.rb} +3 -3
  99. data/test/unit/test_message_matcher.rb +137 -0
  100. metadata +86 -66
  101. data/bin/grn2jsons +0 -82
  102. data/lib/droonga/distribution_planner.rb +0 -76
  103. data/lib/droonga/distributor_plugin.rb +0 -95
  104. data/lib/droonga/output_adapter.rb +0 -53
  105. data/lib/droonga/plugin/collector/groonga.rb +0 -83
  106. data/lib/droonga/plugin/distributor/crud.rb +0 -84
  107. data/lib/droonga/plugin/handler/add.rb +0 -109
  108. data/lib/droonga/plugin/handler/forward.rb +0 -75
  109. data/lib/droonga/plugin/handler/groonga.rb +0 -99
  110. data/lib/droonga/plugin/handler/groonga/column_create.rb +0 -106
  111. data/lib/droonga/plugin/handler/groonga/table_create.rb +0 -91
  112. data/lib/droonga/plugin/handler/watch.rb +0 -108
  113. data/lib/droonga/plugin/input_adapter/groonga.rb +0 -49
  114. data/lib/droonga/plugin/input_adapter/groonga/select.rb +0 -63
  115. data/lib/droonga/plugin/output_adapter/crud.rb +0 -51
  116. data/lib/droonga/plugin/output_adapter/groonga/select.rb +0 -54
  117. data/lib/groonga_command_converter.rb +0 -143
  118. data/sample/fluentd.conf +0 -8
  119. data/test/unit/plugin/distributor/test_search_planner.rb +0 -1102
  120. data/test/unit/plugin/input_adapter/groonga/test_select.rb +0 -248
  121. data/test/unit/test_command_mapper.rb +0 -44
  122. data/test/unit/test_groonga_command_converter.rb +0 -242
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 2013-2014 Droonga Project
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -15,7 +13,7 @@
15
13
  # License along with this library; if not, write to the Free Software
16
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
15
 
18
- require "droonga/handler"
16
+ require "droonga/handler_runner"
19
17
 
20
18
  module Droonga
21
19
  class Processor
@@ -27,24 +25,24 @@ module Droonga
27
25
  end
28
26
 
29
27
  def start
30
- @handler = Handler.new(@loop, @options)
31
- @handler.start
28
+ @handler_runner = HandlerRunner.new(@loop, @options)
29
+ @handler_runner.start
32
30
  end
33
31
 
34
32
  def shutdown
35
33
  $log.trace("#{log_tag}: shutdown: start")
36
- @handler.shutdown
34
+ @handler_runner.shutdown
37
35
  $log.trace("#{log_tag}: shutdown: done")
38
36
  end
39
37
 
40
38
  def process(message)
41
39
  $log.trace("#{log_tag}: process: start")
42
40
  command = message["type"]
43
- if @handler.processable?(command)
41
+ if @handler_runner.processable?(command)
44
42
  $log.trace("#{log_tag}: process: handlable: #{command}")
45
- synchronous = @handler.prefer_synchronous?(command)
43
+ synchronous = @handler_runner.prefer_synchronous?(command)
46
44
  if @n_workers.zero? or synchronous
47
- @handler.process(message)
45
+ @handler_runner.process(message)
48
46
  else
49
47
  @message_pusher.push(message)
50
48
  end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2013 Droonga Project
3
+ # Copyright (C) 2013-2014 Droonga Project
4
4
  #
5
5
  # This library is free software; you can redistribute it and/or
6
6
  # modify it under the terms of the GNU Lesser General Public
@@ -20,9 +20,16 @@ require "tsort"
20
20
  require "groonga"
21
21
 
22
22
  require "droonga/time_formatter"
23
+ require "droonga/message_processing_error"
23
24
 
24
25
  module Droonga
25
26
  class Searcher
27
+ class NoQuery < BadRequest
28
+ def initialize
29
+ super("You must specify one or more query.")
30
+ end
31
+ end
32
+
26
33
  class MissingSourceParameter < BadRequest
27
34
  def initialize(query, queries)
28
35
  super("The query #{query.inspect} has no source. " +
@@ -63,9 +70,8 @@ module Droonga
63
70
  private
64
71
  def process_queries(queries)
65
72
  $log.trace("#{log_tag}: process_queries: start")
66
- unless queries
67
- $log.trace("#{log_tag}: process_queries: done")
68
- return {}
73
+ if queries.nil? || queries.empty?
74
+ raise NoQuery.new
69
75
  end
70
76
  $log.trace("#{log_tag}: process_queries: sort: start")
71
77
  sorted_queries = QuerySorter.sort(queries)
@@ -640,3 +646,7 @@ module Droonga
640
646
  end
641
647
  end
642
648
  end
649
+
650
+ if ENV["DROONGA_ENABLE_SEARCH_MECAB_FILTER"] == "yes"
651
+ require "droonga/searcher/mecab_filter"
652
+ end
@@ -0,0 +1,67 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2014 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 "MeCab"
19
+
20
+ module Droonga
21
+ class Searcher
22
+ class QuerySearcher
23
+ class MeCabTokenizer
24
+ def initialize
25
+ @mecab = MeCab::Tagger.new("-Owakati")
26
+ end
27
+
28
+ def tokenize(text)
29
+ tokens = @mecab.parse(text).force_encoding("utf-8").split(/\s+/)
30
+ tokens.reject do |token|
31
+ token.empty?
32
+ end
33
+ end
34
+ end
35
+
36
+ def apply_mecab_filter(condition)
37
+ return unless condition.is_a?(Hash)
38
+ return unless condition["useMeCabFilter"]
39
+ query = condition["query"]
40
+ return if query.nil?
41
+ match_columns = condition["matchTo"]
42
+ return unless match_columns.is_a?(Array)
43
+ return if match_columns.size != 1
44
+ match_column = match_columns.first
45
+
46
+ tokenizer = MeCabTokenizer.new
47
+
48
+ @records.open_cursor do |cursor|
49
+ count = 0
50
+ cursor.each do |record|
51
+ match_target = record[match_column]
52
+ body_terms = tokenizer.tokenize(match_target)
53
+ unless body_terms.include?(query)
54
+ record.delete
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ alias_method :original_apply_condition!, :apply_condition!
61
+ def apply_condition!(condition)
62
+ original_apply_condition!(condition)
63
+ apply_mecab_filter(condition)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -48,10 +48,10 @@ module Droonga
48
48
  end
49
49
  tasks.each do |task|
50
50
  task["n_of_inputs"] += 1
51
- component = task["component"]
52
- type = component["type"]
51
+ step = task["step"]
52
+ type = step["type"]
53
53
  command = "collector_" + type
54
- n_of_expects = component["n_of_expects"]
54
+ n_of_expects = step["n_of_expects"]
55
55
  message = {
56
56
  "task"=>task,
57
57
  "name"=>name,
@@ -61,9 +61,9 @@ module Droonga
61
61
  return if task["n_of_inputs"] < n_of_expects
62
62
  #the task is done
63
63
  result = task["values"]
64
- post = component["post"]
64
+ post = step["post"]
65
65
  @dispatcher.reply("body" => result) if post
66
- component["descendants"].each do |name, routes|
66
+ step["descendants"].each do |name, routes|
67
67
  message = {
68
68
  "id" => @id,
69
69
  "input" => name,
data/lib/droonga/test.rb CHANGED
@@ -15,7 +15,7 @@
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
- require "droonga/test/stub_distributor"
18
+ require "droonga/test/stub_planner"
19
19
  require "droonga/test/stub_handler"
20
20
  require "droonga/test/stub_handler_message"
21
21
  require "droonga/test/stub_handler_messenger"
@@ -22,7 +22,7 @@ module Droonga
22
22
  raw = {
23
23
  "body" => {
24
24
  "task" => {
25
- "component" => {
25
+ "step" => {
26
26
  "body" => request,
27
27
  },
28
28
  },
@@ -17,7 +17,7 @@
17
17
 
18
18
  module Droonga
19
19
  module Test
20
- class StubDistributor
20
+ class StubPlanner
21
21
  attr_reader :messages
22
22
  def initialize
23
23
  @messages = []
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 2013-2014 Droonga Project
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -16,14 +14,15 @@
16
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
15
 
18
16
  require "droonga/event_loop"
19
- require "droonga/handler"
17
+ require "droonga/handler_runner"
20
18
  require "droonga/message_receiver"
21
19
 
22
20
  module Droonga
23
21
  module Worker
24
22
  def initialize
25
23
  @loop = EventLoop.new
26
- @handler = Handler.new(@loop, config.merge(:dispatcher => nil))
24
+ @handler_runner = HandlerRunner.new(@loop,
25
+ config.merge(:dispatcher => nil))
27
26
  receiver_socket = config[:message_receiver]
28
27
  @message_receiver = MessageReceiver.new(@loop, receiver_socket) do |message|
29
28
  process(message)
@@ -32,10 +31,10 @@ module Droonga
32
31
 
33
32
  def run
34
33
  $log.trace("#{log_tag}: run: start")
35
- @handler.start
34
+ @handler_runner.start
36
35
  @message_receiver.start
37
36
  @loop.run
38
- @handler.shutdown
37
+ @handler_runner.shutdown
39
38
  $log.trace("#{log_tag}: run: done")
40
39
  end
41
40
 
@@ -49,7 +48,7 @@ module Droonga
49
48
  private
50
49
  def process(message)
51
50
  $log.trace("#{log_tag}: process: start")
52
- @handler.process(message)
51
+ @handler_runner.process(message)
53
52
  $log.trace("#{log_tag}: process: done")
54
53
  end
55
54
 
@@ -60,7 +60,6 @@ module Fluent
60
60
  "body" => record
61
61
  }
62
62
  end
63
- message["via"] ||= []
64
63
  reply_to = message["replyTo"]
65
64
  if reply_to.is_a? String
66
65
  message["replyTo"] = {
@@ -1,4 +1,5 @@
1
1
  {
2
+ "version": 1,
2
3
  "effective_date": "2013-09-01T00:00:00Z",
3
4
  "zones": ["localhost:23003/droonga"],
4
5
  "farms": {
@@ -10,7 +11,7 @@
10
11
  "datasets": {
11
12
  "Droonga": {
12
13
  "workers": 2,
13
- "plugins": ["search", "groonga", "add"],
14
+ "plugins": ["groonga", "search", "crud"],
14
15
  "number_of_replicas": 2,
15
16
  "number_of_partitions": 2,
16
17
  "partition_key": "_key",
@@ -36,8 +37,5 @@
36
37
  }
37
38
  }
38
39
  }
39
- },
40
- "options": {
41
- "plugins": ["groonga"]
42
40
  }
43
41
  }
@@ -0,0 +1,7 @@
1
+ load --table Memo
2
+ [
3
+ {"_key": "1", "content": "アンパサンド"},
4
+ {"_key": "2", "content": "ジャパン"},
5
+ {"_key": "3", "content": "食パン"},
6
+ {"_key": "4", "content": "フランスのパン"}
7
+ ]
@@ -0,0 +1,7 @@
1
+ table_create Memo TABLE_HASH_KEY ShortText
2
+ column_create Memo content COLUMN_SCALAR ShortText
3
+
4
+ table_create Terms TABLE_PAT_KEY ShortText \
5
+ --default_tokenizer TokenBigram \
6
+ --normalizer NormalizerAuto
7
+ column_create Terms memo_context COLUMN_INDEX|WITH_POSITION Memo content
@@ -0,0 +1,21 @@
1
+ {
2
+ "type": "search",
3
+ "dataset": "Droonga",
4
+ "body": {
5
+ "queries": {
6
+ "search": {
7
+ "source": "Memo",
8
+ "condition": {
9
+ "matchTo": ["content"],
10
+ "query": "パン",
11
+ "useMeCabFilter": true
12
+ },
13
+ "output": {
14
+ "elements": ["count", "records"],
15
+ "attributes": ["_key", "content"],
16
+ "limit": 10
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "type": "search",
3
+ "dataset": "Droonga",
4
+ "body": {
5
+ "queries": {
6
+ "search": {
7
+ "source": "Memo",
8
+ "condition": {
9
+ "matchTo": ["content"],
10
+ "query": "パン",
11
+ "useMeCabFilter": false
12
+ },
13
+ "output": {
14
+ "elements": ["count", "records"],
15
+ "attributes": ["_key", "content"],
16
+ "limit": 10
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
@@ -10,7 +10,7 @@
10
10
  "datasets": {
11
11
  "Droonga": {
12
12
  "workers": 2,
13
- "plugins": ["search", "groonga", "add"],
13
+ "plugins": ["groonga", "crud", "search"],
14
14
  "number_of_replicas": 2,
15
15
  "number_of_partitions": 2,
16
16
  "partition_key": "_key",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "Watch": {
40
40
  "workers": 2,
41
- "plugins": ["search", "groonga", "add", "watch"],
41
+ "plugins": ["groonga", "watch", "search", "crud"],
42
42
  "number_of_replicas": 1,
43
43
  "number_of_partitions": 1,
44
44
  "partition_key": "_key",
@@ -54,8 +54,5 @@
54
54
  }
55
55
  }
56
56
  }
57
- },
58
- "options": {
59
- "plugins": ["crud", "groonga"]
60
57
  }
61
58
  }
@@ -0,0 +1,13 @@
1
+ [
2
+ "droonga.message",
3
+ 0,
4
+ {
5
+ "inReplyTo": "request-id",
6
+ "statusCode": 400,
7
+ "type": "search.result",
8
+ "body": {
9
+ "name": "NoQuery",
10
+ "message": "You must specify one or more query."
11
+ }
12
+ }
13
+ ]
@@ -0,0 +1,7 @@
1
+ #@include fixture/user-table.jsons
2
+ {
3
+ "type": "search",
4
+ "dataset": "Droonga",
5
+ "body": {
6
+ }
7
+ }
@@ -13,6 +13,32 @@
13
13
  "source": "unknown"
14
14
  }
15
15
  }
16
+ },
17
+ "errors": {
18
+ "sources0": {
19
+ "statusCode": 404,
20
+ "body": {
21
+ "name": "UnknownSource",
22
+ "message": "The source \"unknown\" does not exist. It must be a name of an existing table or another query.",
23
+ "detail": {
24
+ "unknown-source": {
25
+ "source": "unknown"
26
+ }
27
+ }
28
+ }
29
+ },
30
+ "sources1": {
31
+ "statusCode": 404,
32
+ "body": {
33
+ "name": "UnknownSource",
34
+ "message": "The source \"unknown\" does not exist. It must be a name of an existing table or another query.",
35
+ "detail": {
36
+ "unknown-source": {
37
+ "source": "unknown"
38
+ }
39
+ }
40
+ }
41
+ }
16
42
  }
17
43
  }
18
44
  ]