Drop obsolete lightweight theme update endpoint (#15060)
* Drop obsolete lightweight theme update endpoint * Remove obsolete MIGRATED_LWT_UPDATES_ENABLED setting
This commit is contained in:
Родитель
b0f602ad83
Коммит
14223cfe24
|
@ -1,120 +0,0 @@
|
|||
import json
|
||||
import re
|
||||
from time import time
|
||||
from wsgiref.handlers import format_date_time
|
||||
|
||||
from services.utils import (
|
||||
get_cdn_url, log_configure, log_exception, mypool, settings)
|
||||
|
||||
# This has to be imported after the settings (utils).
|
||||
from django_statsd.clients import statsd
|
||||
|
||||
# Configure the log.
|
||||
log_configure()
|
||||
|
||||
|
||||
class ThemeUpdate(object):
|
||||
|
||||
def __init__(self, locale, id_, qs=None):
|
||||
self.from_gp = qs == 'src=gp'
|
||||
self.addon_id = id_
|
||||
self.cursor = mypool.connect().cursor()
|
||||
|
||||
def get_headers(self, length):
|
||||
return [('Cache-Control', 'public, max-age=86400'),
|
||||
('Content-Length', str(length)),
|
||||
('Content-Type', 'application/json'),
|
||||
('Expires', format_date_time(time() + 86400)),
|
||||
('Last-Modified', format_date_time(time()))]
|
||||
|
||||
|
||||
class MigratedUpdate(ThemeUpdate):
|
||||
|
||||
def get_data(self):
|
||||
if hasattr(self, 'data'):
|
||||
return self.data
|
||||
|
||||
primary_key = (
|
||||
'getpersonas_id' if self.from_gp else 'lightweight_theme_id')
|
||||
|
||||
"""sql from:
|
||||
MigratedLWT.objects.filter(lightweight_theme_id=xxx).values_list(
|
||||
'static_theme_id',
|
||||
'static_theme___current_version__files__filename',
|
||||
'static_theme___current_version__files__hash').query"""
|
||||
|
||||
sql = """
|
||||
SELECT `migrated_personas`.`static_theme_id`,
|
||||
`files`.`filename`,
|
||||
`files`.`hash`
|
||||
FROM `migrated_personas`
|
||||
INNER JOIN `addons` T3 ON (
|
||||
`migrated_personas`.`static_theme_id` = T3.`id` )
|
||||
LEFT OUTER JOIN `versions` ON (
|
||||
T3.`current_version` = `versions`.`id` )
|
||||
LEFT OUTER JOIN `files` ON (
|
||||
`versions`.`id` = `files`.`version_id` )
|
||||
WHERE `migrated_personas`.{primary_key}=%(id)s
|
||||
""".format(primary_key=primary_key)
|
||||
self.cursor.execute(sql, {'id': self.addon_id})
|
||||
row = self.cursor.fetchone()
|
||||
self.data = (
|
||||
dict(zip(('stheme_id', 'filename', 'hash'), row)) if row else {})
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def is_migrated(self):
|
||||
return bool(self.get_data())
|
||||
|
||||
def get_json(self):
|
||||
if self.get_data():
|
||||
response = {
|
||||
"converted_theme": {
|
||||
"url": get_cdn_url(self.data['stheme_id'], self.data),
|
||||
"hash": self.data['hash']
|
||||
}
|
||||
}
|
||||
return json.dumps(response)
|
||||
|
||||
|
||||
url_re = re.compile(r'(?P<locale>.+)?/themes/update-check/(?P<id>\d+)$')
|
||||
|
||||
|
||||
def application(environ, start_response):
|
||||
"""
|
||||
Developing locally?
|
||||
|
||||
gunicorn -b 0.0.0.0:7000 -w 12 -k sync -t 90 --max-requests 5000 \
|
||||
-n gunicorn-theme_update services.wsgi.theme_update:application
|
||||
|
||||
"""
|
||||
|
||||
with statsd.timer('services.theme_update'):
|
||||
try:
|
||||
locale, id_ = url_re.match(environ['PATH_INFO']).groups()
|
||||
locale = (locale or 'en-US').lstrip('/')
|
||||
id_ = int(id_)
|
||||
except AttributeError: # URL path incorrect.
|
||||
start_response('404 Not Found', [])
|
||||
return ['']
|
||||
|
||||
try:
|
||||
query_string = environ.get('QUERY_STRING')
|
||||
update = MigratedUpdate(locale, id_, query_string)
|
||||
is_migrated = update.is_migrated
|
||||
if is_migrated:
|
||||
output = (
|
||||
update.get_json() if settings.MIGRATED_LWT_UPDATES_ENABLED
|
||||
else None)
|
||||
else:
|
||||
output = None
|
||||
|
||||
if not output:
|
||||
start_response('404 Not Found', [])
|
||||
return ['']
|
||||
start_response('200 OK', update.get_headers(len(output)))
|
||||
except Exception:
|
||||
log_exception(environ['PATH_INFO'])
|
||||
raise
|
||||
|
||||
return [output.encode('utf-8')]
|
|
@ -1,131 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
import io
|
||||
|
||||
from unittest import mock
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from django.db import connection
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from services import theme_update
|
||||
|
||||
from olympia import amo
|
||||
from olympia.addons.models import MigratedLWT
|
||||
from olympia.amo.templatetags.jinja_helpers import user_media_url
|
||||
from olympia.amo.tests import TestCase, addon_factory
|
||||
|
||||
|
||||
class TestWSGIApplication(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestWSGIApplication, self).setUp()
|
||||
self.environ = {'wsgi.input': io.StringIO()}
|
||||
self.start_response = mock.Mock()
|
||||
self.urls = {
|
||||
'/themes/update-check/5': ['en-US', 5, None],
|
||||
'/en-US/themes/update-check/5': ['en-US', 5, None],
|
||||
'/fr/themes/update-check/5': ['fr', 5, None]
|
||||
}
|
||||
|
||||
@mock.patch('services.theme_update.MigratedUpdate')
|
||||
@override_settings(MIGRATED_LWT_UPDATES_ENABLED=True)
|
||||
def test_wsgi_application_200_migrated(self, MigratedUpdate_mock):
|
||||
MigratedUpdate_mock.return_value.is_migrated = True
|
||||
MigratedUpdate_mock.return_value.get_json.return_value = (
|
||||
u'{"foó": "ba"}')
|
||||
# From AMO we consume the ID as the `addon_id`.
|
||||
for path_info, call_args in self.urls.items():
|
||||
environ = dict(self.environ, PATH_INFO=path_info)
|
||||
response = theme_update.application(environ, self.start_response)
|
||||
# wsgi expects a bytestring, rather than unicode response.
|
||||
assert response == [b'{"fo\xc3\xb3": "ba"}']
|
||||
MigratedUpdate_mock.assert_called_with(*call_args)
|
||||
self.start_response.assert_called_with('200 OK', mock.ANY)
|
||||
|
||||
# From getpersonas.com we append `?src=gp` so we know to consume
|
||||
# the ID as the `persona_id`.
|
||||
self.environ['QUERY_STRING'] = 'src=gp'
|
||||
for path_info, call_args in self.urls.items():
|
||||
environ = dict(self.environ, PATH_INFO=path_info)
|
||||
theme_update.application(environ, self.start_response)
|
||||
call_args[2] = 'src=gp'
|
||||
MigratedUpdate_mock.assert_called_with(*call_args)
|
||||
self.start_response.assert_called_with('200 OK', mock.ANY)
|
||||
|
||||
@mock.patch('services.theme_update.MigratedUpdate')
|
||||
def test_wsgi_application_404(self, MigratedUpdate_mock):
|
||||
urls = [
|
||||
'/xxx',
|
||||
'/themes/update-check/xxx',
|
||||
'/en-US/themes/update-check/xxx',
|
||||
'/fr/themes/update-check/xxx'
|
||||
]
|
||||
|
||||
for path_info in urls:
|
||||
environ = dict(self.environ, PATH_INFO=path_info)
|
||||
theme_update.application(environ, self.start_response)
|
||||
assert not MigratedUpdate_mock.called
|
||||
self.start_response.assert_called_with('404 Not Found', [])
|
||||
|
||||
@mock.patch('services.theme_update.MigratedUpdate')
|
||||
@override_settings(MIGRATED_LWT_UPDATES_ENABLED=False)
|
||||
def test_404_for_migrated_but_updates_disabled(self, MigratedUpdate_mock):
|
||||
MigratedUpdate_mock.return_value.is_migrated = True
|
||||
for path_info, call_args in self.urls.items():
|
||||
environ = dict(self.environ, PATH_INFO=path_info)
|
||||
theme_update.application(environ, self.start_response)
|
||||
MigratedUpdate_mock.assert_called_with(*call_args)
|
||||
self.start_response.assert_called_with('404 Not Found', [])
|
||||
|
||||
|
||||
class TestMigratedUpdate(TestCase):
|
||||
|
||||
def get_update(self, *args):
|
||||
update = theme_update.MigratedUpdate(*args)
|
||||
update.cursor = connection.cursor()
|
||||
return update
|
||||
|
||||
def test_is_migrated(self):
|
||||
stheme = addon_factory(type=amo.ADDON_STATICTHEME)
|
||||
assert not self.get_update('en-US', 666).is_migrated
|
||||
assert not self.get_update('en-US', 1234, 'src=gp').is_migrated
|
||||
|
||||
MigratedLWT.objects.create(
|
||||
lightweight_theme_id=666, static_theme=stheme, getpersonas_id=1234)
|
||||
assert self.get_update('en-US', 666).is_migrated
|
||||
assert self.get_update('en-US', 1234, 'src=gp').is_migrated
|
||||
assert not self.get_update('en-US', 667).is_migrated
|
||||
assert not self.get_update('en-US', 1235, 'src=gp').is_migrated
|
||||
|
||||
def test_response(self):
|
||||
stheme = addon_factory(type=amo.ADDON_STATICTHEME)
|
||||
stheme.current_version.files.all()[0].update(
|
||||
filename='foo.xpi', hash='brown')
|
||||
MigratedLWT.objects.create(
|
||||
lightweight_theme_id=999, static_theme=stheme, getpersonas_id=666)
|
||||
update = self.get_update('en-US', 999)
|
||||
|
||||
response = json.loads(update.get_json())
|
||||
url = '{0}{1}/{2}?{3}'.format(
|
||||
user_media_url('addons'), str(stheme.id), 'foo.xpi',
|
||||
urlencode({'filehash': 'brown'}))
|
||||
assert update.data == {
|
||||
'stheme_id': stheme.id, 'filename': 'foo.xpi', 'hash': 'brown'}
|
||||
assert response == {
|
||||
"converted_theme": {
|
||||
"url": url,
|
||||
"hash": 'brown'
|
||||
}
|
||||
}
|
||||
|
||||
update = self.get_update('en-US', 666, 'src=gp')
|
||||
response = json.loads(update.get_json())
|
||||
assert update.data == {
|
||||
'stheme_id': stheme.id, 'filename': 'foo.xpi', 'hash': 'brown'}
|
||||
assert response == {
|
||||
"converted_theme": {
|
||||
"url": url,
|
||||
"hash": 'brown'
|
||||
}
|
||||
}
|
|
@ -1908,8 +1908,6 @@ FXA_SQS_AWS_WAIT_TIME = 20 # Seconds.
|
|||
AWS_STATS_S3_BUCKET = env('AWS_STATS_S3_BUCKET', default=None)
|
||||
AWS_STATS_S3_PREFIX = env('AWS_STATS_S3_PREFIX', default='amo_stats')
|
||||
|
||||
MIGRATED_LWT_UPDATES_ENABLED = True
|
||||
|
||||
BASKET_URL = env('BASKET_URL', default='https://basket.allizom.org')
|
||||
BASKET_API_KEY = env('BASKET_API_KEY', default=None)
|
||||
# Default is 10, the API usually answers in 0.5 - 1.5 seconds.
|
||||
|
|
Загрузка…
Ссылка в новой задаче