Skip to content

Commit c743e79

Browse files
committed
Fix analytics tests and fix analytics APIs for no indices.
- Get all the analytics-related tests working again in this branch of merged upgrades/things. - We had added some tests for the behavior of analytics API queries against date ranges without any elasticsearch indices present. Fix that behavior in the Rails version of the web-app by handling the lack of aggregation results. - Other test suite fixes.
1 parent c783e1c commit c743e79

File tree

12 files changed

+150
-129
lines changed

12 files changed

+150
-129
lines changed

config/elasticsearch_templates_v1_es2x.json renamed to config/elasticsearch_templates_v1_es1.json

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"template": "api-umbrella-logs-v1-*",
66
"settings": {
77
"index": {
8-
"number_of_shards": 1,
8+
"number_of_shards": 3,
99
"codec": "best_compression"
1010
},
1111
"analysis": {
@@ -27,21 +27,7 @@
2727
"_all": {
2828
"enabled": false
2929
},
30-
"date_detection": false,
31-
"numeric_detection": false,
32-
"dynamic_templates": [
33-
{
34-
"string_template": {
35-
"match": "*",
36-
"match_mapping_type": "string",
37-
"mapping": {
38-
"type": "string",
39-
"index": "analyzed",
40-
"analyzer": "keyword_lowercase"
41-
}
42-
}
43-
}
44-
],
30+
"dynamic": false,
4531
"properties": {
4632
"api_backend_id": {
4733
"type": "string",

config/elasticsearch_templates_v1.json renamed to config/elasticsearch_templates_v1_es5.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"template": "api-umbrella-logs-v1-*",
66
"settings": {
77
"index": {
8-
"number_of_shards": 1,
8+
"number_of_shards": 3,
99
"codec": "best_compression"
1010
},
1111
"analysis": {

config/elasticsearch_templates_v2.json renamed to config/elasticsearch_templates_v2_es5.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@
8484
"normalizer": "lowercase_normalizer"
8585
},
8686
"request_ip_city": {
87-
"type": "keyword"
87+
"type": "keyword",
88+
"normalizer": "lowercase_normalizer"
8889
},
8990
"request_ip_country": {
9091
"type": "keyword",

src/api-umbrella/proxy/startup/init_elasticsearch_templates_data.lua

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
local cjson = require "cjson"
22

3-
local path = os.getenv("API_UMBRELLA_SRC_ROOT") .. "/config/elasticsearch_templates_v" .. config["elasticsearch"]["template_version"] .. "_es2x.json"
3+
local path = os.getenv("API_UMBRELLA_SRC_ROOT") .. "/config/elasticsearch_templates_v" .. config["elasticsearch"]["template_version"]
4+
if config["elasticsearch"]["api_version"] >= 5 then
5+
path = path .. "_es5.json"
6+
else
7+
path = path .. "_es1.json"
8+
end
9+
410
local f, err = io.open(path, "rb")
511
if err then
612
ngx.log(ngx.ERR, "failed to open file: ", err)

src/api-umbrella/web-app/app/controllers/admin/stats_controller.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def users
146146
@search.aggregate_by_user_stats!(aggregation_options)
147147

148148
@result = @search.result
149-
buckets = @result.aggregations["user_stats"]["buckets"]
149+
buckets = if(@result.aggregations && @result.aggregations["user_stats"]) then @result.aggregations["user_stats"]["buckets"] else [] end
150150
@total = buckets.length
151151

152152
# If we were sorting by one of the facet fields, then the sorting has
@@ -195,7 +195,9 @@ def users
195195

196196
respond_to do |format|
197197
format.json
198-
format.csv
198+
format.csv do
199+
@filename = "api_users_#{Time.now.utc.strftime("%Y-%m-%d")}.csv"
200+
end
199201
end
200202
end
201203

@@ -216,7 +218,9 @@ def map
216218

217219
respond_to do |format|
218220
format.json
219-
format.csv
221+
format.csv do
222+
@filename = "api_map_#{Time.now.utc.strftime("%Y-%m-%d")}.csv"
223+
end
220224
end
221225
end
222226

src/api-umbrella/web-app/app/controllers/api/v1/analytics_controller.rb

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ def drilldown
2828
@result = @search.result
2929

3030
respond_to do |format|
31-
format.csv
31+
format.csv do
32+
@filename = "api_drilldown_#{Time.now.utc.strftime("%Y-%m-%d")}.csv"
33+
end
3234
format.json do
3335
@breadcrumbs = [
3436
:crumb => "All Hosts",
@@ -51,48 +53,50 @@ def drilldown
5153
:rows => [],
5254
}
5355

54-
@result.aggregations["top_path_hits_over_time"]["buckets"].each do |bucket|
55-
@hits_over_time[:cols] << {
56-
:id => bucket["key"],
57-
:label => bucket["key"].split("/", 2).last,
58-
:type => "number",
59-
}
60-
end
61-
62-
has_other_hits = false
63-
@result.aggregations["hits_over_time"]["buckets"].each_with_index do |total_bucket, index|
64-
cells = [
65-
{ :v => total_bucket["key"], :f => formatted_interval_time(total_bucket["key"]) },
66-
]
67-
68-
path_total_hits = 0
69-
@result.aggregations["top_path_hits_over_time"]["buckets"].each do |path_bucket|
70-
bucket = path_bucket["drilldown_over_time"]["buckets"][index]
71-
cells << { :v => bucket["doc_count"], :f => number_with_delimiter(bucket["doc_count"]) }
72-
path_total_hits += bucket["doc_count"]
56+
if @result.aggregations
57+
@result.aggregations["top_path_hits_over_time"]["buckets"].each do |bucket|
58+
@hits_over_time[:cols] << {
59+
:id => bucket["key"],
60+
:label => bucket["key"].split("/", 2).last,
61+
:type => "number",
62+
}
7363
end
7464

75-
other_hits = total_bucket["doc_count"] - path_total_hits
76-
cells << { :v => other_hits, :f => number_with_delimiter(other_hits) }
77-
78-
@hits_over_time[:rows] << {
79-
:c => cells,
80-
}
81-
82-
if(other_hits > 0)
83-
has_other_hits = true
65+
has_other_hits = false
66+
@result.aggregations["hits_over_time"]["buckets"].each_with_index do |total_bucket, index|
67+
cells = [
68+
{ :v => total_bucket["key"], :f => formatted_interval_time(total_bucket["key"]) },
69+
]
70+
71+
path_total_hits = 0
72+
@result.aggregations["top_path_hits_over_time"]["buckets"].each do |path_bucket|
73+
bucket = path_bucket["drilldown_over_time"]["buckets"][index]
74+
cells << { :v => bucket["doc_count"], :f => number_with_delimiter(bucket["doc_count"]) }
75+
path_total_hits += bucket["doc_count"]
76+
end
77+
78+
other_hits = total_bucket["doc_count"] - path_total_hits
79+
cells << { :v => other_hits, :f => number_with_delimiter(other_hits) }
80+
81+
@hits_over_time[:rows] << {
82+
:c => cells,
83+
}
84+
85+
if(other_hits > 0)
86+
has_other_hits = true
87+
end
8488
end
85-
end
8689

87-
if(has_other_hits)
88-
@hits_over_time[:cols] << {
89-
:id => "other",
90-
:label => "Other",
91-
:type => "number",
92-
}
93-
else
94-
@hits_over_time[:rows].each do |row|
95-
row[:c].slice!(-1)
90+
if(has_other_hits)
91+
@hits_over_time[:cols] << {
92+
:id => "other",
93+
:label => "Other",
94+
:type => "number",
95+
}
96+
else
97+
@hits_over_time[:rows].each do |row|
98+
row[:c].slice!(-1)
99+
end
96100
end
97101
end
98102
end

src/api-umbrella/web-app/app/models/log_result/base.rb

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,40 @@ def aggregations
1919
end
2020

2121
def hits_over_time
22-
if(!@hits_over_time && aggregations["hits_over_time"])
22+
unless @hits_over_time
2323
@hits_over_time = {}
2424

25-
aggregations["hits_over_time"]["buckets"].each do |bucket|
26-
@hits_over_time[bucket["key"]] = bucket["doc_count"]
25+
if(aggregations && aggregations["hits_over_time"])
26+
aggregations["hits_over_time"]["buckets"].each do |bucket|
27+
@hits_over_time[bucket["key"]] = bucket["doc_count"]
28+
end
2729
end
2830
end
2931

3032
@hits_over_time
3133
end
3234

3335
def drilldown
34-
if(!@drilldown && aggregations["drilldown"])
36+
unless @drilldown
3537
@drilldown = []
3638

37-
aggregations["drilldown"]["buckets"].each do |bucket|
38-
depth, path = bucket["key"].split("/", 2)
39-
terminal = !path.end_with?("/")
40-
41-
depth = depth.to_i
42-
descendent_depth = depth + 1
43-
descendent_prefix = File.join(descendent_depth.to_s, path)
44-
45-
@drilldown << {
46-
:depth => depth,
47-
:path => path,
48-
:terminal => terminal,
49-
:descendent_prefix => descendent_prefix,
50-
:hits => bucket["doc_count"],
51-
}
39+
if(aggregations && aggregations["drilldown"])
40+
aggregations["drilldown"]["buckets"].each do |bucket|
41+
depth, path = bucket["key"].split("/", 2)
42+
terminal = !path.end_with?("/")
43+
44+
depth = depth.to_i
45+
descendent_depth = depth + 1
46+
descendent_prefix = File.join(descendent_depth.to_s, path)
47+
48+
@drilldown << {
49+
:depth => depth,
50+
:path => path,
51+
:terminal => terminal,
52+
:descendent_prefix => descendent_prefix,
53+
:hits => bucket["doc_count"],
54+
}
55+
end
5256
end
5357
end
5458

@@ -86,23 +90,25 @@ def cities
8690
unless @cities
8791
@cities = {}
8892

89-
@regions = aggregations["regions"]["buckets"]
90-
if(@search.query[:aggregations][:regions][:terms][:field] == "request_ip_city")
91-
@city_names = @regions.map { |bucket| bucket["key"] }
92-
@cities = {}
93-
94-
if @city_names.any?
95-
cities = LogCityLocation.where(:country => @search.country)
96-
if @search.state
97-
cities = cities.where(:region => @search.state)
98-
end
99-
cities = cities.where(:city.in => @city_names)
100-
101-
cities.each do |city|
102-
@cities[city.city] = {
103-
"lat" => city.location["coordinates"][1],
104-
"lon" => city.location["coordinates"][0],
105-
}
93+
if(aggregations && aggregations["regions"])
94+
@regions = aggregations["regions"]["buckets"]
95+
if(@search.query[:aggregations][:regions][:terms][:field] == "request_ip_city")
96+
@city_names = @regions.map { |bucket| bucket["key"] }
97+
@cities = {}
98+
99+
if @city_names.any?
100+
cities = LogCityLocation.where(:country => @search.country)
101+
if @search.state
102+
cities = cities.where(:region => @search.state)
103+
end
104+
cities = cities.where(:city.in => @city_names)
105+
106+
cities.each do |city|
107+
@cities[city.city] = {
108+
"lat" => city.location["coordinates"][1],
109+
"lon" => city.location["coordinates"][0],
110+
}
111+
end
106112
end
107113
end
108114
end

src/api-umbrella/web-app/app/views/admin/stats/map.rabl

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,40 @@ node :region_field do
55
end
66

77
node :regions do
8-
rows = @result.aggregations["regions"]["buckets"].map do |bucket|
9-
{
10-
:id => region_id(bucket["key"]),
11-
:name => region_name(bucket["key"]),
12-
:hits => bucket["doc_count"],
13-
}
14-
end
8+
if(@result.aggregations && @result.aggregations["regions"])
9+
rows = @result.aggregations["regions"]["buckets"].map do |bucket|
10+
{
11+
:id => region_id(bucket["key"]),
12+
:name => region_name(bucket["key"]),
13+
:hits => bucket["doc_count"],
14+
}
15+
end
1516

16-
if(@result.aggregations["missing_regions"]["doc_count"] > 0)
17-
rows << {
18-
:id => "missing",
19-
:name => "Unknown",
20-
:hits => @result.aggregations["missing_regions"]["doc_count"],
21-
}
22-
end
17+
if(@result.aggregations["missing_regions"]["doc_count"] > 0)
18+
rows << {
19+
:id => "missing",
20+
:name => "Unknown",
21+
:hits => @result.aggregations["missing_regions"]["doc_count"],
22+
}
23+
end
2324

24-
rows
25+
rows
26+
else
27+
[]
28+
end
2529
end
2630

2731
node :map_regions do
28-
@result.aggregations["regions"]["buckets"].map do |bucket|
29-
{
30-
:c => region_location_columns(bucket) + [
31-
{ :v => bucket["doc_count"], :f => number_with_delimiter(bucket["doc_count"]) },
32-
]
33-
}
32+
if(@result.aggregations && @result.aggregations["regions"])
33+
@result.aggregations["regions"]["buckets"].map do |bucket|
34+
{
35+
:c => region_location_columns(bucket) + [
36+
{ :v => bucket["doc_count"], :f => number_with_delimiter(bucket["doc_count"]) },
37+
]
38+
}
39+
end
40+
else
41+
[]
3442
end
3543
end
3644

test/apis/admin/stats/test_logs.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def test_query_builder_case_insensitive_defaults
101101

102102
def test_query_builder_api_key_case_sensitive
103103
FactoryBot.create(:log_item, :request_at => Time.parse("2015-01-16T06:06:28.816Z").utc, :api_key => "AbCDeF", :request_user_agent => unique_test_id)
104+
LogItem.refresh_indices!
104105

105106
response = Typhoeus.get("https://127.0.0.1:9081/admin/stats/logs.json", http_options.deep_merge(admin_session).deep_merge({
106107
:params => {

0 commit comments

Comments
 (0)