Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cs_comments_service
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
cs_comments_service
Commits
1235e147
Commit
1235e147
authored
Jan 26, 2017
by
Diana Huang
Committed by
GitHub
Jan 26, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #225 from edx/diana/elasticsearch-update
Diana/elasticsearch update
parents
276448e2
e2053333
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
89 additions
and
36 deletions
+89
-36
Gemfile
+1
-0
Gemfile.lock
+3
-0
api/search.rb
+13
-7
app.rb
+21
-2
spec/api/search_spec.rb
+30
-27
spec/app_spec.rb
+13
-0
spec/spec_helper.rb
+1
-0
spec/support/matchers.rb
+7
-0
No files found.
Gemfile
View file @
1235e147
...
@@ -12,6 +12,7 @@ gem 'bundler'
...
@@ -12,6 +12,7 @@ gem 'bundler'
gem
'
rake
'
gem
'
rake
'
gem
'
sinatra
'
gem
'
sinatra
'
gem
'
sinatra-param
'
,
'~> 1.4'
gem
'
yajl-ruby
'
gem
'
yajl-ruby
'
...
...
Gemfile.lock
View file @
1235e147
...
@@ -154,6 +154,8 @@ GEM
...
@@ -154,6 +154,8 @@ GEM
rack (~> 1.3, >= 1.3.6)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
tilt (~> 1.3, >= 1.3.3)
sinatra-param (1.4.0)
sinatra (~> 1.3)
slop (3.3.2)
slop (3.3.2)
thor (0.16.0)
thor (0.16.0)
thread_safe (0.3.5)
thread_safe (0.3.5)
...
@@ -215,6 +217,7 @@ DEPENDENCIES
...
@@ -215,6 +217,7 @@ DEPENDENCIES
rs_voteable_mongo!
rs_voteable_mongo!
rspec (~> 2.11.0)
rspec (~> 2.11.0)
sinatra
sinatra
sinatra-param (~> 1.4)
unicorn
unicorn
webmock (~> 1.22)
webmock (~> 1.22)
will_paginate_mongoid (~> 2.0)
will_paginate_mongoid (~> 2.0)
...
...
api/search.rb
View file @
1235e147
...
@@ -125,14 +125,20 @@ def get_threads(context, group_ids, local_params, search_text)
...
@@ -125,14 +125,20 @@ def get_threads(context, group_ids, local_params, search_text)
result_obj
.
to_json
result_obj
.
to_json
end
end
error
Sinatra
::
Param
::
InvalidParameterError
do
# NOTE (CCB): The current behavior of the service is to return a seemingly positive response
# for an invalid request. In the future the API's contract should be modified so that HTTP 400
# is returned. This informs the client that the request was invalid, rather than having to guess
# about an empty response body.
[
200
,
'{}'
]
end
get
"
#{
APIPREFIX
}
/search/threads"
do
get
"
#{
APIPREFIX
}
/search/threads"
do
param
:text
,
String
,
required:
true
param
:context
,
String
,
default:
'course'
param
:sort_key
,
String
,
in:
%w(activity comments date votes)
,
transform: :downcase
local_params
=
params
# Necessary for params to be available inside blocks
local_params
=
params
# Necessary for params to be available inside blocks
group_ids
=
get_group_ids_from_params
(
local_params
)
group_ids
=
get_group_ids_from_params
(
local_params
)
context
=
local_params
[
"context"
]
?
local_params
[
"context"
]
:
"course"
get_threads
(
params
[
:context
],
group_ids
,
local_params
,
params
[
:text
])
search_text
=
local_params
[
"text"
]
if
!
search_text
'{}'
else
get_threads
(
context
,
group_ids
,
local_params
,
search_text
)
end
end
end
app.rb
View file @
1235e147
...
@@ -27,14 +27,34 @@ if ENV["ENABLE_GC_PROFILER"]
...
@@ -27,14 +27,34 @@ if ENV["ENABLE_GC_PROFILER"]
GC
::
Profiler
.
enable
GC
::
Profiler
.
enable
end
end
def
get_logger
(
progname
,
threshold
=
nil
)
logger
=
Logger
.
new
(
STDERR
)
logger
.
progname
=
progname
logger
.
level
=
threshold
||
Logger
::
INFO
logger
end
application_yaml
=
ERB
.
new
(
File
.
read
(
"config/application.yml"
)).
result
()
application_yaml
=
ERB
.
new
(
File
.
read
(
"config/application.yml"
)).
result
()
CommentService
.
config
=
YAML
.
load
(
application_yaml
).
with_indifferent_access
CommentService
.
config
=
YAML
.
load
(
application_yaml
).
with_indifferent_access
# Raise sinatra-param exceptions so that we can process, and respond to, them appropriately
set
:raise_sinatra_param_exceptions
,
true
# Setup Mongo
Mongoid
.
load!
(
"config/mongoid.yml"
,
environment
)
Mongoid
.
load!
(
"config/mongoid.yml"
,
environment
)
Mongoid
.
logger
.
level
=
Logger
::
INFO
Mongoid
.
logger
.
level
=
Logger
::
INFO
Mongo
::
Logger
.
logger
.
level
=
ENV
[
"ENABLE_MONGO_DEBUGGING"
]
?
Logger
::
DEBUG
:
Logger
::
INFO
Mongo
::
Logger
.
logger
.
level
=
ENV
[
"ENABLE_MONGO_DEBUGGING"
]
?
Logger
::
DEBUG
:
Logger
::
INFO
# set up i18n
# Setup Elasticsearch
# NOTE (CCB): If you want to see all data sent to Elasticsearch (e.g. for debugging purposes), set the tracer argument
# to the value of a logger.
# Example: Elascisearch.Client.new(tracer: get_logger('elasticsearch.tracer'))
Elasticsearch
::
Model
.
client
=
Elasticsearch
::
Client
.
new
(
host:
CommentService
.
config
[
:elasticsearch_server
],
logger:
get_logger
(
'elasticsearch'
,
Logger
::
WARN
)
)
# Setup i18n
I18n
.
load_path
+=
Dir
[
File
.
join
(
File
.
dirname
(
__FILE__
),
'locale'
,
'*.yml'
).
to_s
]
I18n
.
load_path
+=
Dir
[
File
.
join
(
File
.
dirname
(
__FILE__
),
'locale'
,
'*.yml'
).
to_s
]
I18n
.
default_locale
=
CommentService
.
config
[
:default_locale
]
I18n
.
default_locale
=
CommentService
.
config
[
:default_locale
]
I18n
.
enforce_available_locales
=
false
I18n
.
enforce_available_locales
=
false
...
@@ -51,7 +71,6 @@ Dir[File.dirname(__FILE__) + '/lib/**/*.rb'].each { |file| require file }
...
@@ -51,7 +71,6 @@ Dir[File.dirname(__FILE__) + '/lib/**/*.rb'].each { |file| require file }
Dir
[
File
.
dirname
(
__FILE__
)
+
'/models/*.rb'
].
each
{
|
file
|
require
file
}
Dir
[
File
.
dirname
(
__FILE__
)
+
'/models/*.rb'
].
each
{
|
file
|
require
file
}
Dir
[
File
.
dirname
(
__FILE__
)
+
'/presenters/*.rb'
].
each
{
|
file
|
require
file
}
Dir
[
File
.
dirname
(
__FILE__
)
+
'/presenters/*.rb'
].
each
{
|
file
|
require
file
}
Elasticsearch
::
Model
.
client
=
Elasticsearch
::
Client
.
new
(
host:
CommentService
.
config
[
:elasticsearch_server
],
log:
false
)
$check_index_mapping_exists
=
defined?
(
RAKE_SEARCH_INITIALIZE
)
===
nil
||
RAKE_SEARCH_INITIALIZE
===
false
$check_index_mapping_exists
=
defined?
(
RAKE_SEARCH_INITIALIZE
)
===
nil
||
RAKE_SEARCH_INITIALIZE
===
false
if
$check_index_mapping_exists
if
$check_index_mapping_exists
...
...
spec/api/search_spec.rb
View file @
1235e147
require
'spec_helper'
require
'spec_helper'
require
'unicode_shared_examples'
require
'unicode_shared_examples'
describe
"app"
do
describe
'app'
do
describe
"search"
do
describe
'search'
do
include_context
'search_enabled'
include_context
'search_enabled'
before
(
:each
)
{
set_api_key_header
}
before
(
:each
)
{
set_api_key_header
}
let
(
:author
)
{
create
_test_user
(
42
)
}
let
(
:author
)
{
create
(
:user
)
}
let
(
:course_id
)
{
"test/course/id"
}
let
(
:course_id
)
{
'test/course/id'
}
def
get_result_ids
(
result
)
def
get_result_ids
(
result
)
result
[
"collection"
].
map
{
|
t
|
t
[
"id"
]
}
result
[
'collection'
].
map
{
|
t
|
t
[
'id'
]
}
end
end
describe
"GET /api/v1/search/threads"
do
describe
"GET /api/v1/search/threads"
do
def
assert_empty_response
shared_examples_for
'response for invalid request'
do
last_response
.
should
be_ok
before
(
:each
)
{
refresh_es_index
}
result
=
parse
(
last_response
.
body
)
subject
{
get
'/api/v1/search/threads'
,
{
course_id:
course_id
}.
merge!
(
parameters
)
}
result
.
should
==
{}
it
{
should
be_ok
}
it
{
should
be_an_empty_response
}
end
end
it
"returns an empty result if text parameter is missing"
do
context
'without text parameter'
do
get
"/api/v1/search/threads"
,
course_id:
course_id
let
(
:parameters
)
{
{}
}
assert_empty_response
it_behaves_like
'response for invalid request'
end
end
it
"returns an empty result if sort key is invalid"
do
context
'with an invalid sort key'
do
get
"/api/v1/search/threads"
,
course_id:
course_id
,
text:
"foobar"
,
sort_key:
"invalid"
let
(
:parameters
)
{
{
text:
'foobar'
,
sort_key:
'invalid'
}
}
assert_empty_response
it_behaves_like
'response for invalid request'
end
end
describe
"search for updated/deleted comment/thread works"
do
describe
"search for updated/deleted comment/thread works"
do
...
@@ -91,6 +93,7 @@ describe "app" do
...
@@ -91,6 +93,7 @@ describe "app" do
end
end
end
end
describe
"filtering works"
do
describe
"filtering works"
do
let!
(
:threads
)
do
let!
(
:threads
)
do
threads
=
(
0
..
34
).
map
do
|
i
|
threads
=
(
0
..
34
).
map
do
|
i
|
...
@@ -375,21 +378,21 @@ describe "app" do
...
@@ -375,21 +378,21 @@ describe "app" do
def
test_unicode_data
(
text
)
def
test_unicode_data
(
text
)
# Elasticsearch may not be able to handle searching for non-ASCII text,
# Elasticsearch may not be able to handle searching for non-ASCII text,
# so prepend the text with an ASCII term we can search for.
# so prepend the text with an ASCII term we can search for.
search_term
=
"artichoke"
search_term
=
'artichoke'
course_id
=
"unicode/course"
thread
=
make_thread
(
author
,
"
#{
search_term
}
#{
text
}
"
,
course_id
,
"unicode_commentable"
)
thread
=
create
(
:comment_thread
,
body:
"
#{
search_term
}
#{
text
}
"
)
make_comment
(
author
,
thread
,
text
)
create
(
:comment
,
comment_thread:
thread
,
body:
text
)
# Elasticsearch does not necessarily make newly indexed content
# available immediately, so we must explicitly refresh the index
refresh_es_index
refresh_es_index
get
"/api/v1/search/threads"
,
course_id:
course_id
,
text:
search_term
last_response
.
should
be_ok
get
'/api/v1/search/threads'
,
course_id:
thread
.
course_id
,
text:
search_term
result
=
parse
(
last_response
.
body
)[
"collection"
]
result
.
length
.
should
==
1
expect
(
last_response
).
to
be_ok
check_thread_result_json
(
nil
,
thread
,
result
.
first
)
json
=
parse
(
last_response
.
body
)[
'collection'
]
expect
(
json
.
length
).
to
eq
1
check_thread_result_json
(
nil
,
thread
,
json
.
first
)
end
end
include_examples
"unicode data"
include_examples
'unicode data'
end
end
end
end
end
end
spec/app_spec.rb
View file @
1235e147
...
@@ -174,4 +174,17 @@ describe 'app' do
...
@@ -174,4 +174,17 @@ describe 'app' do
expect
(
last_response
.
body
).
to
include
File
.
expand_path
(
__FILE__
)
expect
(
last_response
.
body
).
to
include
File
.
expand_path
(
__FILE__
)
end
end
end
end
describe
'config'
do
describe
'Elasticsearch client'
do
subject
{
Elasticsearch
::
Model
.
client
}
it
'has a host value set to that from application.yaml'
do
expected
=
URI
::
parse
(
CommentService
.
config
[
:elasticsearch_server
])
host
=
subject
.
transport
.
hosts
[
0
]
host
[
:port
]
=
host
[
:port
].
to_i
expect
(
URI
::
HTTP
.
build
(
host
)).
to
eq
expected
end
end
end
end
end
spec/spec_helper.rb
View file @
1235e147
...
@@ -17,6 +17,7 @@ require 'support/database_cleaner'
...
@@ -17,6 +17,7 @@ require 'support/database_cleaner'
require
'support/elasticsearch'
require
'support/elasticsearch'
require
'support/factory_girl'
require
'support/factory_girl'
require
'support/rake'
require
'support/rake'
require
'support/matchers'
require
'webmock/rspec'
require
'webmock/rspec'
WebMock
.
allow_net_connect!
WebMock
.
allow_net_connect!
...
...
spec/support/matchers.rb
0 → 100644
View file @
1235e147
require
'rspec/expectations'
RSpec
::
Matchers
.
define
:be_an_empty_response
do
match
do
|
actual
|
actual
.
body
==
'{}'
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment