Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes bug 867388 - Added basic middleware services for Bixie. #1307

Merged
merged 1 commit into from Jul 8, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 17 additions & 22 deletions socorro/external/postgresql/error.py
Expand Up @@ -2,20 +2,13 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import logging

from socorro.external import MissingOrBadArgumentError
from socorro.external.postgresql.base import PostgreSQLBase
from socorro.lib import datetimeutil, external_common

logger = logging.getLogger("webapi")


class Error(PostgreSQLBase):

"""
Implement the /error service with PostgreSQL.
"""
"""Implement the /error service with PostgreSQL. """

def get(self, **kwargs):
"""Return a single error report from its UUID. """
Expand All @@ -26,11 +19,10 @@ def get(self, **kwargs):

if params.uuid is None:
raise MissingOrBadArgumentError(
"Mandatory parameter 'uuid' is missing or empty")
"Mandatory parameter 'uuid' is missing or empty"
)

crash_date = datetimeutil.uuid_to_date(params.uuid)
logger.debug("Looking for error %s during day %s" % (params.uuid,
crash_date))

sql = """/* socorro.external.postgresql.error.Error.get */
SELECT
Expand All @@ -40,26 +32,29 @@ def get(self, **kwargs):
FROM bixie.crashes
WHERE bixie.crashes.crash_id=%(uuid)s
AND bixie.crashes.success IS NOT NULL
AND utc_day_is( bixie.crashes.processor_completed_datetime, %(crash_date)s)
AND utc_day_is(
bixie.crashes.processor_completed_datetime,
%(crash_date)s
)
"""
sql_params = {
"uuid": params.uuid,
"uuid": params.uuid,
"crash_date": crash_date
}

error_message = "Failed to retrieve crash data from PostgreSQL"
error_message = "Failed to retrieve error data from PostgreSQL"
results = self.query(sql, sql_params, error_message=error_message)

crashes = []
errors = []
for row in results:
crash = dict(zip((
"product",
"error",
"signature"), row))
crashes.append(crash)
error = dict(zip((
"product",
"error",
"signature"
), row))
errors.append(error)

return {
"hits": crashes,
"total": len(crashes)
"hits": errors,
"total": len(errors)
}
87 changes: 87 additions & 0 deletions socorro/external/postgresql/errors.py
@@ -0,0 +1,87 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import datetime

from socorro.external import MissingOrBadArgumentError
from socorro.external.postgresql.base import PostgreSQLBase
from socorro.lib import datetimeutil, external_common, search_common


class Errors(PostgreSQLBase):
'''Implement the /errors services with PostgreSQL. '''

def get_signatures(self, **kwargs):
'''Return a list of errors aggregated by signatures. '''
now = datetimeutil.utc_now()
lastweek = now - datetime.timedelta(7)

filters = [
('signature', None, 'str'),
('search_mode', 'is_exactly', 'str'),
('product', None, 'str'),
('start_date', lastweek, 'datetime'),
('end_date', now, 'datetime'),
]
params = external_common.parse_arguments(filters, kwargs)

authorized_search_modes = (
'is_exactly',
'contains',
'starts_with',
'ends_with'
)
if params.search_mode not in authorized_search_modes:
search_mode = authorized_search_modes[0]

fields = ('signature', 'count')
sql_fields = {
'signature': 'signature',
'count': 'count(crash_id) as total'
}

sql = '''/* socorro.external.postgresql.error.Error.get */
SELECT %s
FROM bixie.crashes
WHERE success IS NOT NULL
AND processor_completed_datetime BETWEEN
%%(start_date)s AND %%(end_date)s
''' % ', '.join(sql_fields[x] for x in fields)

sql_where = [sql]
if params.signature:
if params.search_mode == 'is_exactly':
sql_where.append('signature = %(signature)s')
else:
if params.search_mode == 'contains':
params.signature = '%%%s%%' % params.signature
elif params.search_mode == 'starts_with':
params.signature = '%%%s' % params.signature
elif params.search_mode == 'ends_with':
params.signature = '%s%%' % params.signature

sql_where.append('signature LIKE %(signature)s')

if params.product:
sql_where.append('product = %(product)s')

