fluent-plugin-droonga 0.9.0 → 0.9.9

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