fluent-plugin-droonga 0.8.0 → 0.9.0

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +7 -0
  4. data/benchmark/watch/benchmark-notify.rb +6 -6
  5. data/benchmark/watch/benchmark-notify.sh +3 -2
  6. data/bin/grn2jsons +0 -3
  7. data/doc/text/news.md +13 -0
  8. data/fluent-plugin-droonga.gemspec +1 -1
  9. data/lib/droonga/catalog/base.rb +8 -3
  10. data/lib/droonga/catalog.rb +1 -16
  11. data/lib/droonga/catalog_observer.rb +57 -0
  12. data/lib/droonga/collector.rb +1 -1
  13. data/lib/droonga/dispatcher.rb +3 -1
  14. data/lib/droonga/distributor_plugin.rb +47 -19
  15. data/lib/droonga/handler_messenger.rb +26 -2
  16. data/lib/droonga/message_processing_error.rb +6 -8
  17. data/lib/droonga/output_message.rb +17 -1
  18. data/lib/droonga/plugin/collector/basic.rb +44 -81
  19. data/lib/droonga/plugin/collector/groonga.rb +83 -0
  20. data/lib/droonga/plugin/collector/search.rb +104 -0
  21. data/lib/droonga/plugin/distributor/crud.rb +41 -0
  22. data/lib/droonga/plugin/distributor/distributed_search_planner.rb +4 -4
  23. data/lib/droonga/plugin/distributor/groonga.rb +38 -0
  24. data/lib/droonga/plugin/handler/add.rb +4 -1
  25. data/lib/droonga/plugin/handler/groonga/column_create.rb +7 -0
  26. data/lib/droonga/plugin/handler/groonga/table_remove.rb +42 -0
  27. data/lib/droonga/plugin/handler/groonga.rb +17 -2
  28. data/lib/droonga/plugin/handler/watch.rb +4 -4
  29. data/lib/droonga/plugin/input_adapter/crud.rb +27 -0
  30. data/lib/droonga/plugin/input_adapter/groonga.rb +16 -1
  31. data/lib/droonga/plugin/output_adapter/crud.rb +51 -0
  32. data/lib/droonga/plugin/output_adapter/groonga.rb +8 -1
  33. data/lib/droonga/plugin.rb +1 -1
  34. data/lib/droonga/replier.rb +7 -1
  35. data/lib/droonga/searcher.rb +168 -74
  36. data/lib/droonga/session.rb +1 -1
  37. data/lib/groonga_command_converter.rb +7 -1
  38. data/test/command/config/default/catalog.json +1 -1
  39. data/test/command/suite/add/error/invalid-integer.expected +31 -1
  40. data/test/command/suite/add/error/invalid-time.expected +31 -1
  41. data/test/command/suite/add/error/missing-key.expected +17 -1
  42. data/test/command/suite/add/error/missing-table.expected +17 -1
  43. data/test/command/suite/add/error/unknown-column.expected +31 -1
  44. data/test/command/suite/add/error/unknown-table.expected +17 -1
  45. data/test/command/suite/add/minimum.expected +1 -1
  46. data/test/command/suite/add/with-values.expected +1 -1
  47. data/test/command/suite/add/without-key.expected +1 -1
  48. data/test/command/suite/groonga/column_create/scalar.expected +2 -2
  49. data/test/command/suite/groonga/column_create/unknown-table.expected +18 -0
  50. data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
  51. data/test/command/suite/groonga/column_create/vector.expected +2 -2
  52. data/test/command/suite/groonga/select/minimum.expected +1 -1
  53. data/test/command/suite/groonga/table_create/array.expected +1 -1
  54. data/test/command/suite/groonga/table_create/hash.expected +1 -1
  55. data/test/command/suite/groonga/table_remove/success.expected +17 -0
  56. data/test/command/suite/groonga/table_remove/success.test +8 -0
  57. data/test/command/suite/groonga/table_remove/unknown-table.expected +18 -0
  58. data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
  59. data/test/command/suite/message/error/missing-dataset.expected +1 -1
  60. data/test/command/suite/message/error/unknown-command.expected +1 -1
  61. data/test/command/suite/message/error/unknown-dataset.expected +1 -1
  62. data/test/command/suite/search/attributes/array.expected +1 -1
  63. data/test/command/suite/search/attributes/hash.expected +1 -1
  64. data/test/command/suite/search/complex.expected +1 -1
  65. data/test/command/suite/search/condition/nested.expected +1 -1
  66. data/test/command/suite/search/condition/query.expected +1 -1
  67. data/test/command/suite/search/condition/script.expected +1 -1
  68. data/test/command/suite/search/error/cyclic-source.expected +1 -1
  69. data/test/command/suite/search/error/deeply-cyclic-source.expected +1 -1
  70. data/test/command/suite/search/error/missing-source-parameter.expected +1 -1
  71. data/test/command/suite/search/error/unknown-source.expected +1 -1
  72. data/test/command/suite/search/group/count.expected +1 -1
  73. data/test/command/suite/search/group/limit.expected +1 -1
  74. data/test/command/suite/search/group/string.expected +1 -1
  75. data/test/command/suite/search/multiple/chained.expected +1 -1
  76. data/test/command/suite/search/multiple/parallel.expected +1 -1
  77. data/test/command/suite/search/range/only-output.expected +1 -1
  78. data/test/command/suite/search/range/only-sort.expected +1 -1
  79. data/test/command/suite/search/range/sort-and-output.expected +1 -1
  80. data/test/command/suite/search/range/too-large-output-offset.expected +1 -1
  81. data/test/command/suite/search/range/too-large-sort-offset.expected +1 -1
  82. data/test/command/suite/search/response/records/value/time.expected +1 -1
  83. data/test/command/suite/search/simple.expected +1 -1
  84. data/test/command/suite/search/sort/default-offset-limit.expected +1 -1
  85. data/test/command/suite/search/sort/invisible-column.expected +1 -1
  86. data/test/command/suite/watch/subscribe.expected +1 -1
  87. data/test/command/suite/watch/unsubscribe.expected +1 -1
  88. data/test/performance/run-test.rb +56 -0
  89. data/{benchmark → test/performance}/watch/catalog.json +0 -0
  90. data/test/performance/watch/feed.json +9 -0
  91. data/{benchmark → test/performance}/watch/fluentd.conf +0 -0
  92. data/test/performance/watch/subscribe.json +3 -0
  93. data/test/unit/catalog/test_version1.rb +34 -0
  94. data/test/unit/plugin/collector/test_basic.rb +300 -479
  95. data/test/unit/plugin/collector/test_search.rb +814 -0
  96. data/test/unit/plugin/distributor/test_search.rb +4 -4
  97. data/test/unit/plugin/distributor/test_search_planner.rb +260 -260
  98. data/test/unit/plugin/handler/groonga/test_column_create.rb +15 -1
  99. data/test/unit/plugin/handler/groonga/test_table_create.rb +6 -2
  100. data/test/unit/plugin/handler/groonga/test_table_remove.rb +58 -0
  101. data/test/unit/plugin/handler/test_add.rb +3 -1
  102. data/test/unit/plugin/handler/test_groonga.rb +24 -0
  103. data/test/unit/plugin/handler/test_search.rb +294 -0
  104. data/test/unit/plugin/handler/test_watch.rb +1 -1
  105. data/test/unit/plugin/{adapter → input_adapter}/groonga/test_select.rb +5 -37
  106. data/test/unit/plugin/output_adapter/groonga/test_select.rb +55 -0
  107. metadata +38 -6
