commit
ad5d25f0a0
@ -13,8 +13,8 @@ OLD_VERSIONS = $(wildcard old_versions/*.sql)
|
|||||||
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
# @see http://www.postgresql.org/docs/current/static/extend-pgxs.html
|
||||||
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
DATA = $(NEW_EXTENSION_ARTIFACT) \
|
||||||
$(OLD_VERSIONS) \
|
$(OLD_VERSIONS) \
|
||||||
cdb_dataservices_server--0.6.1--0.6.0.sql \
|
cdb_dataservices_server--0.6.2--0.6.1.sql \
|
||||||
cdb_dataservices_server--0.6.0--0.6.1.sql
|
cdb_dataservices_server--0.6.1--0.6.2.sql
|
||||||
|
|
||||||
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
REGRESS = $(notdir $(basename $(wildcard test/sql/*test.sql)))
|
||||||
TEST_DIR = test/
|
TEST_DIR = test/
|
||||||
|
102
server/extension/cdb_dataservices_server--0.6.1--0.6.2.sql
Normal file
102
server/extension/cdb_dataservices_server--0.6.1--0.6.2.sql
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.6.2'" to load this file. \quit
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
|
RETURNS Geometry AS $$
|
||||||
|
from cartodb_services.mapzen import MapzenGeocoder
|
||||||
|
from cartodb_services.mapzen.types import country_to_iso3
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
||||||
|
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
plpy.error('You have reach the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
geocoder = MapzenGeocoder(user_geocoder_config.mapzen_api_key)
|
||||||
|
country_iso3 = None
|
||||||
|
if country:
|
||||||
|
country_iso3 = country_to_iso3(country)
|
||||||
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city,
|
||||||
|
state_province=state_province,
|
||||||
|
country=country_iso3)
|
||||||
|
if coordinates:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0]
|
||||||
|
return point['st_setsrid']
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return None
|
||||||
|
except BaseException as e:
|
||||||
|
import sys, traceback
|
||||||
|
type_, value_, traceback_ = sys.exc_info()
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
error_msg = 'There was an error trying to geocode using mapzen geocoder: {0}'.format(e)
|
||||||
|
plpy.notice(traceback.format_tb(traceback_))
|
||||||
|
plpy.error(error_msg)
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_point_to_point(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
origin geometry(Point, 4326),
|
||||||
|
destination geometry(Point, 4326),
|
||||||
|
mode TEXT,
|
||||||
|
options text[] DEFAULT ARRAY[]::text[],
|
||||||
|
units text DEFAULT 'kilometers')
|
||||||
|
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||||
|
import json
|
||||||
|
from cartodb_services.mapzen import MapzenRouting, MapzenRoutingResponse
|
||||||
|
from cartodb_services.mapzen.types import polyline_to_linestring
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Coordinate
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
plpy.error('You have reach the limit of your quota')
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MapzenRouting(user_routing_config.mapzen_api_key)
|
||||||
|
|
||||||
|
if not origin or not destination:
|
||||||
|
plpy.notice("Empty origin or destination")
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
|
||||||
|
orig_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % origin)[0]['lat']
|
||||||
|
orig_lon = plpy.execute("SELECT ST_X('%s') AS lon" % origin)[0]['lon']
|
||||||
|
origin_coordinates = Coordinate(orig_lon, orig_lat)
|
||||||
|
dest_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % destination)[0]['lat']
|
||||||
|
dest_lon = plpy.execute("SELECT ST_X('%s') AS lon" % destination)[0]['lon']
|
||||||
|
dest_coordinates = Coordinate(dest_lon, dest_lat)
|
||||||
|
|
||||||
|
resp = client.calculate_route_point_to_point(origin_coordinates, dest_coordinates, mode, options, units)
|
||||||
|
|
||||||
|
if resp and resp.shape:
|
||||||
|
shape_linestring = polyline_to_linestring(resp.shape)
|
||||||
|
if shape_linestring:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
return [shape_linestring, resp.length, resp.duration]
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
except BaseException as e:
|
||||||
|
import sys, traceback
|
||||||
|
type_, value_, traceback_ = sys.exc_info()
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
error_msg = 'There was an error trying to obtain route using mapzen provider: {0}'.format(e)
|
||||||
|
plpy.notice(traceback.format_tb(traceback_))
|
||||||
|
plpy.error(error_msg)
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
98
server/extension/cdb_dataservices_server--0.6.2--0.6.1.sql
Normal file
98
server/extension/cdb_dataservices_server--0.6.2--0.6.1.sql
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES
|
||||||
|
-- Complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.6.1'" to load this file. \quit
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
|
RETURNS Geometry AS $$
|
||||||
|
from cartodb_services.mapzen import MapzenGeocoder
|
||||||
|
from cartodb_services.mapzen.types import country_to_iso3
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
||||||
|
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
||||||
|
|
||||||
|
try:
|
||||||
|
geocoder = MapzenGeocoder(user_geocoder_config.mapzen_app_key)
|
||||||
|
country_iso3 = None
|
||||||
|
if country:
|
||||||
|
country_iso3 = country_to_iso3(country)
|
||||||
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city,
|
||||||
|
state_province=state_province,
|
||||||
|
country=country_iso3)
|
||||||
|
if coordinates:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
point = plpy.execute(plan, [coordinates[0], coordinates[1]], 1)[0]
|
||||||
|
return point['st_setsrid']
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return None
|
||||||
|
except BaseException as e:
|
||||||
|
import sys, traceback
|
||||||
|
type_, value_, traceback_ = sys.exc_info()
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
error_msg = 'There was an error trying to geocode using mapzen geocoder: {0}'.format(e)
|
||||||
|
plpy.notice(traceback.format_tb(traceback_))
|
||||||
|
plpy.error(error_msg)
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_route_point_to_point(
|
||||||
|
username TEXT,
|
||||||
|
orgname TEXT,
|
||||||
|
origin geometry(Point, 4326),
|
||||||
|
destination geometry(Point, 4326),
|
||||||
|
mode TEXT,
|
||||||
|
options text[] DEFAULT ARRAY[]::text[],
|
||||||
|
units text DEFAULT 'kilometers')
|
||||||
|
RETURNS cdb_dataservices_server.simple_route AS $$
|
||||||
|
import json
|
||||||
|
from cartodb_services.mapzen import MapzenRouting, MapzenRoutingResponse
|
||||||
|
from cartodb_services.mapzen.types import polyline_to_linestring
|
||||||
|
from cartodb_services.metrics import QuotaService
|
||||||
|
from cartodb_services.tools import Coordinate
|
||||||
|
|
||||||
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
|
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
|
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = MapzenRouting(user_routing_config.mapzen_app_key)
|
||||||
|
|
||||||
|
if not origin or not destination:
|
||||||
|
plpy.notice("Empty origin or destination")
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
|
||||||
|
orig_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % origin)[0]['lat']
|
||||||
|
orig_lon = plpy.execute("SELECT ST_X('%s') AS lon" % origin)[0]['lon']
|
||||||
|
origin_coordinates = Coordinate(orig_lon, orig_lat)
|
||||||
|
dest_lat = plpy.execute("SELECT ST_Y('%s') AS lat" % destination)[0]['lat']
|
||||||
|
dest_lon = plpy.execute("SELECT ST_X('%s') AS lon" % destination)[0]['lon']
|
||||||
|
dest_coordinates = Coordinate(dest_lon, dest_lat)
|
||||||
|
|
||||||
|
resp = client.calculate_route_point_to_point(origin_coordinates, dest_coordinates, mode, options, units)
|
||||||
|
|
||||||
|
if resp and resp.shape:
|
||||||
|
shape_linestring = polyline_to_linestring(resp.shape)
|
||||||
|
if shape_linestring:
|
||||||
|
quota_service.increment_success_service_use()
|
||||||
|
return [shape_linestring, resp.length, resp.duration]
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
else:
|
||||||
|
quota_service.increment_empty_service_use()
|
||||||
|
return [None, None, None]
|
||||||
|
except BaseException as e:
|
||||||
|
import sys, traceback
|
||||||
|
type_, value_, traceback_ = sys.exc_info()
|
||||||
|
quota_service.increment_failed_service_use()
|
||||||
|
error_msg = 'There was an error trying to obtain route using mapzen provider: {0}'.format(e)
|
||||||
|
plpy.notice(traceback.format_tb(traceback_))
|
||||||
|
plpy.error(error_msg)
|
||||||
|
finally:
|
||||||
|
quota_service.increment_total_service_use()
|
||||||
|
$$ LANGUAGE plpythonu SECURITY DEFINER;
|
1024
server/extension/cdb_dataservices_server--0.6.2.sql
Normal file
1024
server/extension/cdb_dataservices_server--0.6.2.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
comment = 'CartoDB dataservices server extension'
|
comment = 'CartoDB dataservices server extension'
|
||||||
default_version = '0.6.1'
|
default_version = '0.6.2'
|
||||||
requires = 'plpythonu, postgis, cdb_geocoder'
|
requires = 'plpythonu, postgis, cdb_geocoder'
|
||||||
superuser = true
|
superuser = true
|
||||||
schema = cdb_dataservices_server
|
schema = cdb_dataservices_server
|
||||||
|
@ -27,6 +27,8 @@ RETURNS cdb_dataservices_server.simple_route AS $$
|
|||||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
quota_service = QuotaService(user_routing_config, redis_conn)
|
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
plpy.error('You have reach the limit of your quota')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = MapzenRouting(user_routing_config.mapzen_app_key)
|
client = MapzenRouting(user_routing_config.mapzen_app_key)
|
||||||
@ -257,6 +259,8 @@ RETURNS Geometry AS $$
|
|||||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
||||||
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
plpy.error('You have reach the limit of your quota')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
geocoder = MapzenGeocoder(user_geocoder_config.mapzen_app_key)
|
geocoder = MapzenGeocoder(user_geocoder_config.mapzen_app_key)
|
@ -24,9 +24,11 @@ RETURNS cdb_dataservices_server.simple_route AS $$
|
|||||||
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
user_routing_config = GD["user_routing_config_{0}".format(username)]
|
||||||
|
|
||||||
quota_service = QuotaService(user_routing_config, redis_conn)
|
quota_service = QuotaService(user_routing_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
plpy.error('You have reach the limit of your quota')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = MapzenRouting(user_routing_config.mapzen_app_key)
|
client = MapzenRouting(user_routing_config.mapzen_api_key)
|
||||||
|
|
||||||
if not origin or not destination:
|
if not origin or not destination:
|
||||||
plpy.notice("Empty origin or destination")
|
plpy.notice("Empty origin or destination")
|
||||||
|
@ -89,18 +89,23 @@ $$ LANGUAGE plpythonu;
|
|||||||
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
CREATE OR REPLACE FUNCTION cdb_dataservices_server._cdb_mapzen_geocode_street_point(username TEXT, orgname TEXT, searchtext TEXT, city TEXT DEFAULT NULL, state_province TEXT DEFAULT NULL, country TEXT DEFAULT NULL)
|
||||||
RETURNS Geometry AS $$
|
RETURNS Geometry AS $$
|
||||||
from cartodb_services.mapzen import MapzenGeocoder
|
from cartodb_services.mapzen import MapzenGeocoder
|
||||||
|
from cartodb_services.mapzen.types import country_to_iso3
|
||||||
from cartodb_services.metrics import QuotaService
|
from cartodb_services.metrics import QuotaService
|
||||||
|
|
||||||
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
redis_conn = GD["redis_connection_{0}".format(username)]['redis_metrics_connection']
|
||||||
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
user_geocoder_config = GD["user_geocoder_config_{0}".format(username)]
|
||||||
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
quota_service = QuotaService(user_geocoder_config, redis_conn)
|
||||||
|
if not quota_service.check_user_quota():
|
||||||
|
plpy.error('You have reach the limit of your quota')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
geocoder = MapzenGeocoder(user_geocoder_config.mapzen_app_key)
|
geocoder = MapzenGeocoder(user_geocoder_config.mapzen_api_key)
|
||||||
country_iso3 = None
|
country_iso3 = None
|
||||||
if country:
|
if country:
|
||||||
country_iso3 = country_to_iso3(country)
|
country_iso3 = country_to_iso3(country)
|
||||||
coordinates = geocoder.geocode(searchtext=searchtext, country=country_iso3)
|
coordinates = geocoder.geocode(searchtext=searchtext, city=city,
|
||||||
|
state_province=state_province,
|
||||||
|
country=country_iso3)
|
||||||
if coordinates:
|
if coordinates:
|
||||||
quota_service.increment_success_service_use()
|
quota_service.increment_success_service_use()
|
||||||
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
plan = plpy.prepare("SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326); ", ["double precision", "double precision"])
|
||||||
|
@ -25,7 +25,7 @@ SELECT cartodb.cdb_conf_setconf('heremaps_conf', '{"geocoder": {"app_id": "dummy
|
|||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT cartodb.cdb_conf_setconf('mapzen_conf', '{"routing_app_key": "dummy_key", "geocoder_app_key": "dummy_key"}');
|
SELECT cartodb.cdb_conf_setconf('mapzen_conf', '{"routing": {"api_key": "routing_dummy_api_key", "monthly_quota": 1500000}, "geocoder": {"api_key": "geocoder_dummy_api_key", "monthly_quota": 1500000}}');
|
||||||
cdb_conf_setconf
|
cdb_conf_setconf
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ CREATE EXTENSION cdb_dataservices_server;
|
|||||||
SELECT cartodb.cdb_conf_setconf('redis_metrics_config', '{"redis_host": "localhost", "redis_port": 6379, "timeout": 0.1, "redis_db": 5}');
|
SELECT cartodb.cdb_conf_setconf('redis_metrics_config', '{"redis_host": "localhost", "redis_port": 6379, "timeout": 0.1, "redis_db": 5}');
|
||||||
SELECT cartodb.cdb_conf_setconf('redis_metadata_config', '{"redis_host": "localhost", "redis_port": 6379, "timeout": 0.1, "redis_db": 5}');
|
SELECT cartodb.cdb_conf_setconf('redis_metadata_config', '{"redis_host": "localhost", "redis_port": 6379, "timeout": 0.1, "redis_db": 5}');
|
||||||
SELECT cartodb.cdb_conf_setconf('heremaps_conf', '{"geocoder": {"app_id": "dummy_id", "app_code": "dummy_code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "dummy_id", "app_code": "dummy_code"}}');
|
SELECT cartodb.cdb_conf_setconf('heremaps_conf', '{"geocoder": {"app_id": "dummy_id", "app_code": "dummy_code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "dummy_id", "app_code": "dummy_code"}}');
|
||||||
SELECT cartodb.cdb_conf_setconf('mapzen_conf', '{"routing_app_key": "dummy_key", "geocoder_app_key": "dummy_key"}');
|
SELECT cartodb.cdb_conf_setconf('mapzen_conf', '{"routing": {"api_key": "routing_dummy_api_key", "monthly_quota": 1500000}, "geocoder": {"api_key": "geocoder_dummy_api_key", "monthly_quota": 1500000}}');
|
||||||
SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null"}');
|
SELECT cartodb.cdb_conf_setconf('logger_conf', '{"geocoder_log_path": "/dev/null"}');
|
||||||
|
|
||||||
-- Mock the varnish invalidation function
|
-- Mock the varnish invalidation function
|
||||||
|
@ -10,10 +10,15 @@ class ConfigException(Exception):
|
|||||||
class ServiceConfig(object):
|
class ServiceConfig(object):
|
||||||
__metaclass__ = abc.ABCMeta
|
__metaclass__ = abc.ABCMeta
|
||||||
|
|
||||||
def __init__(self, redis_connection, username, orgname=None):
|
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
||||||
self._redis_connection = redis_connection
|
self._redis_connection = redis_connection
|
||||||
self._username = username
|
self._username = username
|
||||||
self._orgname = orgname
|
self._orgname = orgname
|
||||||
|
self._db_config = ServicesDBConfig(db_conn)
|
||||||
|
if redis_connection:
|
||||||
|
self._redis_config = ServicesRedisConfig(redis_connection).build(username, orgname)
|
||||||
|
else:
|
||||||
|
self._redis_config = None
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def service_type(self):
|
def service_type(self):
|
||||||
@ -30,24 +35,30 @@ class ServiceConfig(object):
|
|||||||
|
|
||||||
class RoutingConfig(ServiceConfig):
|
class RoutingConfig(ServiceConfig):
|
||||||
|
|
||||||
ROUTING_CONFIG_KEYS = ['username', 'orgname', 'mapzen_app_key']
|
PERIOD_END_DATE = 'period_end_date'
|
||||||
MAPZEN_APP_KEY = 'mapzen_app_key'
|
|
||||||
USERNAME_KEY = 'username'
|
|
||||||
ORGNAME_KEY = 'orgname'
|
|
||||||
|
|
||||||
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
||||||
super(RoutingConfig, self).__init__(redis_connection, username,
|
super(RoutingConfig, self).__init__(redis_connection, db_conn,
|
||||||
orgname)
|
username, orgname)
|
||||||
db_config = ServicesDBConfig(db_conn)
|
self._mapzen_api_key = self._db_config.mapzen_routing_api_key
|
||||||
self._mapzen_app_key = db_config.mapzen_routing_app_key
|
self._monthly_quota = self._db_config.mapzen_routing_monthly_quota
|
||||||
|
self._period_end_date = date_parse(self._redis_config[self.PERIOD_END_DATE])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def service_type(self):
|
def service_type(self):
|
||||||
return 'routing_mapzen'
|
return 'routing_mapzen'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mapzen_app_key(self):
|
def mapzen_api_key(self):
|
||||||
return self._mapzen_app_key
|
return self._mapzen_api_key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def monthly_quota(self):
|
||||||
|
return self._monthly_quota
|
||||||
|
|
||||||
|
@property
|
||||||
|
def period_end_date(self):
|
||||||
|
return self._period_end_date
|
||||||
|
|
||||||
|
|
||||||
class IsolinesRoutingConfig(ServiceConfig):
|
class IsolinesRoutingConfig(ServiceConfig):
|
||||||
@ -56,43 +67,17 @@ class IsolinesRoutingConfig(ServiceConfig):
|
|||||||
'period_end_date', 'username', 'orgname',
|
'period_end_date', 'username', 'orgname',
|
||||||
'heremaps_isolines_app_id', 'heremaps_isolines_app_code',
|
'heremaps_isolines_app_id', 'heremaps_isolines_app_code',
|
||||||
'geocoder_type']
|
'geocoder_type']
|
||||||
NOKIA_APP_ID_KEY = 'heremaps_isolines_app_id'
|
|
||||||
NOKIA_APP_CODE_KEY = 'heremaps_isolines_app_code'
|
|
||||||
QUOTA_KEY = 'here_isolines_quota'
|
QUOTA_KEY = 'here_isolines_quota'
|
||||||
SOFT_LIMIT_KEY = 'soft_here_isolines_limit'
|
SOFT_LIMIT_KEY = 'soft_here_isolines_limit'
|
||||||
USERNAME_KEY = 'username'
|
|
||||||
ORGNAME_KEY = 'orgname'
|
|
||||||
PERIOD_END_DATE = 'period_end_date'
|
PERIOD_END_DATE = 'period_end_date'
|
||||||
GEOCODER_TYPE_KEY = 'geocoder_type'
|
GEOCODER_TYPE_KEY = 'geocoder_type'
|
||||||
GOOGLE_GEOCODER = 'google'
|
GOOGLE_GEOCODER = 'google'
|
||||||
|
|
||||||
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
||||||
super(IsolinesRoutingConfig, self).__init__(redis_connection, username,
|
super(IsolinesRoutingConfig, self).__init__(redis_connection, db_conn,
|
||||||
orgname)
|
username, orgname)
|
||||||
config = self.__get_user_config(username, orgname)
|
filtered_config = {key: self._redis_config[key] for key in self.ROUTING_CONFIG_KEYS if key in self._redis_config.keys()}
|
||||||
db_config = ServicesDBConfig(db_conn)
|
self.__parse_config(filtered_config, self._db_config)
|
||||||
filtered_config = {key: config[key] for key in self.ROUTING_CONFIG_KEYS if key in config.keys()}
|
|
||||||
self.__parse_config(filtered_config, db_config)
|
|
||||||
|
|
||||||
def __get_user_config(self, username, orgname):
|
|
||||||
user_config = self._redis_connection.hgetall(
|
|
||||||
"rails:users:{0}".format(username))
|
|
||||||
if not user_config:
|
|
||||||
raise ConfigException("""There is no user config available. Please check your configuration.'""")
|
|
||||||
else:
|
|
||||||
if orgname:
|
|
||||||
self.__get_organization_config(orgname, user_config)
|
|
||||||
|
|
||||||
return user_config
|
|
||||||
|
|
||||||
def __get_organization_config(self, orgname, user_config):
|
|
||||||
org_config = self._redis_connection.hgetall(
|
|
||||||
"rails:orgs:{0}".format(orgname))
|
|
||||||
if not org_config:
|
|
||||||
raise ConfigException("""There is no organization config available. Please check your configuration.'""")
|
|
||||||
else:
|
|
||||||
user_config[self.QUOTA_KEY] = org_config[self.QUOTA_KEY]
|
|
||||||
user_config[self.PERIOD_END_DATE] = org_config[self.PERIOD_END_DATE]
|
|
||||||
|
|
||||||
def __parse_config(self, filtered_config, db_config):
|
def __parse_config(self, filtered_config, db_config):
|
||||||
self._geocoder_type = filtered_config[self.GEOCODER_TYPE_KEY].lower()
|
self._geocoder_type = filtered_config[self.GEOCODER_TYPE_KEY].lower()
|
||||||
@ -137,10 +122,10 @@ class IsolinesRoutingConfig(ServiceConfig):
|
|||||||
class InternalGeocoderConfig(ServiceConfig):
|
class InternalGeocoderConfig(ServiceConfig):
|
||||||
|
|
||||||
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
||||||
super(InternalGeocoderConfig, self).__init__(redis_connection,
|
# For now, internal geocoder doesn't use the redis config
|
||||||
|
super(InternalGeocoderConfig, self).__init__(None, db_conn,
|
||||||
username, orgname)
|
username, orgname)
|
||||||
db_config = ServicesDBConfig(db_conn)
|
self._log_path = self._db_config.geocoder_log_path
|
||||||
self._log_path = db_config.geocoder_log_path
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def service_type(self):
|
def service_type(self):
|
||||||
@ -169,7 +154,7 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
'geocoding_quota', 'soft_geocoding_limit',
|
'geocoding_quota', 'soft_geocoding_limit',
|
||||||
'geocoder_type', 'period_end_date',
|
'geocoder_type', 'period_end_date',
|
||||||
'heremaps_geocoder_app_id', 'heremaps_geocoder_app_code',
|
'heremaps_geocoder_app_id', 'heremaps_geocoder_app_code',
|
||||||
'mapzen_geocoder_app_key', 'username', 'orgname']
|
'mapzen_geocoder_api_key', 'username', 'orgname']
|
||||||
NOKIA_GEOCODER_REDIS_MANDATORY_KEYS = ['geocoding_quota', 'soft_geocoding_limit']
|
NOKIA_GEOCODER_REDIS_MANDATORY_KEYS = ['geocoding_quota', 'soft_geocoding_limit']
|
||||||
NOKIA_GEOCODER = 'heremaps'
|
NOKIA_GEOCODER = 'heremaps'
|
||||||
NOKIA_GEOCODER_APP_ID_KEY = 'heremaps_geocoder_app_id'
|
NOKIA_GEOCODER_APP_ID_KEY = 'heremaps_geocoder_app_id'
|
||||||
@ -178,7 +163,7 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
GOOGLE_GEOCODER_API_KEY = 'google_maps_api_key'
|
GOOGLE_GEOCODER_API_KEY = 'google_maps_api_key'
|
||||||
GOOGLE_GEOCODER_CLIENT_ID = 'google_maps_client_id'
|
GOOGLE_GEOCODER_CLIENT_ID = 'google_maps_client_id'
|
||||||
MAPZEN_GEOCODER = 'mapzen'
|
MAPZEN_GEOCODER = 'mapzen'
|
||||||
MAPZEN_GEOCODER_API_KEY = 'mapzen_geocoder_app_key'
|
MAPZEN_GEOCODER_API_KEY = 'mapzen_geocoder_api_key'
|
||||||
GEOCODER_TYPE = 'geocoder_type'
|
GEOCODER_TYPE = 'geocoder_type'
|
||||||
QUOTA_KEY = 'geocoding_quota'
|
QUOTA_KEY = 'geocoding_quota'
|
||||||
SOFT_LIMIT_KEY = 'soft_geocoding_limit'
|
SOFT_LIMIT_KEY = 'soft_geocoding_limit'
|
||||||
@ -187,12 +172,10 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
PERIOD_END_DATE = 'period_end_date'
|
PERIOD_END_DATE = 'period_end_date'
|
||||||
|
|
||||||
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
def __init__(self, redis_connection, db_conn, username, orgname=None):
|
||||||
super(GeocoderConfig, self).__init__(redis_connection, username,
|
super(GeocoderConfig, self).__init__(redis_connection, db_conn,
|
||||||
orgname)
|
username, orgname)
|
||||||
db_config = ServicesDBConfig(db_conn)
|
filtered_config = {key: self._redis_config[key] for key in self.GEOCODER_CONFIG_KEYS if key in self._redis_config.keys()}
|
||||||
config = self.__get_user_config(username, orgname)
|
self.__parse_config(filtered_config, self._db_config)
|
||||||
filtered_config = {key: config[key] for key in self.GEOCODER_CONFIG_KEYS if key in config.keys()}
|
|
||||||
self.__parse_config(filtered_config, db_config)
|
|
||||||
self.__check_config(filtered_config)
|
self.__check_config(filtered_config)
|
||||||
|
|
||||||
def __get_user_config(self, username, orgname):
|
def __get_user_config(self, username, orgname):
|
||||||
@ -226,7 +209,7 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
if self.GOOGLE_GEOCODER_API_KEY not in filtered_config.keys():
|
if self.GOOGLE_GEOCODER_API_KEY not in filtered_config.keys():
|
||||||
raise ConfigException("""Google geocoder need the mandatory parameter 'google_maps_private_key'""")
|
raise ConfigException("""Google geocoder need the mandatory parameter 'google_maps_private_key'""")
|
||||||
elif filtered_config[self.GEOCODER_TYPE].lower() == self.MAPZEN_GEOCODER:
|
elif filtered_config[self.GEOCODER_TYPE].lower() == self.MAPZEN_GEOCODER:
|
||||||
if not self.mapzen_app_key:
|
if not self.mapzen_api_key:
|
||||||
raise ConfigException("""Mapzen config is not setted up""")
|
raise ConfigException("""Mapzen config is not setted up""")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -249,7 +232,8 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
self._google_maps_client_id = filtered_config[self.GOOGLE_GEOCODER_CLIENT_ID]
|
self._google_maps_client_id = filtered_config[self.GOOGLE_GEOCODER_CLIENT_ID]
|
||||||
self._cost_per_hit = 0
|
self._cost_per_hit = 0
|
||||||
elif filtered_config[self.GEOCODER_TYPE].lower() == self.MAPZEN_GEOCODER:
|
elif filtered_config[self.GEOCODER_TYPE].lower() == self.MAPZEN_GEOCODER:
|
||||||
self._mapzen_app_key = db_config.mapzen_geocoder_app_key
|
self._mapzen_api_key = db_config.mapzen_geocoder_api_key
|
||||||
|
self._geocoding_quota = db_config.mapzen_geocoder_monthly_quota
|
||||||
self._cost_per_hit = 0
|
self._cost_per_hit = 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -283,10 +267,10 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def geocoding_quota(self):
|
def geocoding_quota(self):
|
||||||
if self.heremaps_geocoder:
|
if self.google_geocoder:
|
||||||
return self._geocoding_quota
|
|
||||||
else:
|
|
||||||
return None
|
return None
|
||||||
|
else:
|
||||||
|
return self._geocoding_quota
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def soft_geocoding_limit(self):
|
def soft_geocoding_limit(self):
|
||||||
@ -305,8 +289,8 @@ class GeocoderConfig(ServiceConfig):
|
|||||||
return self._heremaps_app_code
|
return self._heremaps_app_code
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mapzen_app_key(self):
|
def mapzen_api_key(self):
|
||||||
return self._mapzen_app_key
|
return self._mapzen_api_key
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_high_resolution(self):
|
def is_high_resolution(self):
|
||||||
@ -351,8 +335,10 @@ class ServicesDBConfig:
|
|||||||
raise ConfigException('Mapzen configuration missing')
|
raise ConfigException('Mapzen configuration missing')
|
||||||
else:
|
else:
|
||||||
mapzen_conf = json.loads(mapzen_conf_json)
|
mapzen_conf = json.loads(mapzen_conf_json)
|
||||||
self._mapzen_routing_app_key = mapzen_conf['routing_app_key']
|
self._mapzen_routing_api_key = mapzen_conf['routing']['api_key']
|
||||||
self._mapzen_geocoder_app_key = mapzen_conf['geocoder_app_key']
|
self._mapzen_routing_quota = mapzen_conf['routing']['monthly_quota']
|
||||||
|
self._mapzen_geocoder_api_key = mapzen_conf['geocoder']['api_key']
|
||||||
|
self._mapzen_geocoder_quota = mapzen_conf['geocoder']['monthly_quota']
|
||||||
|
|
||||||
def _get_logger_config(self):
|
def _get_logger_config(self):
|
||||||
logger_conf_json = self._get_conf('logger_conf')
|
logger_conf_json = self._get_conf('logger_conf')
|
||||||
@ -391,13 +377,57 @@ class ServicesDBConfig:
|
|||||||
return self._heremaps_geocoder_cost_per_hit
|
return self._heremaps_geocoder_cost_per_hit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mapzen_routing_app_key(self):
|
def mapzen_routing_api_key(self):
|
||||||
return self._mapzen_routing_app_key
|
return self._mapzen_routing_api_key
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mapzen_geocoder_app_key(self):
|
def mapzen_routing_monthly_quota(self):
|
||||||
return self._mapzen_geocoder_app_key
|
return self._mapzen_routing_quota
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mapzen_geocoder_api_key(self):
|
||||||
|
return self._mapzen_geocoder_api_key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mapzen_geocoder_monthly_quota(self):
|
||||||
|
return self._mapzen_geocoder_quota
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geocoder_log_path(self):
|
def geocoder_log_path(self):
|
||||||
return self._geocoder_log_path
|
return self._geocoder_log_path
|
||||||
|
|
||||||
|
|
||||||
|
class ServicesRedisConfig:
|
||||||
|
|
||||||
|
GOOGLE_GEOCODER_API_KEY = 'google_maps_api_key'
|
||||||
|
GOOGLE_GEOCODER_CLIENT_ID = 'google_maps_client_id'
|
||||||
|
QUOTA_KEY = 'geocoding_quota'
|
||||||
|
PERIOD_END_DATE = 'period_end_date'
|
||||||
|
|
||||||
|
def __init__(self, redis_conn):
|
||||||
|
self._redis_connection = redis_conn
|
||||||
|
|
||||||
|
def build(self, username, password):
|
||||||
|
return self.__get_user_config(username, password)
|
||||||
|
|
||||||
|
def __get_user_config(self, username, orgname):
|
||||||
|
user_config = self._redis_connection.hgetall(
|
||||||
|
"rails:users:{0}".format(username))
|
||||||
|
if not user_config:
|
||||||
|
raise ConfigException("""There is no user config available. Please check your configuration.'""")
|
||||||
|
else:
|
||||||
|
if orgname:
|
||||||
|
self.__get_organization_config(orgname, user_config)
|
||||||
|
|
||||||
|
return user_config
|
||||||
|
|
||||||
|
def __get_organization_config(self, orgname, user_config):
|
||||||
|
org_config = self._redis_connection.hgetall(
|
||||||
|
"rails:orgs:{0}".format(orgname))
|
||||||
|
if not org_config:
|
||||||
|
raise ConfigException("""There is no organization config available. Please check your configuration.'""")
|
||||||
|
else:
|
||||||
|
user_config[self.QUOTA_KEY] = org_config[self.QUOTA_KEY]
|
||||||
|
user_config[self.PERIOD_END_DATE] = org_config[self.PERIOD_END_DATE]
|
||||||
|
user_config[self.GOOGLE_GEOCODER_CLIENT_ID] = org_config[self.GOOGLE_GEOCODER_CLIENT_ID]
|
||||||
|
user_config[self.GOOGLE_GEOCODER_API_KEY] = org_config[self.GOOGLE_GEOCODER_API_KEY]
|
||||||
|
@ -70,6 +70,9 @@ class QuotaChecker:
|
|||||||
elif re.match('here_isolines',
|
elif re.match('here_isolines',
|
||||||
self._user_service_config.service_type) is not None:
|
self._user_service_config.service_type) is not None:
|
||||||
return self.__check_isolines_quota()
|
return self.__check_isolines_quota()
|
||||||
|
elif re.match('routing_mapzen',
|
||||||
|
self._user_service_config.service_type) is not None:
|
||||||
|
return self.__check_routing_quota()
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -100,3 +103,14 @@ class QuotaChecker:
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def __check_routing_quota(self):
|
||||||
|
user_quota = self._user_service_config.monthly_quota
|
||||||
|
today = date.today()
|
||||||
|
service_type = self._user_service_config.service_type
|
||||||
|
current_used = self._user_service.used_quota(service_type, today)
|
||||||
|
|
||||||
|
if (user_quota > 0 and current_used <= user_quota):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
@ -41,11 +41,12 @@ class UserMetricsService:
|
|||||||
return current_use
|
return current_use
|
||||||
|
|
||||||
def __used_isolines_quota(self, service_type, date):
|
def __used_isolines_quota(self, service_type, date):
|
||||||
|
""" Recover the used quota for the user in the current month """
|
||||||
date_from, date_to = self.__current_billing_cycle()
|
date_from, date_to = self.__current_billing_cycle()
|
||||||
current_use = 0
|
current_use = 0
|
||||||
isolines_generated = self.get_metrics(service_type,
|
isolines_generated = self.get_metrics(service_type,
|
||||||
'isolines_generated', date_from,
|
'isolines_generated', date_from,
|
||||||
date_to)
|
date_to)
|
||||||
empty_responses = self.get_metrics(service_type,
|
empty_responses = self.get_metrics(service_type,
|
||||||
'empty_responses', date_from,
|
'empty_responses', date_from,
|
||||||
date_to)
|
date_to)
|
||||||
@ -53,12 +54,27 @@ class UserMetricsService:
|
|||||||
|
|
||||||
return current_use
|
return current_use
|
||||||
|
|
||||||
|
def __used_routing_quota(self, service_type, date):
|
||||||
|
""" Recover the used quota for the user in the current month """
|
||||||
|
date_from, date_to = self.__current_billing_cycle()
|
||||||
|
current_use = 0
|
||||||
|
success_responses = self.get_metrics(service_type,
|
||||||
|
'success_responses', date_from,
|
||||||
|
date_to)
|
||||||
|
empty_responses = self.get_metrics(service_type,
|
||||||
|
'empty_responses', date_from,
|
||||||
|
date_to)
|
||||||
|
current_use += (success_responses + empty_responses)
|
||||||
|
|
||||||
def increment_service_use(self, service_type, metric, date=date.today(), amount=1):
|
return current_use
|
||||||
|
|
||||||
|
def increment_service_use(self, service_type, metric, date=date.today(),
|
||||||
|
amount=1):
|
||||||
""" Increment the services uses in monthly and daily basis"""
|
""" Increment the services uses in monthly and daily basis"""
|
||||||
self.__increment_user_uses(service_type, metric, date, amount)
|
self.__increment_user_uses(service_type, metric, date, amount)
|
||||||
if self._orgname:
|
if self._orgname:
|
||||||
self.__increment_organization_uses(service_type, metric, date, amount)
|
self.__increment_organization_uses(service_type, metric, date,
|
||||||
|
amount)
|
||||||
|
|
||||||
def get_metrics(self, service, metric, date_from, date_to):
|
def get_metrics(self, service, metric, date_from, date_to):
|
||||||
aggregated_metric = 0
|
aggregated_metric = 0
|
||||||
@ -83,11 +99,12 @@ class UserMetricsService:
|
|||||||
service_type, metric, date)
|
service_type, metric, date)
|
||||||
self._redis_connection.zincrby(redis_prefix, date.day, amount)
|
self._redis_connection.zincrby(redis_prefix, date.day, amount)
|
||||||
|
|
||||||
def __parse_redis_prefix(self, prefix, entity_name, service_type, metric, date):
|
def __parse_redis_prefix(self, prefix, entity_name, service_type, metric,
|
||||||
|
date):
|
||||||
yearmonth_key = date.strftime('%Y%m')
|
yearmonth_key = date.strftime('%Y%m')
|
||||||
redis_name = "{0}:{1}:{2}:{3}:{4}".format(prefix, entity_name,
|
redis_name = "{0}:{1}:{2}:{3}:{4}".format(prefix, entity_name,
|
||||||
service_type, metric,
|
service_type, metric,
|
||||||
yearmonth_key)
|
yearmonth_key)
|
||||||
|
|
||||||
return redis_name
|
return redis_name
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ from setuptools import setup, find_packages
|
|||||||
setup(
|
setup(
|
||||||
name='cartodb_services',
|
name='cartodb_services',
|
||||||
|
|
||||||
version='0.4.4',
|
version='0.4.5',
|
||||||
|
|
||||||
description='CartoDB Services API Python Library',
|
description='CartoDB Services API Python Library',
|
||||||
|
|
||||||
|
@ -46,6 +46,6 @@ def _plpy_execute_side_effect(*args, **kwargs):
|
|||||||
if args[0] == "SELECT cartodb.CDB_Conf_GetConf('heremaps_conf') as conf":
|
if args[0] == "SELECT cartodb.CDB_Conf_GetConf('heremaps_conf') as conf":
|
||||||
return [{'conf': '{"geocoder": {"app_id": "app_id", "app_code": "code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "app_id", "app_code": "code"}}'}]
|
return [{'conf': '{"geocoder": {"app_id": "app_id", "app_code": "code", "geocoder_cost_per_hit": 1}, "isolines": {"app_id": "app_id", "app_code": "code"}}'}]
|
||||||
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('mapzen_conf') as conf":
|
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('mapzen_conf') as conf":
|
||||||
return [{'conf': '{"routing_app_key": "app_key", "geocoder_app_key": "app_key"}'}]
|
return [{'conf': '{"routing": {"api_key": "valhalla-Z61FWEs", "monthly_quota": 1500000}, "geocoder": {"api_key": "search-d744tp0", "monthly_quota": 1500000}}'}]
|
||||||
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('logger_conf') as conf":
|
elif args[0] == "SELECT cartodb.CDB_Conf_GetConf('logger_conf') as conf":
|
||||||
return [{'conf': '{"geocoder_log_path": "/dev/null"}'}]
|
return [{'conf': '{"geocoder_log_path": "/dev/null"}'}]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import test_helper
|
import test_helper
|
||||||
from mockredis import MockRedis
|
from mockredis import MockRedis
|
||||||
from cartodb_services.metrics import QuotaService
|
from cartodb_services.metrics import QuotaService
|
||||||
from cartodb_services.metrics import GeocoderConfig
|
from cartodb_services.metrics import GeocoderConfig, RoutingConfig
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from nose.tools import assert_raises
|
from nose.tools import assert_raises
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
@ -18,79 +18,124 @@ class TestQuotaService(TestCase):
|
|||||||
self.redis_conn = MockRedis()
|
self.redis_conn = MockRedis()
|
||||||
|
|
||||||
def test_should_return_true_if_user_quota_with_no_use(self):
|
def test_should_return_true_if_user_quota_with_no_use(self):
|
||||||
qs = self.__build_quota_service('test_user')
|
qs = self.__build_geocoder_quota_service('test_user')
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_return_true_if_org_quota_with_no_use(self):
|
def test_should_return_true_if_org_quota_with_no_use(self):
|
||||||
qs = self.__build_quota_service('test_user', orgname='test_org')
|
qs = self.__build_geocoder_quota_service('test_user',
|
||||||
|
orgname='test_org')
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_return_true_if_user_quota_is_not_completely_used(self):
|
def test_should_return_true_if_user_quota_is_not_completely_used(self):
|
||||||
qs = self.__build_quota_service('test_user')
|
qs = self.__build_geocoder_quota_service('test_user')
|
||||||
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user')
|
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user')
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_return_true_if_org_quota_is_not_completely_used(self):
|
def test_should_return_true_if_org_quota_is_not_completely_used(self):
|
||||||
qs = self.__build_quota_service('test_user', orgname='test_org')
|
qs = self.__build_geocoder_quota_service('test_user',
|
||||||
|
orgname='test_org')
|
||||||
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
||||||
orgname='test_org')
|
orgname='test_org')
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_return_false_if_user_quota_is_surpassed(self):
|
def test_should_return_false_if_user_quota_is_surpassed(self):
|
||||||
qs = self.__build_quota_service('test_user')
|
qs = self.__build_geocoder_quota_service('test_user')
|
||||||
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
||||||
amount=300)
|
amount=300)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
def test_should_return_false_if_org_quota_is_surpassed(self):
|
def test_should_return_false_if_org_quota_is_surpassed(self):
|
||||||
qs = self.__build_quota_service('test_user', orgname='test_org')
|
qs = self.__build_geocoder_quota_service('test_user',
|
||||||
|
orgname='test_org')
|
||||||
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
||||||
orgname='test_org', amount=400)
|
orgname='test_org', amount=400)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
def test_should_return_true_if_user_quota_is_surpassed_but_soft_limit_is_enabled(self):
|
def test_should_return_true_if_user_quota_is_surpassed_but_soft_limit_is_enabled(self):
|
||||||
qs = self.__build_quota_service('test_user', soft_limit=True)
|
qs = self.__build_geocoder_quota_service('test_user', soft_limit=True)
|
||||||
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
||||||
amount=300)
|
amount=300)
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_return_true_if_org_quota_is_surpassed_but_soft_limit_is_enabled(self):
|
def test_should_return_true_if_org_quota_is_surpassed_but_soft_limit_is_enabled(self):
|
||||||
qs = self.__build_quota_service('test_user', orgname='test_org',
|
qs = self.__build_geocoder_quota_service('test_user',
|
||||||
soft_limit=True)
|
orgname='test_org',
|
||||||
|
soft_limit=True)
|
||||||
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
test_helper.increment_geocoder_uses(self.redis_conn, 'test_user',
|
||||||
orgname='test_org', amount=400)
|
orgname='test_org', amount=400)
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
|
|
||||||
def test_should_check_user_increment_and_quota_check_correctly(self):
|
def test_should_check_user_increment_and_quota_check_correctly(self):
|
||||||
qs = self.__build_quota_service('test_user', quota=2)
|
qs = self.__build_geocoder_quota_service('test_user', quota=2)
|
||||||
qs.increment_success_service_use()
|
qs.increment_success_service_use()
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
qs.increment_success_service_use(amount=2)
|
qs.increment_success_service_use(amount=2)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is False
|
||||||
month = date.today().strftime('%Y%m')
|
|
||||||
|
|
||||||
def test_should_check_org_increment_and_quota_check_correctly(self):
|
def test_should_check_org_increment_and_quota_check_correctly(self):
|
||||||
qs = self.__build_quota_service('test_user', orgname='test_org',
|
qs = self.__build_geocoder_quota_service('test_user', quota=2,
|
||||||
quota=2)
|
orgname='test_org')
|
||||||
qs.increment_success_service_use()
|
qs.increment_success_service_use()
|
||||||
assert qs.check_user_quota() is True
|
assert qs.check_user_quota() is True
|
||||||
qs.increment_success_service_use(amount=2)
|
qs.increment_success_service_use(amount=2)
|
||||||
assert qs.check_user_quota() is False
|
assert qs.check_user_quota() is False
|
||||||
month = date.today().strftime('%Y%m')
|
|
||||||
|
|
||||||
def __build_quota_service(self, username, quota=100, service='heremaps',
|
def test_should_check_user_mapzen_geocoder_quota_correctly(self):
|
||||||
orgname=None, soft_limit=False,
|
qs = self.__build_geocoder_quota_service('test_user', service='mapzen')
|
||||||
end_date = datetime.today()):
|
qs.increment_success_service_use()
|
||||||
|
assert qs.check_user_quota() is True
|
||||||
|
qs.increment_success_service_use(amount=1500000)
|
||||||
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
|
def test_should_check_org_mapzen_geocoder_quota_correctly(self):
|
||||||
|
qs = self.__build_geocoder_quota_service('test_user', orgname='testorg',
|
||||||
|
service='mapzen')
|
||||||
|
qs.increment_success_service_use()
|
||||||
|
assert qs.check_user_quota() is True
|
||||||
|
qs.increment_success_service_use(amount=1500000)
|
||||||
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
|
def test_should_check_user_routing_quota_correctly(self):
|
||||||
|
qs = self.__build_routing_quota_service('test_user')
|
||||||
|
qs.increment_success_service_use()
|
||||||
|
assert qs.check_user_quota() is True
|
||||||
|
qs.increment_success_service_use(amount=1500000)
|
||||||
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
|
def test_should_check_org_routing_quota_correctly(self):
|
||||||
|
qs = self.__build_routing_quota_service('test_user', orgname='testorg')
|
||||||
|
qs.increment_success_service_use()
|
||||||
|
assert qs.check_user_quota() is True
|
||||||
|
qs.increment_success_service_use(amount=1500000)
|
||||||
|
assert qs.check_user_quota() is False
|
||||||
|
|
||||||
|
def __prepare_quota_service(self, username, quota, service, orgname,
|
||||||
|
soft_limit, end_date):
|
||||||
test_helper.build_redis_user_config(self.redis_conn, username,
|
test_helper.build_redis_user_config(self.redis_conn, username,
|
||||||
quota = quota, service = service,
|
quota=quota, service=service,
|
||||||
soft_limit = soft_limit,
|
soft_limit=soft_limit,
|
||||||
end_date = end_date)
|
end_date=end_date)
|
||||||
if orgname:
|
if orgname:
|
||||||
test_helper.build_redis_org_config(self.redis_conn, orgname,
|
test_helper.build_redis_org_config(self.redis_conn, orgname,
|
||||||
quota=quota, end_date=end_date)
|
quota=quota, end_date=end_date)
|
||||||
plpy_mock = test_helper.build_plpy_mock()
|
self._plpy_mock = test_helper.build_plpy_mock()
|
||||||
geocoder_config = GeocoderConfig(self.redis_conn, plpy_mock,
|
|
||||||
username, orgname)
|
|
||||||
return QuotaService(geocoder_config,
|
|
||||||
redis_connection = self.redis_conn)
|
|
||||||
|
|
||||||
|
def __build_geocoder_quota_service(self, username, quota=100,
|
||||||
|
service='heremaps', orgname=None,
|
||||||
|
soft_limit=False,
|
||||||
|
end_date=datetime.today()):
|
||||||
|
self.__prepare_quota_service(username, quota, service, orgname,
|
||||||
|
soft_limit, end_date)
|
||||||
|
geocoder_config = GeocoderConfig(self.redis_conn, self._plpy_mock,
|
||||||
|
username, orgname)
|
||||||
|
return QuotaService(geocoder_config, redis_connection=self.redis_conn)
|
||||||
|
|
||||||
|
def __build_routing_quota_service(self, username, quota=100,
|
||||||
|
service='routing_mapzen', orgname=None,
|
||||||
|
soft_limit=False,
|
||||||
|
end_date=datetime.today()):
|
||||||
|
self.__prepare_quota_service(username, quota, service, orgname,
|
||||||
|
soft_limit, end_date)
|
||||||
|
routing_config = RoutingConfig(self.redis_conn, self._plpy_mock,
|
||||||
|
username, orgname)
|
||||||
|
return QuotaService(routing_config, redis_connection=self.redis_conn)
|
||||||
|
Loading…
Reference in New Issue
Block a user