sunspot_padrino 0.1.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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +74 -0
- data/LICENSE.txt +20 -0
- data/README.md +5 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/generators/sunspot.rb +57 -0
- data/generators/templates/sunspot.yml +22 -0
- data/lib/sunspot/padrino.rb +73 -0
- data/lib/sunspot/padrino/adapters.rb +90 -0
- data/lib/sunspot/padrino/configuration.rb +404 -0
- data/lib/sunspot/padrino/init.rb +8 -0
- data/lib/sunspot/padrino/request_lifecycle.rb +36 -0
- data/lib/sunspot/padrino/searchable.rb +497 -0
- data/lib/sunspot/padrino/server.rb +99 -0
- data/lib/sunspot/padrino/solr_instrumentation.rb +21 -0
- data/lib/sunspot/padrino/spec_helper.rb +26 -0
- data/lib/sunspot/padrino/stub_session_proxy.rb +168 -0
- data/lib/sunspot/padrino/tasks.rb +67 -0
- data/lib/sunspot_padrino.rb +14 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/sunspot_padrino_spec.rb +7 -0
- metadata +143 -0
@@ -0,0 +1,404 @@
|
|
1
|
+
module Sunspot #:nodoc:
|
2
|
+
module Padrino #:nodoc:
|
3
|
+
#
|
4
|
+
# Sunspot::Padrino is configured via the config/sunspot.yml file, which
|
5
|
+
# contains properties keyed by environment name. A sample sunspot.yml file
|
6
|
+
# would look like:
|
7
|
+
#
|
8
|
+
# development:
|
9
|
+
# solr:
|
10
|
+
# hostname: localhost
|
11
|
+
# port: 8982
|
12
|
+
# min_memory: 512M
|
13
|
+
# max_memory: 1G
|
14
|
+
# solr_jar: /some/path/solr15/start.jar
|
15
|
+
# bind_address: 0.0.0.0
|
16
|
+
# disabled: false
|
17
|
+
# test:
|
18
|
+
# solr:
|
19
|
+
# hostname: localhost
|
20
|
+
# port: 8983
|
21
|
+
# log_level: OFF
|
22
|
+
# open_timeout: 0.5
|
23
|
+
# read_timeout: 2
|
24
|
+
# production:
|
25
|
+
# solr:
|
26
|
+
# scheme: http
|
27
|
+
# user: username
|
28
|
+
# pass: password
|
29
|
+
# hostname: localhost
|
30
|
+
# port: 8983
|
31
|
+
# path: /solr/myindex
|
32
|
+
# log_level: WARNING
|
33
|
+
# solr_home: /some/path
|
34
|
+
# open_timeout: 0.5
|
35
|
+
# read_timeout: 2
|
36
|
+
# master_solr:
|
37
|
+
# hostname: localhost
|
38
|
+
# port: 8982
|
39
|
+
# path: /solr
|
40
|
+
# auto_commit_after_request: true
|
41
|
+
#
|
42
|
+
# Sunspot::Padrino uses the configuration to set up the Solr connection, as
|
43
|
+
# well as for starting Solr with the appropriate port using the
|
44
|
+
# <code>rake sunspot:solr:start</code> task.
|
45
|
+
#
|
46
|
+
# If the <code>master_solr</code> configuration is present, Sunspot will use
|
47
|
+
# the Solr instance specified here for all write operations, and the Solr
|
48
|
+
# configured under <code>solr</code> for all read operations.
|
49
|
+
#
|
50
|
+
class Configuration
|
51
|
+
# ActiveSupport log levels are integers; this array maps them to the
|
52
|
+
# appropriate java.util.logging.Level constant
|
53
|
+
LOG_LEVELS = %w(FINE INFO WARNING SEVERE SEVERE INFO)
|
54
|
+
|
55
|
+
attr_writer :user_configuration
|
56
|
+
#
|
57
|
+
# The host name at which to connect to Solr. Default 'localhost'.
|
58
|
+
#
|
59
|
+
# ==== Returns
|
60
|
+
#
|
61
|
+
# String:: host name
|
62
|
+
#
|
63
|
+
def hostname
|
64
|
+
unless defined?(@hostname)
|
65
|
+
@hostname = solr_url.host if solr_url
|
66
|
+
@hostname ||= user_configuration_from_key('solr', 'hostname')
|
67
|
+
@hostname ||= default_hostname
|
68
|
+
end
|
69
|
+
@hostname
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# The port at which to connect to Solr.
|
74
|
+
# Defaults to 8981 in test, 8982 in development and 8983 in production.
|
75
|
+
#
|
76
|
+
# ==== Returns
|
77
|
+
#
|
78
|
+
# Integer:: port
|
79
|
+
#
|
80
|
+
def port
|
81
|
+
unless defined?(@port)
|
82
|
+
@port = solr_url.port if solr_url
|
83
|
+
@port ||= user_configuration_from_key('solr', 'port')
|
84
|
+
@port ||= default_port
|
85
|
+
@port = @port.to_i
|
86
|
+
end
|
87
|
+
@port
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# The scheme to use, http or https.
|
92
|
+
# Defaults to http
|
93
|
+
#
|
94
|
+
# ==== Returns
|
95
|
+
#
|
96
|
+
# String:: scheme
|
97
|
+
#
|
98
|
+
def scheme
|
99
|
+
unless defined?(@scheme)
|
100
|
+
@scheme = solr_url.scheme if solr_url
|
101
|
+
@scheme ||= user_configuration_from_key('solr', 'scheme')
|
102
|
+
@scheme ||= default_scheme
|
103
|
+
end
|
104
|
+
@scheme
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# The userinfo used for authentication, a colon-delimited string like "user:pass"
|
109
|
+
# Defaults to nil, which means no authentication
|
110
|
+
#
|
111
|
+
# ==== Returns
|
112
|
+
#
|
113
|
+
# String:: userinfo
|
114
|
+
#
|
115
|
+
def userinfo
|
116
|
+
unless defined?(@userinfo)
|
117
|
+
@userinfo = solr_url.userinfo if solr_url
|
118
|
+
user = user_configuration_from_key('solr', 'user')
|
119
|
+
pass = user_configuration_from_key('solr', 'pass')
|
120
|
+
@userinfo ||= [ user, pass ].compact.join(":") if user && pass
|
121
|
+
@userinfo ||= default_userinfo
|
122
|
+
end
|
123
|
+
@userinfo
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# The url path to the Solr servlet (useful if you are running multicore).
|
128
|
+
# Default '/solr/default'.
|
129
|
+
#
|
130
|
+
# ==== Returns
|
131
|
+
#
|
132
|
+
# String:: path
|
133
|
+
#
|
134
|
+
def path
|
135
|
+
unless defined?(@path)
|
136
|
+
@path = solr_url.path if solr_url
|
137
|
+
@path ||= user_configuration_from_key('solr', 'path')
|
138
|
+
@path ||= default_path
|
139
|
+
end
|
140
|
+
@path
|
141
|
+
end
|
142
|
+
|
143
|
+
#
|
144
|
+
# The host name at which to connect to the master Solr instance. Defaults
|
145
|
+
# to the 'hostname' configuration option.
|
146
|
+
#
|
147
|
+
# ==== Returns
|
148
|
+
#
|
149
|
+
# String:: host name
|
150
|
+
#
|
151
|
+
def master_hostname
|
152
|
+
@master_hostname ||= (user_configuration_from_key('master_solr', 'hostname') || hostname)
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# The port at which to connect to the master Solr instance. Defaults to
|
157
|
+
# the 'port' configuration option.
|
158
|
+
#
|
159
|
+
# ==== Returns
|
160
|
+
#
|
161
|
+
# Integer:: port
|
162
|
+
#
|
163
|
+
def master_port
|
164
|
+
@master_port ||= (user_configuration_from_key('master_solr', 'port') || port).to_i
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# The path to the master Solr servlet (useful if you are running multicore).
|
169
|
+
# Defaults to the value of the 'path' configuration option.
|
170
|
+
#
|
171
|
+
# ==== Returns
|
172
|
+
#
|
173
|
+
# String:: path
|
174
|
+
#
|
175
|
+
def master_path
|
176
|
+
@master_path ||= (user_configuration_from_key('master_solr', 'path') || path)
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# True if there is a master Solr instance configured, otherwise false.
|
181
|
+
#
|
182
|
+
# ==== Returns
|
183
|
+
#
|
184
|
+
# Boolean:: bool
|
185
|
+
#
|
186
|
+
def has_master?
|
187
|
+
@has_master = !!user_configuration_from_key('master_solr')
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
# The default log_level that should be passed to solr. You can
|
192
|
+
# change the individual log_levels in the solr admin interface.
|
193
|
+
# If no level is specified in the sunspot configuration file,
|
194
|
+
# use a level similar to Padrino own logging level.
|
195
|
+
#
|
196
|
+
# ==== Returns
|
197
|
+
#
|
198
|
+
# String:: log_level
|
199
|
+
#
|
200
|
+
def log_level
|
201
|
+
@log_level ||= (
|
202
|
+
user_configuration_from_key('solr', 'log_level') ||
|
203
|
+
LOG_LEVELS[::Padrino.logger.level]
|
204
|
+
)
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# Should the solr index receive a commit after each http-request.
|
209
|
+
# Default true
|
210
|
+
#
|
211
|
+
# ==== Returns
|
212
|
+
#
|
213
|
+
# Boolean: auto_commit_after_request?
|
214
|
+
#
|
215
|
+
def auto_commit_after_request?
|
216
|
+
@auto_commit_after_request ||=
|
217
|
+
user_configuration_from_key('auto_commit_after_request') != false
|
218
|
+
end
|
219
|
+
|
220
|
+
#
|
221
|
+
# As for #auto_commit_after_request? but only for deletes
|
222
|
+
# Default false
|
223
|
+
#
|
224
|
+
# ==== Returns
|
225
|
+
#
|
226
|
+
# Boolean: auto_commit_after_delete_request?
|
227
|
+
#
|
228
|
+
def auto_commit_after_delete_request?
|
229
|
+
@auto_commit_after_delete_request ||=
|
230
|
+
(user_configuration_from_key('auto_commit_after_delete_request') || false)
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
#
|
235
|
+
# The log directory for solr logfiles
|
236
|
+
#
|
237
|
+
# ==== Returns
|
238
|
+
#
|
239
|
+
# String:: log_dir
|
240
|
+
#
|
241
|
+
def log_file
|
242
|
+
@log_file ||= (user_configuration_from_key('solr', 'log_file') || default_log_file_location )
|
243
|
+
end
|
244
|
+
|
245
|
+
def data_path
|
246
|
+
@data_path ||= user_configuration_from_key('solr', 'data_path') || File.join(::Padrino.root, 'solr', 'data', ::Padrino.env)
|
247
|
+
end
|
248
|
+
|
249
|
+
def pid_dir
|
250
|
+
@pid_dir ||= user_configuration_from_key('solr', 'pid_dir') || File.join(::Padrino.root, 'solr', 'pids', ::Padrino.env)
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
#
|
255
|
+
# The solr home directory. Sunspot::Padrino expects this directory
|
256
|
+
# to contain a config, data and pids directory. See
|
257
|
+
# Sunspot::Padrino::Server.bootstrap for more information.
|
258
|
+
#
|
259
|
+
# ==== Returns
|
260
|
+
#
|
261
|
+
# String:: solr_home
|
262
|
+
#
|
263
|
+
def solr_home
|
264
|
+
@solr_home ||=
|
265
|
+
if user_configuration_from_key('solr', 'solr_home')
|
266
|
+
user_configuration_from_key('solr', 'solr_home')
|
267
|
+
else
|
268
|
+
File.join(::Padrino.root, 'solr')
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
#
|
273
|
+
# Solr start jar
|
274
|
+
#
|
275
|
+
def solr_jar
|
276
|
+
@solr_jar ||= user_configuration_from_key('solr', 'solr_jar')
|
277
|
+
end
|
278
|
+
|
279
|
+
#
|
280
|
+
# Minimum java heap size for Solr instance
|
281
|
+
#
|
282
|
+
def min_memory
|
283
|
+
@min_memory ||= user_configuration_from_key('solr', 'min_memory')
|
284
|
+
end
|
285
|
+
|
286
|
+
#
|
287
|
+
# Maximum java heap size for Solr instance
|
288
|
+
#
|
289
|
+
def max_memory
|
290
|
+
@max_memory ||= user_configuration_from_key('solr', 'max_memory')
|
291
|
+
end
|
292
|
+
|
293
|
+
#
|
294
|
+
# Interface on which to run Solr
|
295
|
+
#
|
296
|
+
def bind_address
|
297
|
+
@bind_address ||= user_configuration_from_key('solr', 'bind_address')
|
298
|
+
end
|
299
|
+
|
300
|
+
def read_timeout
|
301
|
+
@read_timeout ||= user_configuration_from_key('solr', 'read_timeout')
|
302
|
+
end
|
303
|
+
|
304
|
+
def open_timeout
|
305
|
+
@open_timeout ||= user_configuration_from_key('solr', 'open_timeout')
|
306
|
+
end
|
307
|
+
|
308
|
+
#
|
309
|
+
# Whether or not to disable Solr.
|
310
|
+
# Defaults to false.
|
311
|
+
#
|
312
|
+
def disabled?
|
313
|
+
@disabled ||= (user_configuration_from_key('disabled') || false)
|
314
|
+
end
|
315
|
+
|
316
|
+
private
|
317
|
+
|
318
|
+
#
|
319
|
+
# Logging in padrino_root/log as solr_<environment>.log as a
|
320
|
+
# default.
|
321
|
+
#
|
322
|
+
# ===== Returns
|
323
|
+
#
|
324
|
+
# String:: default_log_file_location
|
325
|
+
#
|
326
|
+
def default_log_file_location
|
327
|
+
File.join(::Padrino.root, 'log', "solr_" + ::Padrino.env + ".log")
|
328
|
+
end
|
329
|
+
|
330
|
+
#
|
331
|
+
# return a specific key from the user configuration in config/sunspot.yml
|
332
|
+
#
|
333
|
+
# ==== Returns
|
334
|
+
#
|
335
|
+
# Mixed:: requested_key or nil
|
336
|
+
#
|
337
|
+
def user_configuration_from_key( *keys )
|
338
|
+
keys.inject(user_configuration) do |hash, key|
|
339
|
+
hash[key] if hash
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
#
|
344
|
+
# Memoized hash of configuration options for the current Padrino environment
|
345
|
+
# as specified in config/sunspot.yml
|
346
|
+
#
|
347
|
+
# ==== Returns
|
348
|
+
#
|
349
|
+
# Hash:: configuration options for current environment
|
350
|
+
#
|
351
|
+
def user_configuration
|
352
|
+
@user_configuration ||=
|
353
|
+
begin
|
354
|
+
path = File.join(::Padrino.root, 'config', 'sunspot.yml')
|
355
|
+
if File.exist?(path)
|
356
|
+
File.open(path) do |file|
|
357
|
+
YAML.load(file.read)[::Padrino.env.to_s]
|
358
|
+
end
|
359
|
+
else
|
360
|
+
{}
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
protected
|
366
|
+
|
367
|
+
#
|
368
|
+
# When a specific hostname, port and path aren't provided in the
|
369
|
+
# sunspot.yml file, look for a key named 'url', then check the
|
370
|
+
# environment, then fall back to a sensible localhost default.
|
371
|
+
#
|
372
|
+
|
373
|
+
def solr_url
|
374
|
+
if ENV['SOLR_URL'] || ENV['WEBSOLR_URL']
|
375
|
+
URI.parse(ENV['SOLR_URL'] || ENV['WEBSOLR_URL'])
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def default_hostname
|
380
|
+
'localhost'
|
381
|
+
end
|
382
|
+
|
383
|
+
def default_port
|
384
|
+
{ 'test' => 8981,
|
385
|
+
'development' => 8982,
|
386
|
+
'production' => 8983
|
387
|
+
}[::Padrino.env.to_s] || 8983
|
388
|
+
end
|
389
|
+
|
390
|
+
def default_scheme
|
391
|
+
'http'
|
392
|
+
end
|
393
|
+
|
394
|
+
def default_userinfo
|
395
|
+
nil
|
396
|
+
end
|
397
|
+
|
398
|
+
def default_path
|
399
|
+
'/solr/default'
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'padrino-core/tasks'
|
2
|
+
require 'padrino-gen/command'
|
3
|
+
require 'padrino-core/cli/rake'
|
4
|
+
|
5
|
+
Sunspot.session = Sunspot::Padrino.build_session
|
6
|
+
Sunspot::Adapters::InstanceAdapter.register(Sunspot::Padrino::Adapters::ActiveRecordInstanceAdapter, ActiveRecord::Base)
|
7
|
+
Sunspot::Adapters::DataAccessor.register(Sunspot::Padrino::Adapters::ActiveRecordDataAccessor, ActiveRecord::Base)
|
8
|
+
ActiveRecord::Base.module_eval { include(Sunspot::Padrino::Searchable) }
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Sunspot #:nodoc:
|
2
|
+
module Padrino #:nodoc:
|
3
|
+
#
|
4
|
+
# This module adds an after_filter to ActionController::Base that commits
|
5
|
+
# the Sunspot session if any documents have been added, changed, or removed
|
6
|
+
# in the course of the request.
|
7
|
+
#
|
8
|
+
module RequestLifecycle
|
9
|
+
class <<self
|
10
|
+
def included(base) #:nodoc:
|
11
|
+
subclasses = base.subclasses.map do |subclass|
|
12
|
+
begin
|
13
|
+
subclass.constantize
|
14
|
+
rescue NameError
|
15
|
+
end
|
16
|
+
end.compact
|
17
|
+
loaded_controllers = [base].concat(subclasses)
|
18
|
+
# Depending on how Sunspot::Padrino is loaded, there may already be
|
19
|
+
# controllers loaded into memory that subclass this controller. In
|
20
|
+
# this case, since after_filter uses the inheritable_attribute
|
21
|
+
# structure, the already-loaded subclasses don't get the filters. So,
|
22
|
+
# the below ensures that all loaded controllers have the filter.
|
23
|
+
loaded_controllers.each do |controller|
|
24
|
+
controller.after do
|
25
|
+
if Sunspot::Padrino.configuration.auto_commit_after_request?
|
26
|
+
Sunspot.commit_if_dirty
|
27
|
+
elsif Sunspot::Padrino.configuration.auto_commit_after_delete_request?
|
28
|
+
Sunspot.commit_if_delete_dirty
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|