fluent-plugin-droonga 0.9.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.dir-locals.el +3 -0
  3. data/.travis.yml +6 -2
  4. data/README.md +6 -7
  5. data/Rakefile +23 -6
  6. data/fluent-plugin-droonga.gemspec +2 -2
  7. data/lib/droonga/adapter.rb +12 -3
  8. data/lib/droonga/adapter_runner.rb +28 -23
  9. data/lib/droonga/catalog/base.rb +7 -111
  10. data/lib/droonga/catalog/dataset.rb +13 -25
  11. data/lib/droonga/catalog/errors.rb +94 -0
  12. data/lib/droonga/catalog/schema.rb +277 -0
  13. data/lib/droonga/catalog/version1.rb +404 -0
  14. data/lib/droonga/catalog/version2.rb +160 -0
  15. data/lib/droonga/catalog_loader.rb +27 -4
  16. data/lib/droonga/catalog_observer.rb +44 -6
  17. data/lib/droonga/collector.rb +12 -10
  18. data/lib/droonga/{handler_plugin.rb → collector_message.rb} +47 -20
  19. data/lib/droonga/collector_runner.rb +64 -0
  20. data/lib/droonga/collectors.rb +18 -0
  21. data/lib/droonga/{catalog.rb → collectors/add.rb} +9 -7
  22. data/lib/droonga/{command_repository.rb → collectors/and.rb} +7 -14
  23. data/lib/droonga/collectors/sum.rb +26 -0
  24. data/lib/droonga/dispatcher.rb +74 -41
  25. data/lib/droonga/distributed_command_planner.rb +2 -2
  26. data/lib/droonga/engine.rb +13 -5
  27. data/lib/droonga/{message_processing_error.rb → error.rb} +33 -12
  28. data/lib/droonga/{plugin/planner/search.rb → error_messages.rb} +12 -10
  29. data/lib/droonga/farm.rb +15 -14
  30. data/lib/droonga/fluent_message_sender.rb +15 -11
  31. data/lib/droonga/forwarder.rb +22 -18
  32. data/lib/droonga/handler.rb +8 -2
  33. data/lib/droonga/handler_runner.rb +47 -26
  34. data/lib/droonga/input_message.rb +6 -6
  35. data/lib/droonga/{command.rb → loggable.rb} +7 -14
  36. data/lib/droonga/logger.rb +56 -15
  37. data/lib/droonga/message_matcher.rb +12 -7
  38. data/lib/droonga/message_pusher.rb +8 -4
  39. data/lib/droonga/message_receiver.rb +11 -9
  40. data/lib/droonga/output_message.rb +2 -0
  41. data/lib/droonga/planner.rb +21 -10
  42. data/lib/droonga/plugin.rb +15 -0
  43. data/lib/droonga/plugin/metadata/{adapter_message.rb → adapter_input_message.rb} +6 -14
  44. data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
  45. data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
  46. data/lib/droonga/plugin/metadata/input_message.rb +15 -0
  47. data/lib/droonga/plugin_loader.rb +33 -25
  48. data/lib/droonga/plugin_registry.rb +9 -1
  49. data/lib/droonga/plugins/basic.rb +54 -0
  50. data/lib/droonga/plugins/crud.rb +36 -15
  51. data/lib/droonga/plugins/error.rb +5 -4
  52. data/lib/droonga/plugins/groonga.rb +9 -6
  53. data/lib/droonga/plugins/groonga/column_create.rb +10 -5
  54. data/lib/droonga/plugins/groonga/generic_command.rb +2 -8
  55. data/lib/droonga/plugins/groonga/generic_response.rb +2 -2
  56. data/lib/droonga/plugins/groonga/select.rb +2 -2
  57. data/lib/droonga/plugins/groonga/table_create.rb +9 -4
  58. data/lib/droonga/plugins/groonga/table_remove.rb +10 -5
  59. data/lib/droonga/plugins/search.rb +106 -5
  60. data/lib/droonga/plugins/search/distributed_search_planner.rb +398 -0
  61. data/lib/droonga/plugins/watch.rb +41 -20
  62. data/lib/droonga/processor.rb +12 -9
  63. data/lib/droonga/{plugin/collector/basic.rb → reducer.rb} +36 -50
  64. data/lib/droonga/replier.rb +7 -4
  65. data/lib/droonga/searcher.rb +40 -37
  66. data/lib/droonga/server.rb +8 -6
  67. data/lib/droonga/session.rb +17 -7
  68. data/lib/droonga/single_step.rb +53 -0
  69. data/lib/droonga/{plugin/planner/watch.rb → single_step_definition.rb} +27 -26
  70. data/lib/droonga/{partition.rb → slice.rb} +23 -12
  71. data/lib/droonga/status_code.rb +25 -0
  72. data/lib/droonga/step_runner.rb +63 -0
  73. data/lib/droonga/watch_schema.rb +7 -3
  74. data/lib/droonga/watcher.rb +4 -4
  75. data/lib/droonga/worker.rb +6 -6
  76. data/lib/fluent/plugin/out_droonga.rb +27 -2
  77. data/sample/cluster/catalog.json +33 -32
  78. data/test/command/config/default/catalog.json +72 -45
  79. data/test/command/config/version1/catalog.json +68 -0
  80. data/test/command/config/version1/fluentd.conf +11 -0
  81. data/test/command/suite/message/error/missing-dataset.expected +1 -1
  82. data/test/command/suite/message/error/unknown-dataset.expected +1 -1
  83. data/test/command/suite/message/error/unknown-type.expected +13 -0
  84. data/test/command/suite/message/error/{unknown-command.test → unknown-type.test} +1 -1
  85. data/test/command/suite/search/error/missing-source-parameter.expected +1 -1
  86. data/test/command/suite/search/error/unknown-source.expected +15 -3
  87. data/test/command/suite/watch/subscribe.expected +1 -3
  88. data/test/command/suite/watch/unsubscribe.expected +1 -3
  89. data/test/performance/watch/catalog.json +1 -0
  90. data/test/unit/catalog/test_dataset.rb +16 -358
  91. data/test/unit/catalog/test_schema.rb +285 -0
  92. data/test/unit/catalog/test_version1.rb +222 -28
  93. data/test/unit/catalog/test_version2.rb +155 -0
  94. data/test/unit/fixtures/catalog/version2.json +62 -0
  95. data/test/unit/helper/distributed_search_planner_helper.rb +2 -2
  96. data/test/unit/plugins/crud/test_add.rb +13 -13
  97. data/test/unit/plugins/groonga/test_column_create.rb +14 -11
  98. data/test/unit/plugins/groonga/test_table_create.rb +4 -9
  99. data/test/unit/plugins/groonga/test_table_remove.rb +4 -9
  100. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_basic.rb +0 -0
  101. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_group_by.rb +0 -0
  102. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_output.rb +0 -0
  103. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_sort_by.rb +0 -0
  104. data/test/unit/{plugin/collector/test_search.rb → plugins/search/test_collector.rb} +40 -39
  105. data/test/unit/plugins/{test_search.rb → search/test_handler.rb} +6 -5
  106. data/test/unit/{plugin/planner/test_search.rb → plugins/search/test_planner.rb} +3 -3
  107. data/test/unit/{plugin/collector → plugins}/test_basic.rb +68 -50
  108. data/test/unit/plugins/test_groonga.rb +2 -15
  109. data/test/unit/plugins/test_watch.rb +25 -22
  110. data/test/unit/test_message_matcher.rb +29 -6
  111. data/test/unit/test_output.rb +4 -0
  112. metadata +58 -50
  113. data/lib/droonga/collector_plugin.rb +0 -50
  114. data/lib/droonga/legacy_pluggable.rb +0 -66
  115. data/lib/droonga/legacy_plugin.rb +0 -57
  116. data/lib/droonga/legacy_plugin_repository.rb +0 -54
  117. data/lib/droonga/planner_plugin.rb +0 -54
  118. data/lib/droonga/plugin/collector/search.rb +0 -98
  119. data/lib/droonga/plugin/planner/crud.rb +0 -49
  120. data/lib/droonga/plugin/planner/distributed_search_planner.rb +0 -393
  121. data/lib/droonga/plugin/planner/groonga.rb +0 -54
  122. data/lib/droonga/plugin_registerable.rb +0 -75
  123. data/test/command/suite/message/error/unknown-command.expected +0 -13
  124. data/test/unit/test_command_repository.rb +0 -39
  125. data/test/unit/test_legacy_plugin.rb +0 -50
  126. data/test/unit/test_legacy_plugin_repository.rb +0 -89
