Commit d229bf6c authored by fab-girard's avatar fab-girard
Browse files

Count api calls

parent 1ac8ee3f
......@@ -29,6 +29,7 @@ group :test do
gem 'minitest-focus'
gem 'minitest-reporters'
gem 'simplecov', require: false
gem 'fakeredis'
end
group :development, :test do
......
......@@ -32,6 +32,8 @@ GEM
unf (>= 0.0.5, < 1.0.0)
equalizer (0.0.11)
erubis (2.7.0)
fakeredis (0.7.0)
redis (>= 3.2, < 5.0)
grape (1.2.5)
activesupport
builder
......@@ -148,6 +150,7 @@ DEPENDENCIES
activesupport
border_patrol
byebug
fakeredis
geocoder!
grape
grape-entity
......
......@@ -31,6 +31,43 @@ module Api
end
end
helpers do
def redis_count
GeocoderWrapper.config[:redis_count]
end
def count_time
@count_time ||= Time.now.utc
end
def count_key(operation)
@count_key ||= [
[:geocoder, operation, count_time.to_s[0..9]],
[:key, params[:api_key]],
[:ip, request.ip],
[:asset, params[:asset]]
].map{ |a| a.join(':') }.join('_')
end
def count(operation)
return unless redis_count
@count_val = redis_count.hgetall(count_key(operation)).symbolize_keys
if @count_val.empty?
@count_val = {hits: 0, transactions: 0}
redis_count.mapped_hmset @count_key, @count_val
redis_count.expire @count_key, 100.days
end
end
def count_incr(operation, options)
return unless redis_count
count operation unless @count_val
incr = {hits: @count_val[:hits].to_i + 1}
incr[:transactions] = @count_val[:transactions].to_i + options[:transactions] if options[:transactions]
redis_count.mapped_hmset @count_key, incr
end
end
rescue_from :all, backtrace: ENV['APP_ENV'] != 'production' do |e|
@error = e
if ENV['APP_ENV'] != 'test'
......
......@@ -87,6 +87,7 @@ module Api
if !params.key?('geocodes') || !params['geocodes'].is_a?(Array)
error!({status: 'Missing or invalid field "geocodes".'}, 400)
end
count :geocode
params_limit = APIBase.services(params[:api_key])[:params_limit].merge(GeocoderWrapper.access[params[:api_key]][:params_limit] || {})
if !params_limit[:locations].nil?
......@@ -95,6 +96,7 @@ module Api
results = GeocoderWrapper.wrapper_geocodes(APIBase.services(params[:api_key]), params[:geocodes])
if results
count_incr :geocode, transactions: results.size
results = { geocodes: results }
status 200
if params['format'] != :csv
......@@ -126,6 +128,7 @@ module Api
if !params.key?('reverses') || !params['reverses'].is_a?(Array)
error!('400 Bad Request. Missing or invalid field "reverses".', 400)
end
count :reverse
params_limit = APIBase.services(params[:api_key])[:params_limit].merge(GeocoderWrapper.access[params[:api_key]][:params_limit] || {})
if !params_limit[:locations].nil?
......@@ -143,6 +146,7 @@ module Api
}
results = GeocoderWrapper.wrapper_reverses(APIBase.services(params[:api_key]), params[:reverses])
if results
count_incr :reverse, transactions: results.size
results = { reverses: results }
status 200
present results, with: ReversesResult
......
......@@ -32,6 +32,7 @@ module Api
]
}
get '/', erb: 'map' do
count_incr :map, transactions: 1
end
end
end
......
......@@ -53,6 +53,7 @@ module Api
optional :limit, type: Integer, desc: 'Max results numbers. (default and upper max 10)'
}
get do
count :geocode
params[:limit] = [params[:limit] || 10, 10].min
results = GeocoderWrapper::wrapper_geocode(APIBase.services(params[:api_key]), params)
if results && results[:error]
......@@ -60,6 +61,7 @@ module Api
error!(message, results[:response].code)
elsif results
results[:geocoding][:version] = 'draft#namespace#score'
count_incr :geocode, transactions: 1
present results, with: GeocodeResult
else
error!('500 Internal Server Error', 500)
......@@ -84,10 +86,12 @@ module Api
optional :limit, type: Integer, desc: 'Max results numbers. (default and upper max 10)'
}
patch do
count :complete
params[:limit] = [params[:limit] || 10, 10].min
results = GeocoderWrapper::wrapper_complete(APIBase.services(params[:api_key]), params)
if results
results[:geocoding][:version] = 'draft#namespace#score'
count_incr :complete, transactions: 1
present results, with: GeocodeResult
else
error!('500 Internal Server Error', 500)
......@@ -105,9 +109,11 @@ module Api
requires :lng, type: Float, desc: 'Longitude.'
}
get do
count :reverse
results = GeocoderWrapper::wrapper_reverse(APIBase.services(params[:api_key]), params)
if results
results[:geocoding][:version] = 'draft#namespace#score'
count_incr :reverse, transactions: 1
present results, with: GeocodeResult
else
error!('500 Internal Server Error', 500)
......
......@@ -16,6 +16,8 @@
# <http://www.gnu.org/licenses/agpl.html>
#
require 'active_support'
require 'active_support/core_ext'
require 'tmpdir'
require './wrappers/ruby_geocoder/ruby_geocoder_opencagedata'
......@@ -28,6 +30,8 @@ require './wrappers/ign'
require './lib/cache_manager'
require './lib/point_in_polygon'
require 'byebug'
module GeocoderWrapper
Geocoder::Configuration.always_raise = :all
......@@ -40,6 +44,7 @@ module GeocoderWrapper
IGN = Wrappers::Ign.new(ENV['IGN_API_KEY'], CACHE)
PARAMS_LIMIT = { locations: 10000 }
REDIS_COUNT = ENV['REDIS_COUNT_HOST'] && Redis.new(host: ENV['REDIS_COUNT_HOST'])
@@c = {
product_title: 'Geocoder API',
......@@ -62,6 +67,7 @@ module GeocoderWrapper
# Set the appropriate authentication if required
here: ['APP_ID', 'APP_CODE'],
opencagedata: 'API_KEY'
}
},
redis_count: REDIS_COUNT,
}
end
......@@ -16,6 +16,8 @@
# <http://www.gnu.org/licenses/agpl.html>
#
require 'active_support'
require 'active_support/core_ext'
require 'tmpdir'
require './wrappers/ruby_geocoder/ruby_geocoder_here'
......@@ -39,6 +41,7 @@ module GeocoderWrapper
IGN = Wrappers::Ign.new('hxexfaqsph8w23yaxap442ru', CACHE, 'poly/france.kml')
PARAMS_LIMIT = { locations: 1000 }.freeze
REDIS_COUNT = ENV['REDIS_COUNT_HOST'] && Redis.new(host: ENV['REDIS_COUNT_HOST'])
@@c = {
product_title: 'Geocoder API',
......@@ -62,6 +65,7 @@ module GeocoderWrapper
# Set the appropriate authentication if required
here: ['APP_ID', 'APP_CODE'],
opencagedata: 'API_KEY'
}
},
redis_count: REDIS_COUNT,
}
end
......@@ -16,6 +16,8 @@
# <http://www.gnu.org/licenses/agpl.html>
#
require 'active_support'
require 'active_support/core_ext'
require 'tmpdir'
require './wrappers/ruby_geocoder/ruby_geocoder_google'
......@@ -28,6 +30,8 @@ require './wrappers/demo'
require './lib/cache_manager'
require './lib/point_in_polygon'
require 'byebug'
module GeocoderWrapper
Geocoder::Configuration.always_raise = :all
......@@ -41,6 +45,7 @@ module GeocoderWrapper
DEMO = Wrappers::Demo.new(CACHE)
PARAMS_LIMIT = { locations: 10000 }
REDIS_COUNT = Redis.new # Fake redis
@@c = {
product_title: 'Geocoder API',
......@@ -59,6 +64,7 @@ module GeocoderWrapper
# Set the appropriate authentication if required
here: ['APP_ID', 'APP_CODE'],
opencagedata: 'API_KEY'
}
},
redis_count: REDIS_COUNT,
}
end
......@@ -21,6 +21,7 @@ require './api/root'
class Api::V01::BulkTest < Minitest::Test
include Rack::Test::Methods
include FakeRedis
def app
Api::Root
......@@ -114,4 +115,34 @@ class Api::V01::BulkTest < Minitest::Test
]}
assert !last_response.ok?, last_response.body
end
def test_count_geocodes
(1..2).each do |i|
post '/0.1/geocode', {api_key: 'demo', geocodes: [
{query: 'NYC', country: 'ttt'},
{query: 'Bordeaux', country: 'France'},
{query: 'Rome', country: 'ttt'},
]}
keys = GeocoderWrapper.config[:redis_count].keys("geocoder:geocode:#{Time.now.utc.to_s[0..9]}_key:demo_ip*")
assert_equal 1, keys.size
keys.each{ |key|
assert_equal({'hits' => "#{i}", 'transactions' => "#{i*3}"}, GeocoderWrapper.config[:redis_count].hgetall(key))
}
end
end
def test_count_reverses
(1..2).each do |i|
post '/0.1/reverse', {api_key: 'demo', reverses: [
{lat: 0.1, lng: 0.1},
{lat: 46.03349, lng: 4.07271},
{lat: 0.2, lng: 0.2},
]}
keys = GeocoderWrapper.config[:redis_count].keys("geocoder:reverse:#{Time.now.utc.to_s[0..9]}_key:demo_ip*")
assert_equal 1, keys.size
keys.each{ |key|
assert_equal({'hits' => "#{i}", 'transactions' => "#{i*3}"}, GeocoderWrapper.config[:redis_count].hgetall(key))
}
end
end
end
......@@ -21,6 +21,7 @@ require './api/root'
class Api::V01::UnitaryTest < Minitest::Test
include Rack::Test::Methods
include FakeRedis
def app
Api::Root
......@@ -82,6 +83,39 @@ class Api::V01::UnitaryTest < Minitest::Test
assert_equal "query is empty", JSON.parse(last_response.body)["message"]
end
def test_count_geocode
(1..2).each do |i|
get '/0.1/geocode', {api_key: 'demo', query: 'Place Pey Berland, Bordeaux', country: 'demo'}
keys = GeocoderWrapper.config[:redis_count].keys("geocoder:geocode:#{Time.now.utc.to_s[0..9]}_key:demo_ip*")
assert_equal 1, keys.size
keys.each{ |key|
assert_equal({'hits' => "#{i}", 'transactions' => "#{i}"}, GeocoderWrapper.config[:redis_count].hgetall(key))
}
end
end
def test_count_complete
(1..2).each do |i|
patch '/0.1/geocode', {api_key: 'demo', query: 'Place Pey Berland, Bordeaux', country: 'demo'}
keys = GeocoderWrapper.config[:redis_count].keys("geocoder:complete:#{Time.now.utc.to_s[0..9]}_key:demo_ip*")
assert_equal 1, keys.size
keys.each{ |key|
assert_equal({'hits' => "#{i}", 'transactions' => "#{i}"}, GeocoderWrapper.config[:redis_count].hgetall(key))
}
end
end
def test_count_reverse
(1..2).each do |i|
get '/0.1/reverse', {api_key: 'demo', lat: 0, lng: 0, country: 'demo'}
keys = GeocoderWrapper.config[:redis_count].keys("geocoder:reverse:#{Time.now.utc.to_s[0..9]}_key:demo_ip*")
assert_equal 1, keys.size
keys.each{ |key|
assert_equal({'hits' => "#{i}", 'transactions' => "#{i}"}, GeocoderWrapper.config[:redis_count].hgetall(key))
}
end
end
private
def _test_geocode_from_full_text(country)
......
......@@ -15,8 +15,10 @@
# along with Mapotempo. If not, see:
# <http://www.gnu.org/licenses/agpl.html>
#
require 'minitest'
require 'simplecov'
SimpleCov.start unless ENV['COV'] == 'false'
require 'fakeredis/minitest'
ENV['APP_ENV'] ||= 'test'
require File.expand_path('../../config/environments/' + ENV['APP_ENV'], __FILE__)
......@@ -35,3 +37,9 @@ require 'grape-entity'
require 'minitest/autorun'
require 'rack/test'
module FakeRedis
def teardown
GeocoderWrapper.config[:redis_count].flushall
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment