Skip to content
This repository has been archived by the owner on Dec 7, 2022. It is now read-only.

Commit

Permalink
ref #827, separate view for collection actions.
Browse files Browse the repository at this point in the history
  • Loading branch information
jortel committed May 12, 2015
1 parent 632a884 commit 857679c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 39 deletions.
29 changes: 22 additions & 7 deletions server/pulp/server/webservices/urls.py
Expand Up @@ -30,13 +30,26 @@
ConsumerGroupSearchView,
ConsumerGroupUnassociateActionView,
ConsumerGroupView)

from pulp.server.webservices.views.content import (
CatalogResourceView, ContentSourceView, ContentSourceResourceView,
ContentUnitResourceView, ContentUnitSearch, ContentUnitsCollectionView,
ContentUnitUserMetadataResourceView, DeleteOrphansActionView, OrphanCollectionView,
OrphanResourceView, OrphanTypeSubCollectionView, UploadsCollectionView, UploadResourceView,
CatalogResourceView,
ContentSourceCollectionActionView,
ContentSourceCollectionView,
ContentSourceResourceActionView,
ContentSourceResourceView,
ContentUnitResourceView,
ContentUnitsCollectionView,
ContentUnitSearch,
ContentUnitUserMetadataResourceView,
DeleteOrphansActionView,
OrphanCollectionView,
OrphanResourceView,
OrphanTypeSubCollectionView,
UploadResourceView,
UploadsCollectionView,
UploadSegmentResourceView
)

