Support purge queue

Implement blueprint: purge-queue

Change-Id: I2617d03d6ee7bcdf83859a9d4115e22793e02423
This commit is contained in:
Fei Long Wang 2017-02-20 14:42:56 +13:00
parent 282ed90538
commit 285301db58
8 changed files with 240 additions and 5 deletions

View File

@ -15,7 +15,7 @@ function install_zaqar_ui {
} }
function configure_zaqar_ui { function configure_zaqar_ui {
cp -a ${ZAQAR_UI_DIR}/zaqar_ui/enabled/* ${DEST}/horizon/openstack_dashboard/local/enabled/ #cp -a ${ZAQAR_UI_DIR}/zaqar_ui/enabled/* ${DEST}/horizon/openstack_dashboard/local/enabled/
# NOTE: If locale directory does not exist, compilemessages will fail, # NOTE: If locale directory does not exist, compilemessages will fail,
# so check for an existence of locale directory is required. # so check for an existence of locale directory is required.
if [ -d ${ZAQAR_UI_DIR}/zaqar_ui/locale ]; then if [ -d ${ZAQAR_UI_DIR}/zaqar_ui/locale ]; then

View File

@ -45,12 +45,19 @@ def _load_yaml(data):
@urls.register @urls.register
class Queue(generic.View): class Queue(generic.View):
"""API for retrieving a single queue""" """API for retrieving a single queue"""
url_regex = r'zaqar/queue/(?P<queue_name>[^/]+)$' url_regex = r'zaqar/queues/(?P<queue_name>[^/]+)$'
@rest_utils.ajax() @rest_utils.ajax()
def get(self, request, queue_name): def get(self, request, queue_name):
"""Get a specific queue""" """Get a specific queue"""
return zaqar.queue_get(request, queue_name).to_dict() queue = zaqar.queue_get(request, queue_name)
stats = queue.stats['messages']
queue_info = {'name': queue_name,
'claimed': stats['claimed'],
'free': stats['free'],
'total': stats['total'],
'metadata': queue.metadata()}
return queue_info
@rest_utils.ajax(data_required=True) @rest_utils.ajax(data_required=True)
def post(self, request, queue_name): def post(self, request, queue_name):
@ -59,12 +66,28 @@ class Queue(generic.View):
Returns the updated queue object on success. Returns the updated queue object on success.
""" """
queue = zaqar.queue_update(request, queue_name, **request.DATA) queue = zaqar.queue_update(request, queue_name, **request.DATA)
location = '/api/zaqar/queue/%s' % queue._name location = '/api/zaqars/queue/%s' % queue._name
response = {'name': queue._name, response = {'name': queue._name,
'metadata': queue._metadata} 'metadata': queue._metadata}
return rest_utils.CreatedResponse(location, response) return rest_utils.CreatedResponse(location, response)
@urls.register
class QueueActions(generic.View):
"""API for actions on a single queue"""
url_regex = r'zaqar/queues/(?P<queue_name>[^/]+)/(?P<action>[^/]+)$'
@rest_utils.ajax(data_required=True)
def post(self, request, queue_name, action):
"""Actions for a queue"""
if action == "purge":
resource_types = request.DATA.get("resource_types")
zaqar.queue_purge(request, queue_name, resource_types)
elif action == "share":
# FIXME(flwang): This is placeholder for pre-signed feature.
pass
@urls.register @urls.register
class Queues(generic.View): class Queues(generic.View):
"""API for queues""" """API for queues"""

View File

@ -89,6 +89,11 @@ def queue_get(request, queue_name):
return zaqarclient(request).queue(queue_name, auto_create=False) return zaqarclient(request).queue(queue_name, auto_create=False)
def queue_purge(request, queue_name, resource_types):
queue = zaqarclient(request).queue(queue_name, auto_create=False)
queue.purge(resource_types=resource_types)
def subscription_list(request, queue_name): def subscription_list(request, queue_name):
return [{'subscriber': s.subscriber, return [{'subscriber': s.subscriber,
'id': s.id, 'id': s.id,

View File

@ -35,9 +35,11 @@
var service = { var service = {
getQueues: getQueues, getQueues: getQueues,
getQueue: getQueue,
createQueue: createQueue, createQueue: createQueue,
deleteQueue: deleteQueue, deleteQueue: deleteQueue,
updateQueue: updateQueue, updateQueue: updateQueue,
purgeQueue: purgeQueue,
getSubscriptions: getSubscriptions, getSubscriptions: getSubscriptions,
addSubscription: addSubscription, addSubscription: addSubscription,
deleteSubscription: deleteSubscription, deleteSubscription: deleteSubscription,
@ -62,6 +64,11 @@
return apiService.get(queuePath).error(error(msg)); return apiService.get(queuePath).error(error(msg));
} }
function getQueue(queueName) {
var msg = gettext('Unable to retrieve the Queue.');
return apiService.get(queuePath + queueName).error(error(msg));
}
function createQueue(newQueue) { function createQueue(newQueue) {
var msg = gettext('Unable to create the queue.'); var msg = gettext('Unable to create the queue.');
return apiService.put(queuePath, newQueue).error(error(msg)); return apiService.put(queuePath, newQueue).error(error(msg));
@ -73,11 +80,18 @@
function updateQueue(queue) { function updateQueue(queue) {
var msg = gettext('Unable to update the queue.'); var msg = gettext('Unable to update the queue.');
var url = '/api/zaqar/queue/' + queue.queue_name; var url = queuePath + queue.queue_name;
var form = { metadata: queue.metadata }; var form = { metadata: queue.metadata };
return apiService.post(url, form).error(error(msg)); return apiService.post(url, form).error(error(msg));
} }
function purgeQueue(queueName, resourceTypes) {
var msg = gettext('Unable to purge the queue.');
var url = queuePath + queueName + '/purge';
var form = resourceTypes;
return apiService.post(url, form).error(error(msg));
}
function getSubscriptions(queue) { function getSubscriptions(queue) {
var url = interpolate(subPath, [queue.name]); var url = interpolate(subPath, [queue.name]);
return apiService.get(url); return apiService.get(url);

View File

@ -32,6 +32,7 @@
'horizon.dashboard.project.queues.actions.createQueueService', 'horizon.dashboard.project.queues.actions.createQueueService',
'horizon.dashboard.project.queues.actions.deleteQueueService', 'horizon.dashboard.project.queues.actions.deleteQueueService',
'horizon.dashboard.project.queues.actions.updateQueueService', 'horizon.dashboard.project.queues.actions.updateQueueService',
'horizon.dashboard.project.queues.actions.purgeQueueService',
'horizon.dashboard.project.queues.actions.createSubscriptionService', 'horizon.dashboard.project.queues.actions.createSubscriptionService',
'horizon.dashboard.project.queues.resourceType' 'horizon.dashboard.project.queues.resourceType'
]; ];
@ -41,6 +42,7 @@
createQueueService, createQueueService,
deleteQueueService, deleteQueueService,
updateQueueService, updateQueueService,
purgeQueueService,
createSubscriptionService, createSubscriptionService,
resourceType resourceType
) { ) {
@ -54,6 +56,13 @@
text: gettext('Update') text: gettext('Update')
} }
}) })
.append({
id: 'queuesItemPurge',
service: purgeQueueService,
template: {
text: gettext('Purge')
}
})
.append({ .append({
id: 'subscriptionsCreate', id: 'subscriptionsCreate',
service: createSubscriptionService, service: createSubscriptionService,

View File

@ -0,0 +1,147 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use self file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
angular
.module('horizon.dashboard.project.queues')
.factory(
'horizon.dashboard.project.queues.actions.purgeQueueService', purgeQueueService);
purgeQueueService.$inject = [
'$q',
'horizon.app.core.openstack-service-api.policy',
'horizon.app.core.openstack-service-api.zaqar',
'horizon.dashboard.project.queues.events',
'horizon.framework.util.i18n.gettext',
'horizon.framework.util.q.extensions',
'horizon.framework.widgets.form.ModalFormService',
'horizon.framework.widgets.toast.service'
];
/**
* @ngdoc factory
* @name horizon.dashboard.project.queues.actions.purgeQueueService
* @param {Object} $q
* @param {Object} policy
* @param {Object} zaqar
* @param {Object} events
* @param {Object} gettext
* @param {Object} $qExtensions
* @param {Object} modal
* @param {Object} toast
* @returns {Object} purge queue service
* @description Brings up the purge queues choices modal dialog.
* On submit, purge given queues.
* On cancel, do nothing.
*/
function purgeQueueService(
$q, policy, zaqar, events, gettext, $qExtensions, modal, toast
) {
// schema
var schema = {
type: "object",
properties: {
resource_types: {
title: gettext("Choose resource to purge"),
type: "string",
enum: ["messages", "subscriptions", "all"]
}
}
};
// form
var form = [
{
type: 'section',
htmlClass: 'row',
items: [
{
type: 'section',
htmlClass: 'col-sm-12',
items: [
{
key: 'resource_types',
type: 'radiobuttons',
titleMap: [
{value: 'messages', name: gettext('Messages')},
{value: 'subscriptions', name: gettext('Subscriptions')},
{value: "all", name: "All"}
],
required:true
}
]
}
]
}
];
var scope, model;
var message = {
success: gettext('Queue %s has been purged successfully.')
};
var service = {
initAction: initAction,
perform: perform,
allowed: allowed
};
return service;
//////////////
function initAction() {
}
function allowed() {
return $qExtensions.booleanAsPromise(true);
}
function perform(selected, $scope) {
scope = $scope;
model = {
id: selected.id,
name: selected.name,
resource_types: []
};
// modal config
var config = {
"title": gettext('Purge Queue'),
"submitText": gettext('Purge'),
"schema": schema,
"form": form,
"model": model
};
return modal.open(config).then(submit);
}
function submit(context) {
var id = context.model.id;
var name = context.model.name;
delete context.model.id;
delete context.model.name;
context.model.resource_types = (context.model.resource_types === "all")
? [] : [context.model.resource_types];
return zaqar.purgeQueue(id, context.model).then(function() {
toast.add('success', interpolate(message.success, [name]));
scope.$emit(events.PURGE_SUCCESS, name);
});
}
}
})();