@@ -0,0 +1,18 @@
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/collectors/add"
17
+ require "droonga/collectors/and"
18
+ require "droonga/collectors/sum"
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 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,10 +13,14 @@
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/catalog_loader"
19
-
20
16
  module Droonga
21
- class << self
22
- attr_accessor :catalog
17
+ module Collectors
18
+ class Add
19
+ class << self
20
+ def operator
21
+ "or"
22
+ end
23
+ end
24
+ end
23
25
  end
24
26
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013-2014 Droonga Project
1
+ # Copyright (C) 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
@@ -14,19 +14,12 @@
14
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
15
 
16
16
  module Droonga
17
- class CommandRepository
18
- attr_reader :commands
19
- def initialize
20
- @commands = []
21
- end
22
-
23
- def register(command)
24
- @commands << command
25
- end
26
-
27
- def find(message)
28
- @commands.find do |command|
29
- command.match?(message)
17
+ module Collectors
18
+ class And
19
+ class << self
20
+ def operator
21
+ "and"
22
+ end
30
23
  end
31
24
  end
32
25
  end
@@ -0,0 +1,26 @@
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
+ module Droonga
17
+ module Collectors
18
+ class Sum
19
+ class << self
20
+ def operator
21
+ "sum"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -16,56 +16,54 @@
16
16
  require "English"