sql = ' AND '.join(sql_where)

sql_group = 'GROUP BY signature'
sql_order = 'ORDER BY total DESC, signature'

sql = ' '.join((sql, sql_group, sql_order))

error_message = 'Failed to retrieve error data from PostgreSQL'
results = self.query(sql, params, error_message=error_message)

errors = []
for row in results:
error = dict(zip(fields, row))
errors.append(error)

return {
'hits': errors,
'total': len(errors)
}
74 changes: 53 additions & 21 deletions socorro/external/postgresql/products.py
Expand Up @@ -4,6 +4,7 @@

import logging

from socorro.external import MissingOrBadArgumentError
from socorro.external.postgresql.base import add_param_to_dict, PostgreSQLBase
from socorro.lib import datetimeutil, external_common

Expand All @@ -16,27 +17,51 @@ def get(self, **kwargs):
""" Return product information, or version information for one
or more product:version combinations """
filters = [
("versions", None, ["list", "str"]) # for legacy, to be removed
("versions", None, ["list", "str"]), # for legacy, to be removed
("type", "desktop", "str"),
]
params = external_common.parse_arguments(filters, kwargs)

accepted_types = ("desktop", "webapp")
if params.type not in accepted_types:
raise MissingOrBadArgumentError(
"Bad value for parameter 'type': got '%s', expected one of %s)"
% (params.type, accepted_types)
)

if params.versions and params.versions[0]:
return self._get_versions(params)

sql = """
/* socorro.external.postgresql.products.Products.get */
SELECT
product_name,
version_string,
start_date,
end_date,
throttle,
is_featured,
build_type,
has_builds
FROM product_info
ORDER BY product_sort, version_sort DESC, channel_sort
"""
if params.type == "desktop":
sql = """
/* socorro.external.postgresql.products.Products.get */
SELECT
product_name,
version_string,
start_date,
end_date,
throttle,
is_featured,
build_type,
has_builds
FROM product_info
ORDER BY product_sort, version_sort DESC, channel_sort
"""
elif params.type == "webapp":
sql = """
/* socorro.external.postgresql.products.Products.get */
SELECT
product_name,
version,
NULL as start_date,
NULL as end_date,
1.0 as throttle,
FALSE as is_featured,
build_type,
FALSE as has_builds
FROM bixie.raw_product_releases
ORDER BY product_name, version DESC
"""

error_message = "Failed to retrieve products/versions from PostgreSQL"
results = self.query(sql, error_message=error_message)
Expand All @@ -56,12 +81,19 @@ def get(self, **kwargs):
'has_builds',
), row))

version['end_date'] = datetimeutil.date_to_string(
version['end_date']
)
version['start_date'] = datetimeutil.date_to_string(
version['start_date']
)
try:
version['end_date'] = datetimeutil.date_to_string(
version['end_date']
)
except TypeError:
pass
try:
version['start_date'] = datetimeutil.date_to_string(
version['start_date']
)
except TypeError:
pass

version['throttle'] = float(version['throttle'])

product = version['product']
Expand Down
24 changes: 12 additions & 12 deletions socorro/unittest/external/postgresql/test_error.py
Expand Up @@ -82,6 +82,18 @@ def setUp(self):

self.connection.commit()

#--------------------------------------------------------------------------
def tearDown(self):
"""Clean up the database, delete tables and functions. """
cursor = self.connection.cursor()
cursor.execute(""" SET search_path TO bixie """)
cursor.execute("""
TRUNCATE crashes
CASCADE
""")
self.connection.commit()
super(IntegrationTestError, self).tearDown()

#--------------------------------------------------------------------------
def test_get(self):
""" Test GET for Bixie Errors """
Expand Down Expand Up @@ -115,15 +127,3 @@ def test_get(self):
}

self.assertEqual(res, res_expected)

#--------------------------------------------------------------------------
def tearDown(self):
"""Clean up the database, delete tables and functions. """
cursor = self.connection.cursor()
cursor.execute(""" SET search_path TO bixie """)
cursor.execute("""
TRUNCATE crashes
CASCADE
""")
self.connection.commit()
super(IntegrationTestError, self).tearDown()