View File

@ -48,6 +48,7 @@
METADATA_CHANGED: 'horizon.dashboard.project.queues.METADATA_CHANGED', METADATA_CHANGED: 'horizon.dashboard.project.queues.METADATA_CHANGED',
DELETE_SUCCESS: 'horizon.dashboard.project.queues.DELETE_SUCCESS', DELETE_SUCCESS: 'horizon.dashboard.project.queues.DELETE_SUCCESS',
UPDATE_SUCCESS: 'horizon.dashboard.project.queues.UPDATE_SUCCESS', UPDATE_SUCCESS: 'horizon.dashboard.project.queues.UPDATE_SUCCESS',
PURGE_SUCCESS: 'horizon.dashboard.project.queues.PURGE_SUCCESS',
SUBSCRIPTION_CREATE_SUCCESS: 'horizon.dashboard.project.queues.SUBSCRIPTION_CREATE_SUCCESS' SUBSCRIPTION_CREATE_SUCCESS: 'horizon.dashboard.project.queues.SUBSCRIPTION_CREATE_SUCCESS'
}; };
} }

View File

@ -54,11 +54,13 @@
var createWatcher = $scope.$on(events.CREATE_SUCCESS, onCreateSuccess); var createWatcher = $scope.$on(events.CREATE_SUCCESS, onCreateSuccess);
var deleteWatcher = $scope.$on(events.DELETE_SUCCESS, onDeleteSuccess); var deleteWatcher = $scope.$on(events.DELETE_SUCCESS, onDeleteSuccess);
var updateWatcher = $scope.$on(events.UPDATE_SUCCESS, onUpdateSuccess); var updateWatcher = $scope.$on(events.UPDATE_SUCCESS, onUpdateSuccess);
var purgeWatcher = $scope.$on(events.PURGE_SUCCESS, onPurgeSuccess);
var subWatcher = $scope.$on(events.SUBSCRIPTION_CREATE_SUCCESS, broadcastEvents); var subWatcher = $scope.$on(events.SUBSCRIPTION_CREATE_SUCCESS, broadcastEvents);
$scope.$on('$destroy', function destroy() { $scope.$on('$destroy', function destroy() {
createWatcher(); createWatcher();
deleteWatcher(); deleteWatcher();
updateWatcher(); updateWatcher();
purgeWatcher();
subWatcher(); subWatcher();
}); });
} }
@ -85,6 +87,32 @@
}); });
} }
function refreshQueue(queueName) {
zaqar.getQueue(queueName).then(function(response) {
response.data.id = queueName;
for (var i = 0; i < ctrl.queuesSrc.length; i++) {
var queue = ctrl.queuesSrc[i];
if (queue.id === queueName) {
ctrl.queuesSrc[i] = response.data;
}
}
for (var i = 0; i < ctrl.queues.length; i++) {
var queue = ctrl.queues[i];
if (queue.id === queueName) {
ctrl.queues[i] = response.data;
}
}
});
}
function refreshSubscriptions(queueName) {
var queue = new Object();
queue.name = queueName;
zaqar.getSubscriptions(queue).then(function() {
$scope.tCtrl.broadcastExpansion(queue);
});
}
function onCreateSuccess(e, newQueue) { function onCreateSuccess(e, newQueue) {
e.stopPropagation(); e.stopPropagation();
newQueue.id = newQueue.name; newQueue.id = newQueue.name;
@ -110,6 +138,14 @@
// update queue // update queue
ctrl.queuesSrc[queue.id] = queue; ctrl.queuesSrc[queue.id] = queue;
} }
function onPurgeSuccess(e, queueName) {
e.stopPropagation();
// purge queue
refreshQueue(queueName);
refreshSubscriptions(queueName);
}
} }
})(); })();