17
17
  require "tsort"
18
18
 
19
+ require "droonga/loggable"
19
20
  require "droonga/adapter_runner"
20
- require "droonga/planner"
21
- require "droonga/catalog"
22
- require "droonga/collector"
21
+ require "droonga/collector_runner"
22
+ require "droonga/step_runner"
23
23
  require "droonga/farm"
24
24
  require "droonga/session"
25
25
  require "droonga/replier"
26
- require "droonga/message_processing_error"
27
- require "droonga/catalog_observer"
26
+ require "droonga/error_messages"
28
27
  require "droonga/distributor"
29
28
 
30
29
  module Droonga
31
30
  class Dispatcher
31
+ include Loggable
32
+
32
33
  attr_reader :name
33
34
 
34
- class MissingDatasetParameter < BadRequest
35
+ class MissingDatasetParameter < ErrorMessages::BadRequest
35
36
  def initialize
36
- super("\"dataset\" must be specified.")
37
+ super("Missing required parameter: <dataset>")
37
38
  end
38
39
  end
39
40
 
40
- class UnknownDataset < NotFound
41
+ class UnknownDataset < ErrorMessages::NotFound
41
42
  def initialize(dataset)
42
- super("The dataset #{dataset.inspect} does not exist.")
43
+ super("Unknown dataset: <#{dataset}>")
43
44
  end
44
45
  end
45
46
 
46
- class UnknownCommand < BadRequest
47
- def initialize(command, dataset)
48
- super("The command #{command.inspect} is not available " +
49
- "for the dataset #{dataset.inspect}.")
47
+ class UnknownType < ErrorMessages::BadRequest
48
+ def initialize(type, dataset)
49
+ super("[#{dataset}] Handler not found for the type: <#{type}>")
50
50
  end
51
51
  end
52
52
 