@@ -0,0 +1,104 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013-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 "droonga/plugin/collector/basic"
19
+
20
+ module Droonga
21
+ class SearchCollector < BasicCollector
22
+ repository.register("search", self)
23
+
24
+ command :collector_search_gather
25
+ def collector_search_gather(result)
26
+ output = body ? body[input_name] : input_name
27
+ if output.is_a?(Hash)
28
+ elements = output["elements"]
29
+ if elements && elements.is_a?(Hash)
30
+ # phase 1: pre-process
31
+ elements.each do |element, mapper|
32
+ case mapper["type"]
33
+ when "count"
34
+ result[element] = result[mapper["target"]].size
35
+ when "sort"
36
+ # do nothing on this phase!
37
+ end
38
+ end
39
+ # phase 2: post-process
40
+ elements.each do |element, mapper|
41
+ if mapper["no_output"]
42
+ result.delete(element)
43
+ next
44
+ end
45
+
46
+ case mapper["type"]
47
+ when "count"
48
+ # do nothing on this phase!
49
+ when "sort"
50
+ # because "count" type mapper requires all items of the array,
51
+ # I have to apply "sort" type mapper later.
52
+ if result[element]
53
+ result[element] = apply_output_range(result[element], mapper)
54
+ result[element] = apply_output_attributes_and_format(result[element], mapper)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ output = output["output"]
60
+ end
61
+ emit(output, result)
62
+ end
63
+
64
+ def apply_output_attributes_and_format(items, output)
65
+ attributes = output["attributes"]
66
+ if attributes
67
+ format = output["format"]
68
+ if format == "complex"
69
+ items.collect! do |item|
70
+ complex_item = {}
71
+ attributes.each_with_index do |label, index|
72
+ complex_item[label] = item[index]
73
+ end
74
+ complex_item
75
+ end
76
+ else
77
+ items.collect! do |item|
78
+ item[0...attributes.size]
79
+ end
80
+ end
81
+ end
82
+ items
83
+ end
84
+
85
+ command :collector_search_reduce
86
+ def collector_search_reduce(request)
87
+ return unless request
88
+ body[input_name].each do |output, elements|
89
+ value = request
90
+ old_value = output_values[output]
91
+ value = reduce_elements(elements, old_value, request) if old_value
92
+ emit(output, value)
93
+ end
94
+ end
95
+
96
+ def reduce_elements(elements, left_values, right_values)
97
+ result = {}
98
+ elements.each do |key, deal|
99
+ result[key] = reduce(deal, left_values[key], right_values[key])
100
+ end
101
+ result
102
+ end
103
+ end
104
+ end
@@ -39,5 +39,46 @@ module Droonga
39
39
  key = message["body"]["key"] || rand.to_s
