Merge pull request #2777 from coreos-inc/joseph.schorr/QUAY-618/notificationworker-data-interface
Change notificationworker to use data interface
This commit is contained in:
commit
fdb21aa5dc
13 changed files with 167 additions and 87 deletions
0
workers/notificationworker/__init__.py
Normal file
0
workers/notificationworker/__init__.py
Normal file
50
workers/notificationworker/models_interface.py
Normal file
50
workers/notificationworker/models_interface.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
from abc import ABCMeta, abstractmethod
|
||||
from collections import namedtuple
|
||||
from six import add_metaclass
|
||||
|
||||
|
||||
class Repository(namedtuple('Repository', ['namespace_name', 'name'])):
|
||||
"""
|
||||
Repository represents a repository.
|
||||
"""
|
||||
|
||||
|
||||
class Notification(
|
||||
namedtuple('Notification', [
|
||||
'uuid', 'event_name', 'method_name', 'event_config_dict', 'method_config_dict',
|
||||
'repository'])):
|
||||
"""
|
||||
Notification represents a registered notification of some kind.
|
||||
"""
|
||||
|
||||
|
||||
@add_metaclass(ABCMeta)
|
||||
class NotificationWorkerDataInterface(object):
|
||||
"""
|
||||
Interface that represents all data store interactions required by the notification worker.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def get_enabled_notification(self, notification_uuid):
|
||||
""" Returns an *enabled* notification with the given UUID, or None if none. """
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def reset_number_of_failures_to_zero(self, notification):
|
||||
""" Resets the number of failures for the given notification back to zero. """
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def increment_notification_failure_count(self, notification):
|
||||
""" Increments the number of failures on the given notification. """
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def create_notification_for_testing(self, target_username):
|
||||
""" Creates a notification for testing. """
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def user_has_local_notifications(self, target_username):
|
||||
""" Returns whether there are any Quay-local notifications for the given user. """
|
||||
pass
|
46
workers/notificationworker/models_pre_oci.py
Normal file
46
workers/notificationworker/models_pre_oci.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
import json
|
||||
|
||||
from data import model
|
||||
from workers.notificationworker.models_interface import (
|
||||
NotificationWorkerDataInterface, Notification, Repository)
|
||||
|
||||
|
||||
class PreOCIModel(NotificationWorkerDataInterface):
|
||||
def get_enabled_notification(self, notification_uuid):
|
||||
try:
|
||||
notification_row = model.notification.get_enabled_notification(notification_uuid)
|
||||
except model.InvalidNotificationException:
|
||||
return None
|
||||
|
||||
return Notification(uuid=notification_uuid, event_name=notification_row.event.name,
|
||||
method_name=notification_row.method.name,
|
||||
event_config_dict=json.loads(notification_row.event_config_json),
|
||||
method_config_dict=json.loads(notification_row.config_json),
|
||||
repository=Repository(notification_row.repository.namespace_user.username,
|
||||
notification_row.repository.name))
|
||||
|
||||
def reset_number_of_failures_to_zero(self, notification):
|
||||
model.notification.reset_notification_number_of_failures(
|
||||
notification.repository.namespace_name, notification.repository.name, notification.uuid)
|
||||
|
||||
def increment_notification_failure_count(self, notification):
|
||||
model.notification.increment_notification_failure_count(notification.uuid)
|
||||
|
||||
def create_notification_for_testing(self, target_username):
|
||||
repo = model.repository.get_repository('devtable', 'simple')
|
||||
method_data = {
|
||||
'target': {
|
||||
'kind': 'user',
|
||||
'name': target_username,
|
||||
}
|
||||
}
|
||||
notification = model.notification.create_repo_notification(repo, 'build_success',
|
||||
'quay_notification', method_data, {})
|
||||
return notification.uuid
|
||||
|
||||
def user_has_local_notifications(self, target_username):
|
||||
user = model.user.get_namespace_user(target_username)
|
||||
return bool(list(model.notification.list_notifications(user)))
|
||||
|
||||
|
||||
pre_oci_model = PreOCIModel()
|
|
@ -1,29 +1,22 @@
|
|||
import logging
|
||||
|
||||
from app import notification_queue
|
||||
from data.model.notification import increment_notification_failure_count, reset_number_of_failures_to_zero
|
||||
|
||||
from endpoints.notificationmethod import NotificationMethod, InvalidNotificationMethodException
|
||||
from endpoints.notificationevent import NotificationEvent, InvalidNotificationEventException
|
||||
from workers.notificationworker.models_pre_oci import pre_oci_model as model
|
||||
from workers.queueworker import QueueWorker, JobException
|
||||
|
||||
from data import model
|
||||
from data.model import InvalidNotificationException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NotificationWorker(QueueWorker):
|
||||
def process_queue_item(self, job_details):
|
||||
notification_uuid = job_details['notification_uuid']
|
||||
|
||||
try:
|
||||
notification = model.notification.get_enabled_notification(notification_uuid)
|
||||
except InvalidNotificationException:
|
||||
notification = model.get_enabled_notification(job_details['notification_uuid'])
|
||||
if notification is None:
|
||||
return
|
||||
|
||||
event_name = notification.event.name
|
||||
method_name = notification.method.name
|
||||
event_name = notification.event_name
|
||||
method_name = notification.method_name
|
||||
|
||||
try:
|
||||
event_handler = NotificationEvent.get_event(event_name)
|
||||
|
@ -38,9 +31,9 @@ class NotificationWorker(QueueWorker):
|
|||
if event_handler.should_perform(job_details['event_data'], notification):
|
||||
try:
|
||||
method_handler.perform(notification, event_handler, job_details)
|
||||
reset_number_of_failures_to_zero(notification.id)
|
||||
model.reset_number_of_failures_to_zero(notification)
|
||||
except (JobException, KeyError) as exc:
|
||||
increment_notification_failure_count(notification.id)
|
||||
model.increment_notification_failure_count(notification)
|
||||
raise exc
|
||||
|
||||
|
23
workers/notificationworker/test/test_notificationworker.py
Normal file
23
workers/notificationworker/test/test_notificationworker.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from workers.notificationworker.notificationworker import NotificationWorker
|
||||
|
||||
from test.fixtures import *
|
||||
|
||||
from workers.notificationworker.models_pre_oci import pre_oci_model as model
|
||||
|
||||
def test_basic_notification(initialized_db):
|
||||
# Ensure the public user doesn't have any notifications.
|
||||
assert not model.user_has_local_notifications('public')
|
||||
|
||||
# Add a basic build notification.
|
||||
notification_uuid = model.create_notification_for_testing('public')
|
||||
event_data = {}
|
||||
|
||||
# Fire off the queue processing.
|
||||
worker = NotificationWorker(None)
|
||||
worker.process_queue_item({
|
||||
'notification_uuid': notification_uuid,
|
||||
'event_data': event_data,
|
||||
})
|
||||
|
||||
# Ensure the notification was handled.
|
||||
assert model.user_has_local_notifications('public')
|
Reference in a new issue