53
- def initialize(options)
53
+ def initialize(catalog, options)
54
+ @catalog = catalog
54
55
  @options = options
55
56
  @name = @options[:name]
56
57
  @loop = EventLoop.new
57
- @catalog_observer = CatalogObserver.new(@loop)
58
58
  @sessions = {}
59
59
  @current_id = 0
60
60
  @local = Regexp.new("^#{@name}")
61
61
  @adapter_runners = create_adapter_runners
62
- @farm = Farm.new(name, @loop, :dispatcher => self)
62
+ @farm = Farm.new(name, @catalog, @loop, :dispatcher => self)
63
63
  @forwarder = Forwarder.new(@loop)
64
64
  @replier = Replier.new(@forwarder)
65
- # TODO: make customizable
66
- @planner = Planner.new(self, ["search", "crud", "groonga", "watch"])
67
- # TODO: make customizable
68
- @collector = Collector.new(["basic", "search"])
65
+ @collector_runners = create_collector_runners
66
+ @step_runners = create_step_runners
69
67
  end
70
68
 
71
69
  def start
@@ -74,12 +72,15 @@ module Droonga
74
72
  @loop_thread = Thread.new do
75
73
  @loop.run
76
74
  end
75
+
76
+ ensure_schema
77
77
  end
78
78
 
79
79
  def shutdown
80
80
  @forwarder.shutdown
81
- @planner.shutdown
82
- @collector.shutdown
81
+ @collector_runners.each_value do |collector_runner|
82
+ collector_runner.shutdown
83
+ end
83
84
  @adapter_runners.each_value do |adapter_runner|
84
85
  adapter_runner.shutdown
85
86
  end
@@ -96,12 +97,12 @@ module Droonga
96
97
  begin
97
98
  assert_valid_message(message)
98
99
  process_input_message(message)
99
- rescue MessageProcessingError => error
100
+ rescue ErrorMessage => error
100
101
  reply("statusCode" => error.status_code,
101
102
  "body" => error.response_body)
102
- rescue => error
103
- Logger.error("failed to process input message", error)
104
- formatted_error = MessageProcessingError.new("Unknown internal error")
103
+ rescue StandardError, LoadError, SyntaxError => error
104
+ logger.exception("failed to process input message", error)
105
+ formatted_error = ErrorMessages::InternalServerError.new("Unknown internal error")
105
106
  reply("statusCode" => formatted_error.status_code,
106
107
  "body" => formatted_error.response_body)
107
108
  raise error
@@ -110,9 +111,9 @@ module Droonga
110
111
  end
111
112
 
112
113
  def forward(message, destination)
113
- $log.trace("#{log_tag}: forward start")
114
+ logger.trace("forward start")
114
115
  @forwarder.forward(message, destination)
115
- $log.trace("#{log_tag}: forward done")
116
+ logger.trace("forward done")
116
117
  end
117
118
 
118
119
  # Replies response to replyTo.
@@ -146,7 +147,9 @@ module Droonga
146
147
  steps = message["steps"]
147
148
  if steps
148
149
  session_planner = SessionPlanner.new(self, steps)
149
- session = session_planner.create_session(id, @collector)
150
+ dataset = message["dataset"] || @message["dataset"]
151
+ collector_runner = @collector_runners[dataset]
152
+ session = session_planner.create_session(id, collector_runner)
150
153
  @sessions[id] = session
151
154
  else
152
155
  #todo: take cases receiving result before its query into account
@@ -172,7 +175,7 @@ module Droonga
172
175
  steps.each do |step|
173
176
  dataset = step["dataset"]
174
177
  if dataset
175
- routes = Droonga.catalog.get_routes(dataset, step)
178
+ routes = @catalog.get_routes(dataset, step)
176
179
  step["routes"] = routes
177
180
  else
178
181
  step["routes"] ||= [id]
@@ -190,7 +193,7 @@ module Droonga
190
193
 
191
194
  def process_local_message(local_message)
192
195
  task = local_message["task"]
