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:
Mathieu Pillard 2020-07-28 11:57:54 +02:00 коммит произвёл GitHub
Родитель b0f602ad83
Коммит 14223cfe24
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 0 добавлений и 253 удалений

Просмотреть файл

@ -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.