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:
josephschorr 2017-07-13 00:23:15 +03:00 committed by GitHub
commit fdb21aa5dc
13 changed files with 167 additions and 87 deletions

View file

View 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

View 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()

View file

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

View 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')