193
- partition_name = task["route"]
196
+ slice_name = task["route"]
194
197
  step = task["step"]
195
198
  command = step["command"]
196
199
  descendants = {}
@@ -202,7 +205,7 @@ module Droonga
202
205
  local_message["descendants"] = descendants
203
206
  farm_message = @message.merge("body" => local_message,
204
207
  "type" => command)
205
- @farm.process(partition_name, farm_message)
208
+ @farm.process(slice_name, farm_message)
206
209
  end
207
210
 
208
211
  def local?(route)
@@ -228,11 +231,13 @@ module Droonga
228
231
  dataset = message["dataset"]
229
232
  adapter_runner = @adapter_runners[dataset]
230
233
  adapted_message = adapter_runner.adapt_input(message)
231
- plan = @planner.process(adapted_message["type"], adapted_message)
234
+ step_runner = @step_runners[dataset]
235
+ plan = step_runner.plan(message)
232
236
  distributor = Distributor.new(self)
233
237
  distributor.distribute(plan)
234
- rescue Droonga::LegacyPluggable::UnknownPlugin => error
235
- raise UnknownCommand.new(error.command, message["dataset"])
238
+ rescue Droonga::UnsupportedMessageError => error
239
+ target_message = error.message
240
+ raise UnknownType.new(target_message["type"], target_message["dataset"])
236
241
  end
237
242
 
238
243
  def assert_valid_message(message)
@@ -240,19 +245,47 @@ module Droonga
240
245
  raise MissingDatasetParameter.new
241
246
  end
242
247
  dataset = message["dataset"]
243
- unless Droonga.catalog.have_dataset?(dataset)
248
+ unless @catalog.have_dataset?(dataset)
244
249
  raise UnknownDataset.new(dataset)
245
250
  end
246
251
  end
247
252
 
248
- def create_adapter_runners
253
+ def create_runners
249
254
  runners = {}
250
- Droonga.catalog.datasets.each do |name, configuration|
251
- runners[name] = AdapterRunner.new(self, configuration["plugins"] || [])
255
+ @catalog.datasets.each do |name, configuration|
256
+ runners[name] = yield(configuration)
252
257
  end
253
258
  runners
254
259
  end
255
260
 
261
+ def create_adapter_runners
262
+ create_runners do |configuration|
263
+ AdapterRunner.new(self, configuration["plugins"] || [])
264
+ end
265
+ end
266
+
267
+ def create_collector_runners
268
+ create_runners do |configuration|
269
+ CollectorRunner.new(configuration["plugins"] || [])
270
+ end
271
+ end
272
+
273
+ def create_step_runners
274
+ create_runners do |configuration|
275
+ StepRunner.new(configuration["plugins"] || [])
276
+ end
277
+ end
278
+
279
+ def ensure_schema
280
+ @catalog.datasets.each do |name, dataset|
281
+ schema = dataset.schema
282
+ messages = schema.to_messages
283
+ messages.each do |message|
284
+ process_message(message)
285
+ end
286
+ end
287
+ end
288
+
256
289
  def log_tag
257
290
  "[#{Process.ppid}][#{Process.pid}] dispatcher"
258
291
  end
@@ -265,7 +298,7 @@ module Droonga
265
298
  @steps = steps
266
299
  end
267
300
 
268
- def create_session(id, collector)
301
+ def create_session(id, collector_runner)
269
302
  resolve_descendants
270
303
  tasks = []
271
304
  inputs = {}
@@ -285,7 +318,7 @@ module Droonga
285
318
  end
286
319
  end
287
320
  end
288
- Session.new(id, @dispatcher, collector, tasks, inputs)
321
+ Session.new(id, @dispatcher, collector_runner, tasks, inputs)
289
322
  end
290
323
 
291
324
  def resolve_descendants
@@ -45,7 +45,7 @@ module Droonga
45
45
  return unless params
46
46
  params.each do |name, reducer|
47
47
  gatherer = nil