40
40
  scatter_all(message, key)
41
41
  end
42
+
43
+ private
44
+ def scatterer(message, key)
45
+ scatterer = super
46
+ scatterer["outputs"] << "success"
47
+ scatterer["outputs"] << "errors"
48
+ scatterer
49
+ end
50
+
51
+ def reducer(message)
52
+ reducer = super
53
+ reducer["body"]["success"] = {
54
+ "success_reduced" => {
55
+ "type" => "and",
56
+ },
57
+ }
58
+ reducer["inputs"] << "success"
59
+ reducer["outputs"] << "success_reduced"
60
+ reducer["body"]["errors"] = {
61
+ "errors_reduced" => {
62
+ "type" => "sum",
63
+ "limit" => -1,
64
+ },
65
+ }
66
+ reducer["inputs"] << "errors"
67
+ reducer["outputs"] << "errors_reduced"
68
+ reducer
69
+ end
70
+
71
+ def gatherer(message)
72
+ gatherer = super
73
+ gatherer["body"]["success_reduced"] = {
74
+ "output" => "success",
75
+ }
76
+ gatherer["inputs"] << "success_reduced"
77
+ gatherer["body"]["errors_reduced"] = {
78
+ "output" => "errors",
79
+ }
80
+ gatherer["inputs"] << "errors_reduced"
81
+ gatherer
82
+ end
42
83
  end
43
84
  end
@@ -45,7 +45,7 @@ module Droonga
45
45
  end
46
46
 