from pulp.server.webservices.views.events import (EventResourceView, EventView)
from pulp.server.webservices.views.permissions import (GrantToRoleView, GrantToUserView,
PermissionView, RevokeFromRoleView,
Expand Down Expand Up @@ -129,12 +142,14 @@
name='content_orphan_type_subcollection'),
url(r'^v2/content/orphans/(?P<content_type>[^/]+)/(?P<unit_id>[^/]+)/$',
OrphanResourceView.as_view(), name='content_orphan_resource'),
url(r'^v2/content/sources/$', ContentSourceView.as_view(),
url(r'^v2/content/sources/$',
ContentSourceCollectionView.as_view(),
name='content_sources'),
url(r'^v2/content/sources/action/(?P<action>[^/]+)/$', ContentSourceView.as_view(),
url(r'^v2/content/sources/action/(?P<action>[^/]+)/$',
ContentSourceCollectionActionView.as_view(),
name='content_sources_action'),
url(r'^v2/content/sources/(?P<source_id>[^/]+)/action/(?P<action>[^/]+)/$',
ContentSourceResourceView.as_view(), name='content_sources_resource_action'),
ContentSourceResourceActionView.as_view(), name='content_sources_resource_action'),
url(r'^v2/content/sources/(?P<source_id>[^/]+)/$', ContentSourceResourceView.as_view(),
name='content_sources_resource'),
url(r'^v2/content/units/(?P<type_id>[^/]+)/$', ContentUnitsCollectionView.as_view(),
Expand Down
49 changes: 31 additions & 18 deletions server/pulp/server/webservices/views/content.py
Expand Up @@ -492,7 +492,7 @@ def delete(self, request, upload_id):
return generate_json_response(None)


class ContentSourceView(View):
class ContentSourceCollectionView(View):
"""
View for content sources.
"""
Expand All @@ -518,14 +518,36 @@ def get(self, request):
sources.append(d)
return generate_json_response_with_pulp_encoder(sources)


class ContentSourceCollectionActionView(View):
"""
View for actions on all sources.
"""

@staticmethod
def refresh(request):
"""
Refresh all content sources
:param request: WSGI request object, body contains bits to upload
:type request: django.core.handlers.wsgi.WSGIRequest
:raises: OperationPostponed when an async operation is performed
"""
container = ContentContainer()
content_sources = [tags.resource_tag(RESOURCE_CONTENT_SOURCE, id)
for id in container.sources.keys()]
task_tags = [tags.action_tag(ACTION_REFRESH_ALL_CONTENT_SOURCES)] + content_sources
task_result = content.refresh_content_sources.apply_async(tags=task_tags)
raise OperationPostponed(task_result)

@auth_required(authorization.UPDATE)
@json_body_allow_empty
def post(self, request, action):
"""
Content source actions.
:param request: WSGI request object, body contains bits to upload
:type request: django.core.handlers.wsgi.WSGIRequest
:param request: WSGI request object, body contains bits to upload
:type request: django.core.handlers.wsgi.WSGIRequest
:param action: Name of action to perform
:type action: str
"""
Expand All @@ -535,21 +557,6 @@ def post(self, request, action):
else:
return HttpResponseBadRequest('bad request')

def refresh(self, request):
"""
Refresh all content sources
:param request: WSGI request object, body contains bits to upload
:type request: django.core.handlers.wsgi.WSGIRequest
:raises: OperationPostponed when an async operation is performed
"""
container = ContentContainer()
content_sources = [tags.resource_tag(RESOURCE_CONTENT_SOURCE, id)
for id in container.sources.keys()]
task_tags = [tags.action_tag(ACTION_REFRESH_ALL_CONTENT_SOURCES)] + content_sources
task_result = content.refresh_content_sources.apply_async(tags=task_tags)
raise OperationPostponed(task_result)


class ContentSourceResourceView(View):
"""
Expand Down Expand Up @@ -581,6 +588,12 @@ def get(self, request, source_id):
else:
raise MissingResource(source_id=source_id)


class ContentSourceResourceActionView(View):
"""
View for single content source actions.
"""

@auth_required(authorization.UPDATE)
@json_body_allow_empty
def post(self, request, source_id, action):
Expand Down
52 changes: 38 additions & 14 deletions server/test/unit/server/webservices/views/test_content.py
Expand Up @@ -5,14 +5,26 @@

from django.http import HttpResponseBadRequest, HttpResponseNotFound

from .base import assert_auth_CREATE, assert_auth_DELETE, assert_auth_READ, assert_auth_UPDATE
from base import assert_auth_CREATE, assert_auth_DELETE, assert_auth_READ, assert_auth_UPDATE
from pulp.server import constants
from pulp.server.exceptions import InvalidValue, MissingResource, OperationPostponed
from pulp.server.webservices.views.content import (
CatalogResourceView, ContentSourceView, ContentSourceResourceView, ContentUnitSearch,
ContentUnitResourceView, ContentUnitsCollectionView, ContentUnitUserMetadataResourceView,
DeleteOrphansActionView, OrphanCollectionView, OrphanTypeSubCollectionView, OrphanResourceView,
UploadResourceView, UploadsCollectionView, UploadSegmentResourceView
CatalogResourceView,
ContentSourceCollectionActionView,
ContentSourceCollectionView,
ContentSourceResourceActionView,
ContentSourceResourceView,
ContentUnitResourceView,
ContentUnitsCollectionView,
ContentUnitSearch,
ContentUnitUserMetadataResourceView,
DeleteOrphansActionView,
OrphanCollectionView,
OrphanResourceView,
OrphanTypeSubCollectionView,
UploadResourceView,
UploadsCollectionView,
UploadSegmentResourceView
)


Expand Down Expand Up @@ -626,7 +638,7 @@ def test_delete_upload_resource_view(self, mock_factory, mock_resp):
mock_upload_manager.delete_upload.assert_called_once_with('mock_unit')


class TestContentSourceView(unittest.TestCase):
class TestContentSourceCollectionView(unittest.TestCase):
"""
Tests for content sources
"""
Expand All @@ -644,13 +656,19 @@ def test_get_content_source(self, mock_sources, mock_resp):
mock_sources.return_value = {'mock': source}

request = mock.MagicMock()
content_source_view = ContentSourceView()
content_source_view = ContentSourceCollectionView()
response = content_source_view.get(request)

mock_resp.assert_called_once_with([{'source_id': 'my-id',
'_href': '/v2/content/sources/my-id/'}])
self.assertTrue(response is mock_resp.return_value)


class TestContentSourceCollectionActionView(unittest.TestCase):
"""
Tests for content sources
"""

@mock.patch('pulp.server.webservices.views.decorators._verify_auth',
new=assert_auth_UPDATE())
def test_post_bad_request_content_source(self):
Expand All @@ -659,7 +677,7 @@ def test_post_bad_request_content_source(self):
"""
request = mock.MagicMock()
request.body = None
content_source_view = ContentSourceView()
content_source_view = ContentSourceCollectionActionView()
response = content_source_view.post(request, 'no-such-action')

self.assertTrue(isinstance(response, HttpResponseBadRequest))
Expand All @@ -683,7 +701,7 @@ def test_refresh_content_source(self, mock_refresh, mock_sources, mock_tags):

request = mock.MagicMock()
request.body = None
content_source_view = ContentSourceView()
content_source_view = ContentSourceCollectionActionView()
try:
content_source_view.post(request, 'refresh')
except OperationPostponed, response:
Expand Down Expand Up @@ -741,10 +759,16 @@ def test_get_invalid_content_source_resource(self, mock_sources):
self.assertEqual(response.http_status_code, 404)
self.assertEqual(response.error_data['resources'], {'source_id': 'some-source'})


class TestContentSourceResourceActionView(unittest.TestCase):
"""
Tests for content sources resource
"""

@mock.patch('pulp.server.webservices.views.decorators._verify_auth',
new=assert_auth_UPDATE())
@mock.patch('pulp.server.content.sources.container.ContentSource.load_all')
def test_post_bad_request_specific_content_source(self, mock_sources):
def test_post_invalid_action(self, mock_sources):
"""
Test specific content source invalid action
"""
Expand All @@ -755,7 +779,7 @@ def test_post_bad_request_specific_content_source(self, mock_sources):

request = mock.MagicMock()
request.body = None
content_source_view = ContentSourceResourceView()
content_source_view = ContentSourceResourceActionView()
response = content_source_view.post(request, 'some-source', 'no-such-action')

self.assertTrue(isinstance(response, HttpResponseBadRequest))
Expand All @@ -772,7 +796,7 @@ def test_refresh_invalid_content_source(self, mock_sources):

request = mock.MagicMock()
request.body = None
content_source_view = ContentSourceResourceView()
content_source_view = ContentSourceResourceActionView()
try:
content_source_view.post(request, 'some-source', 'refresh')
except MissingResource, response:
Expand All @@ -787,7 +811,7 @@ def test_refresh_invalid_content_source(self, mock_sources):
@mock.patch('pulp.server.webservices.views.content.tags')
@mock.patch('pulp.server.content.sources.container.ContentSource.load_all')
@mock.patch('pulp.server.webservices.views.content.content.refresh_content_source')
def test_refresh_specific_content_source(self, mock_refresh, mock_sources, mock_tags):
def test_refresh_specific_action(self, mock_refresh, mock_sources, mock_tags):
"""
Test refresh specific content source
"""
Expand All @@ -800,7 +824,7 @@ def test_refresh_specific_content_source(self, mock_refresh, mock_sources, mock_

request = mock.MagicMock()
request.body = None
content_source_view = ContentSourceResourceView()
content_source_view = ContentSourceResourceActionView()
try:
content_source_view.post(request, 'some-source', 'refresh')
except OperationPostponed, response:
Expand Down

0 comments on commit 857679c

Please sign in to comment.