48
- if reducer.is_a?(Hash) && reducer[:gather]
48
+ if reducer.is_a?(Hash) and reducer[:gather]
49
49
  gatherer = reducer[:gather]
50
50
  reducer = reducer[:reduce]
51
51
  end
@@ -127,7 +127,7 @@ module Droonga
127
127
  def fixed_processor
128
128
  @processor["outputs"] = @outputs
129
129
  if @processor["type"] == "scatter"
130
- raise MessageProcessingError.new("missing key") unless @key
130
+ raise ErrorMessages::InternalServerError.new("missing key") unless @key
131
131
  @processor["key"] = @key
132
132
  end
133
133
  @processor
@@ -15,14 +15,17 @@
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/logger"
18
+ require "droonga/loggable"
19
19
  require "droonga/dispatcher"
20
20
 
21
21
  module Droonga
22
22
  class Engine
23
- def initialize(options={})
23
+ include Loggable
24
+
25
+ def initialize(catalog, options={})
26
+ @catalog = catalog
24
27
  @options = options
25
- @dispatcher = Dispatcher.new(@options)
28
+ @dispatcher = Dispatcher.new(@catalog, @options)
26
29
  end
27
30
 
28
31
  def start
@@ -30,13 +33,18 @@ module Droonga
30
33
  end
31
34
 
32
35
  def shutdown
33
- $log.trace("engine: shutdown: start")
36
+ logger.trace("shutdown: start")
34
37
  @dispatcher.shutdown
35
- $log.trace("engine: shutdown: done")
38
+ logger.trace("shutdown: done")
36
39
  end
37
40
 
38
41
  def process(message)
39
42
  @dispatcher.process_message(message)
40
43
  end
44
+
45
+ private
46
+ def log_tag
47
+ "engine"
48
+ end
41
49
  end
42
50
  end
@@ -1,4 +1,6 @@
1
- # Copyright (C) 2013 Droonga Project
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2014 Droonga Project
2
4
  #
3
5
  # This library is free software; you can redistribute it and/or
4
6
  # modify it under the terms of the GNU Lesser General Public
@@ -14,14 +16,31 @@
14
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
17
 
16
18
  module Droonga
17
- class MessageProcessingError < StandardError
18
- STATUS_CODE = 500
19
+ class Error < StandardError
20
+ end
21
+
22
+ class MultiplexError < Error
23
+ attr_reader :errors
24
+
25
+ def initialize(errors=[])
26
+ @errors = errors
27
+ error_messages = @errors.collect do |error|
28
+ error.message
29
+ end
30
+ message = error_messages.sort.join("\n-----------------------\n")
31
+ super(message)
32
+ end
33
+ end
19
34
 
20
- attr_reader :message, :detail
35
+ # the base class for any error which can be described as a Droonga message
36
+ class ErrorMessage < Error
37
+ STATUS_CODE = nil
38
+
39
+ attr_reader :detail
21
40
 
22
41
  def initialize(message, detail=nil)
23
- @message = message
24
42
  @detail = detail
43
+ super(message)
25
44
  end
26
45
 
27
46
  def name
@@ -35,18 +54,20 @@ module Droonga
35
54
  def response_body
36
55
  body = {
37
56
  "name" => name,
38
- "message" => @message,
57
+ "message" => message,
39
58
  }
40
59
  body["detail"] = @detail unless @detail.nil?
41
60
  body
42
61
  end
43
62
  end
44
63
 
45
- class BadRequest < MessageProcessingError
46
- STATUS_CODE = 400
47
- end
48
-
49
- class NotFound < MessageProcessingError
50
- STATUS_CODE = 404
64
+ # TODO: Move to common file for runners
65
+ class UnsupportedMessageError < Error
66
+ attr_reader :phase, :message
67
+ def initialize(phase, message)
68
+ @phase = phase
69
+ @message = message
70
+ super("[#{@phase}] Unsupported message: #{@message.inspect}")
71
+ end
51
72
  end
52
73
  end