47
47
  gatherer = {
48
- "type" => "gather",
48
+ "type" => "search_gather",
49
49
  "body" => @output_mappers,
50
50
  "inputs" => @output_names, # XXX should be placed in the "body"?
51
51
  "post" => true, # XXX should be placed in the "body"?
@@ -96,7 +96,7 @@ module Droonga
96
96
  transformer = QueryTransformer.new(query)
97
97
 
98
98
  reducer = {
99
- "type" => "reduce",
99
+ "type" => "search_reduce",
100
100
  "body" => {
101
101
  input_name => {
102
102
  output_name => transformer.reducers,
@@ -361,8 +361,8 @@ module Droonga
361
361
  sort_attributes
362
362
  end
363
363
 
364
- ASCENDING_OPERATOR = "<".freeze
365
- DESCENDING_OPERATOR = ">".freeze
364
+ ASCENDING_OPERATOR = "<"
365
+ DESCENDING_OPERATOR = ">"
366
366
 
367
367
  def build_records_reducer
368
368
  attributes = @output["attributes"]
@@ -29,9 +29,47 @@ module Droonga
29
29
  broadcast_all(message)
30
30
  end
31
31
 
32
+ command :table_remove
33
+ def table_remove(message)
34
+ unless message["dataset"]
35
+ raise "dataset must be set. FIXME: This error should return client."
36
+ end
37
+ broadcast_all(message)
38
+ end
39
+
32
40
  command :column_create
33
41
  def column_create(message)
34
42
  broadcast_all(message)
35
43
  end
44
+
45
+ private
46
+ def broadcaster(message)
47
+ broadcaster = super
48
+ broadcaster["outputs"] << "result"
49
+ broadcaster
50
+ end
51
+
52
+ def reducer(message)
53
+ reducer = super
54
+ reducer["type"] = "groonga_reduce"
55
+ reducer["body"]["result"] = {
56
+ "result_reduced" => {
57
+ "type" => "groonga_result",
58
+ },
59
+ }
60
+ reducer["inputs"] << "result"
61
+ reducer["outputs"] << "result_reduced"
62
+ reducer
63
+ end
64
+
65
+ def gatherer(message)
66
+ gatherer = super
67
+ gatherer["type"] = "groonga_gather"
68
+ gatherer["body"]["result_reduced"] = {
69
+ "output" => "result",
70
+ }
71
+ gatherer["inputs"] << "result_reduced"
72
+ gatherer
73
+ end
36
74
  end
37
75
  end
@@ -59,7 +59,10 @@ module Droonga
59
59
 
60
60
  command :add
61
61
  def add(message, messenger)
62
- outputs = process_add(message.request)
62
+ succeeded = process_add(message.request)
63
+ outputs = {
64
+ "success" => succeeded,
65
+ }
63
66
  messenger.emit(outputs)
64
67
  end
65
68
 
@@ -25,6 +25,13 @@ module Droonga
25
25
  command_class = Groonga::Command.find("column_create")
26
26
  @command = command_class.new("column_create", request)
27
27
 
28
+ table_name = @command["table"]
29
+ if table_name.nil? || @context[table_name].nil?
30
+ raise CommandError.new(:status => Status::INVALID_ARGUMENT,
31
+ :message => "table doesn't exist: <#{table_name.to_s}>",
32
+ :result => false)
33
+ end
34
+
28
35
  if @command.column_index?
29
36
  define_index
30
37
  else
@@ -0,0 +1,42 @@
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 "groonga"
19
+ require "groonga/command/table-remove"
20
+
21
+ module Droonga
22
+ class GroongaHandler
23
+ class TableRemove < Command
24
+ def process_request(request)
25
+ command_class = Groonga::Command.find("table_remove")
26
+ @command = command_class.new("table_remove", request)
27
+
28
+ name = @command["name"]
29
+ if name.nil? || @context[name].nil?
30
+ raise CommandError.new(:status => Status::INVALID_ARGUMENT,
31
+ :message => "table not found",
32
+ :result => false)
33
+ end
34
+
35
+ Groonga::Schema.define(:context => @context) do |schema|
36
+ schema.remove_table(name)
37
+ end
38
+ true
39
+ end
40
+ end
41
+ end
42
+ end
@@ -26,14 +26,21 @@ module Droonga
26
26
  command :table_create
27
27
  def table_create(message, messenger)
28
28
  command = TableCreate.new(@context)
29
- outputs = command.execute(message.request)
29
+ outputs = format_outputs(command.execute(message.request))
30
+ messenger.emit(outputs)
31
+ end
32
+
33
+ command :table_remove
34
+ def table_remove(message, messenger)
35
+ command = TableRemove.new(@context)
36
+ outputs = format_outputs(command.execute(message.request))
30
37
  messenger.emit(outputs)
31
38
  end
32
39
 
33
40
  command :column_create
34
41
  def column_create(message, messenger)
35
42
  command = ColumnCreate.new(@context)
36
- outputs = command.execute(message.request)
43
+ outputs = format_outputs(command.execute(message.request))
37
44
  messenger.emit(outputs)
38
45
  end
39
46
 
@@ -41,6 +48,13 @@ module Droonga
41
48
  return true
42
49
  end
43
50
 
51
+ private
52
+ def format_outputs(result)
53
+ {
54
+ "result" => result,
55
+ }
56
+ end
57
+
44
58
  module Status
45
59
  SUCCESS = 0
46
60
  INVALID_ARGUMENT = -22
@@ -81,4 +95,5 @@ module Droonga
81
95
  end
82
96
 
83
97
  require "droonga/plugin/handler/groonga/table_create"
98
+ require "droonga/plugin/handler/groonga/table_remove"
84
99
  require "droonga/plugin/handler/groonga/column_create"
@@ -75,13 +75,13 @@ module Droonga
75
75
  def feed(message, messenger)
76
76
  request = message.request
77
77
  @watcher.feed(:targets => request["targets"]) do |route, subscribers|
78
- notification_message = {
78
+ published_message = {
79
79
  "to" => subscribers,
80
80
  "body" => request,
81
81
  }
82
- notification_message = message.raw.merge(notification_message)
83
- messenger.forward(notification_message,
84
- "to" => route, "type" => "watch.notification")
82
+ published_message = message.raw.merge(published_message)
83
+ messenger.forward(published_message,
84
+ "to" => route, "type" => "watch.publish")
85
85
  end
86
86
  end
87
87
 
@@ -0,0 +1,27 @@
1
+ # Copyright (C) 2014 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 "droonga/input_adapter_plugin"
17
+
18
+ module Droonga
19
+ class CRUDInputAdapter < Droonga::InputAdapterPlugin
20
+ repository.register("crud", self)
21
+
22
+ command :add
23
+ def add(input_message)
24
+ input_message.add_route("crud_generic_response")
25
+ end
26
+ end
27
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 2013-2014 Droonga Project
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,21 @@ module Droonga
28
28
  input_message.command = "search"
29
29
  input_message.body = search_request
30
30
  end
31
+
32
+ command :table_create
33
+ def table_create(input_message)
34
+ input_message.add_route("groonga_generic_response")
35
+ end
36
+
37
+ command :table_remove
38
+ def table_remove(input_message)
39
+ input_message.add_route("groonga_generic_response")
40
+ end
41
+
42
+ command :column_create
43
+ def column_create(input_message)
44
+ input_message.add_route("groonga_generic_response")
45
+ end
31
46
  end
32
47
  end
33
48
 
@@ -0,0 +1,51 @@
1
+ # Copyright (C) 2013-2014 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 "droonga/output_adapter_plugin"
17
+
18
+ module Droonga
19
+ class CRUDOutputAdapter < Droonga::OutputAdapterPlugin
20
+ repository.register("crud", self)
21
+
22
+ command :crud_generic_response
23
+ def crud_generic_response(output_message)
24
+ if output_message.body.include?("errors")
25
+ errors = output_message.body["errors"]
26
+ if errors && !errors.empty?
27
+ output_message.errors = errors
28
+
29
+ status_codes = []
30
+ errors.values.each do |error|
31
+ status_codes << error["statusCode"]
32
+ end
33
+ status_codes = status_codes.uniq
34
+ if status_codes.size == 1
35
+ output_message.status_code = status_codes.first
36
+ else
37
+ output_message.status_code = MessageProcessingError::STATUS_CODE
38
+ end
39
+
40
+ output_message.body = errors.values.first["body"]
41
+ end
42
+ end
43
+ if output_message.body.include?("success")
44
+ success = output_message.body["success"]
45
+ unless success.nil?
46
+ output_message.body = output_message.body["success"]
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 2013-2014 Droonga Project
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,13 @@ module Droonga
24
24
  command = Select.new
25
25
  output_message.body = command.convert(output_message.body)
26
26
  end
27
+
28
+ command :groonga_generic_response
29
+ def groonga_generic_response(output_message)
30
+ if output_message.body.include?("result")
31
+ output_message.body = output_message.body["result"]
32
+ end
33
+ end
27
34
  end
28
35
  end
29
36
 
@@ -37,7 +37,7 @@ module Droonga
37
37
  rescue => exception
38
38
  process_error(command, exception, arguments)
39
39
  end
40
-
40
+
41
41
  private
42
42
  def run_command(command, *arguments)
43
43
  __send__(self.class.method_name(command), *arguments)
@@ -15,6 +15,8 @@
15
15
 
16
16
  module Droonga
17
17
  class Replier
18
+ STATUS_OK = 200
19
+
18
20
  def initialize(forwarder)
19
21
  @forwarder = forwarder
20
22
  end
@@ -24,10 +26,14 @@ module Droonga
24
26
  destination = message["replyTo"]
25
27
  reply_message = {
26
28
  "inReplyTo" => message["id"],
27
- "statusCode" => message["statusCode"] || 200,
29
+ "statusCode" => message["statusCode"] || STATUS_OK,
28
30
  "type" => destination["type"],
29
31
  "body" => message["body"],
30
32
  }
33
+ if message.include?("errors")
34
+ errors = message["errors"]
35
+ reply_message["errors"] = errors unless errors.empty?
36
+ end
31
37
  @forwarder.forward(reply_message, destination)
32
38
  $log.trace("#{log_tag}: reply: done")
33
39
  end