Skip to content

Commit

Permalink
Remove ui api non-repo collections endpoint (#514)
Browse files Browse the repository at this point in the history
No-Issue

* Change _ui/collections endpoint to use published repo
* Rename RepositoryCollection* classes to Collection*

Signed-off-by: Andrew Crosby <acrosby@redhat.com>
  • Loading branch information
awcrosby committed Oct 19, 2020
1 parent aa1535b commit 6b91399
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 179 deletions.
12 changes: 11 additions & 1 deletion galaxy_ng/app/api/ui/old_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# TODO: Replace with a RedirectView
router.register('namespaces', viewsets.NamespaceViewSet, basename='namespaces')
router.register('my-namespaces', viewsets.MyNamespaceViewSet, basename='my-namespaces')
router.register('collections', viewsets.CollectionViewSet, basename='collections')
router.register('users', viewsets.UserViewSet, basename='users')
router.register('collection-versions',
viewsets.CollectionVersionViewSet, basename='collection-versions')
Expand All @@ -33,6 +32,17 @@

path('auth/', include(auth_views)),

path(
'collections/',
viewsets.CollectionViewSetDeprecated.as_view({'get': 'list'}),
name='collections-list'
),
path(
'collections/<str:namespace>/<str:name>/',
viewsets.CollectionViewSetDeprecated.as_view({'get': 'retrieve'}),
name='collections-detail'
),

# NOTE: Using path instead of SimpleRouter because SimpleRouter expects retrieve
# to look up values with an ID
path(
Expand Down
4 changes: 0 additions & 4 deletions galaxy_ng/app/api/ui/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
LoginSerializer,
)
from .collection import (
RepositoryCollectionDetailSerializer,
RepositoryCollectionListSerializer,
CollectionDetailSerializer,
CollectionListSerializer,
CollectionVersionSerializer,
Expand Down Expand Up @@ -35,8 +33,6 @@
# auth
'LoginSerializer',
# collection
'RepositoryCollectionDetailSerializer',
'RepositoryCollectionListSerializer',
'CollectionDetailSerializer',
'CollectionListSerializer',
'CollectionVersionSerializer',
Expand Down
49 changes: 5 additions & 44 deletions galaxy_ng/app/api/ui/serializers/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ class ContentSerializer(Serializer):
description = serializers.CharField()


class CollectionVersionSummarySerializer(Serializer):
version = serializers.CharField()
created = serializers.CharField()


class CollectionMetadataSerializer(Serializer):
dependencies = serializers.JSONField()
contents = serializers.JSONField()
Expand Down Expand Up @@ -114,46 +109,12 @@ class CollectionVersionDetailSerializer(CollectionVersionBaseSerializer):
docs_blob = serializers.JSONField()


class _CollectionSerializer(Serializer):
id = serializers.UUIDField()
namespace = serializers.SerializerMethodField()
name = serializers.CharField()
download_count = serializers.IntegerField(default=0)
latest_version = CollectionVersionBaseSerializer(source='*')
deprecated = serializers.BooleanField()

def _get_namespace(self, obj):
raise NotImplementedError

def get_namespace(self, obj):
namespace = self._get_namespace(obj)
return NamespaceSummarySerializer(namespace).data


class CollectionListSerializer(_CollectionSerializer):
def _get_namespace(self, obj):
name = obj['namespace']
return self.context['namespaces'].get(name, None)


class CollectionDetailSerializer(_CollectionSerializer):
latest_version = CollectionVersionDetailSerializer(source='*')
all_versions = serializers.SerializerMethodField()

def _get_namespace(self, obj):
return self.context['namespace']

def get_all_versions(self, obj):
return [CollectionVersionSummarySerializer(version).data
for version in self.context['all_versions']]


class RepositoryCollectionVersionSummarySerializer(Serializer):
class CollectionVersionSummarySerializer(Serializer):
version = serializers.CharField()
created = serializers.CharField(source='pulp_created')


class _RepositoryCollectionSerializer(Serializer):
class _CollectionSerializer(Serializer):
""" Serializer for pulp_ansible CollectionViewSet.
Uses CollectionVersion object to serialize associated Collection data.
"""
Expand Down Expand Up @@ -193,18 +154,18 @@ def _get_latest_version(self, obj):
return next(iter(versions_in_repo), None)


class RepositoryCollectionListSerializer(_RepositoryCollectionSerializer):
class CollectionListSerializer(_CollectionSerializer):
def get_latest_version(self, obj):
version = self._get_latest_version(obj)
return CollectionVersionBaseSerializer(version).data


class RepositoryCollectionDetailSerializer(_RepositoryCollectionSerializer):
class CollectionDetailSerializer(_CollectionSerializer):
all_versions = serializers.SerializerMethodField()

def get_all_versions(self, obj):
versions_in_repo = self._get_versions_in_repo(obj)
return RepositoryCollectionVersionSummarySerializer(versions_in_repo, many=True).data
return CollectionVersionSummarySerializer(versions_in_repo, many=True).data

def get_latest_version(self, obj):
version = self._get_latest_version(obj)
Expand Down
20 changes: 15 additions & 5 deletions galaxy_ng/app/api/ui/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
router.register('namespaces', viewsets.NamespaceViewSet, basename='namespaces')
router.register('my-namespaces', viewsets.MyNamespaceViewSet, basename='my-namespaces')
router.register('my-synclists', viewsets.MySyncListViewSet, basename='my-synclists')
router.register('collections', viewsets.CollectionViewSet, basename='collections')
router.register('users', viewsets.UserViewSet, basename='users')
router.register('collection-versions',
viewsets.CollectionVersionViewSet, basename='collection-versions')
Expand Down Expand Up @@ -73,13 +72,24 @@

path(
'repo/<str:path>/',
viewsets.RepositoryCollectionViewSet.as_view({'get': 'list'}),
name='repo-collections-list'
viewsets.CollectionViewSet.as_view({'get': 'list'}),
name='collections-list'
),
path(
'repo/<str:path>/<str:namespace>/<str:name>/',
viewsets.RepositoryCollectionViewSet.as_view({'get': 'retrieve'}),
name='repo-collections-detail'
viewsets.CollectionViewSet.as_view({'get': 'retrieve'}),
name='collections-detail'
),

path(
'collections/',
viewsets.CollectionViewSetDeprecated.as_view({'get': 'list'}),
name='collections-list'
),
path(
'collections/<str:namespace>/<str:name>/',
viewsets.CollectionViewSetDeprecated.as_view({'get': 'retrieve'}),
name='collections-detail'
),

# NOTE: Using path instead of SimpleRouter because SimpleRouter expects retrieve
Expand Down
4 changes: 2 additions & 2 deletions galaxy_ng/app/api/ui/viewsets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .collection import (
CollectionViewSet,
RepositoryCollectionViewSet,
CollectionViewSetDeprecated,
CollectionVersionViewSet,
CollectionImportViewSet,
CollectionRemoteViewSet
Expand All @@ -23,7 +23,7 @@
'MyNamespaceViewSet',
'MySyncListViewSet',
'CollectionViewSet',
'RepositoryCollectionViewSet',
'CollectionViewSetDeprecated',
'CollectionVersionViewSet',
'CollectionImportViewSet',
'CollectionRemoteViewSet',
Expand Down
134 changes: 15 additions & 119 deletions galaxy_ng/app/api/ui/viewsets/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,138 +14,24 @@
CollectionRemote,
)
from rest_framework.exceptions import NotFound
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response

from galaxy_ng.app import models
from galaxy_ng.app.api import base as api_base
from galaxy_ng.app.access_control import access_policy
from galaxy_ng.app.api.ui import serializers, versioning
from galaxy_ng.app.common import pulp
from galaxy_ng.app import constants


class CollectionViewSet(api_base.ViewSet):
lookup_url_kwarg = 'collection'
lookup_value_regex = r'[0-9a-z_]+/[0-9a-z_]+'
permission_classes = [access_policy.CollectionAccessPolicy]
versioning_class = versioning.UIVersioning

def list(self, request, *args, **kwargs):
self.paginator.init_from_request(request)

params = {
'offset': self.paginator.offset,
'limit': self.paginator.limit,
}
for key, value in self.request.query_params.lists():
if key == 'keywords':
key = 'q'
if isinstance(value, list):
params[key] = ','.join(value)
else:
params[key] = value

api = galaxy_pulp.PulpCollectionsApi(pulp.get_client())

response = api.list(
is_highest=True,
exclude_fields='docs_blob',
**params
)

namespaces = set(collection['namespace'] for collection in response.results)
namespaces = self._query_namespaces(namespaces)

data = serializers.CollectionListSerializer(
response.results, many=True,
context={'namespaces': namespaces}
).data
return self.paginator.paginate_proxy_response(data, response.count)

def retrieve(self, request, *args, **kwargs):
namespace, name = self.kwargs['collection'].split('/')
namespace_obj = get_object_or_404(models.Namespace, name=namespace)

params_dict = self.request.query_params.dict()

version = params_dict.get('version', '')

api = galaxy_pulp.PulpCollectionsApi(pulp.get_client())

params = {
'namespace': namespace,
'name': name,
}

if version == '':
params['is_highest'] = True
params['certification'] = constants.CertificationStatus.CERTIFIED.value
else:
params['version'] = version

response = api.list(**params)

if not response.results:
raise NotFound()

all_versions = api.list(
namespace=namespace,
name=name,
fields='version,id,pulp_created,artifact',
certification=constants.CertificationStatus.CERTIFIED.value
)

all_versions = [
{
'version': collection['version'],
'id': collection['id'],
'created': collection['pulp_created']
} for collection in all_versions.results
]

collection = response.results[0]

data = serializers.CollectionDetailSerializer(
collection,
context={'namespace': namespace_obj, 'all_versions': all_versions}
).data

return Response(data)

@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator

@staticmethod
def _query_namespaces(names):
queryset = models.Namespace.objects.filter(name__in=names)
namespaces = {ns.name: ns for ns in queryset}
return namespaces


# TODO(awcrosby): After "ui/collections/" endpoints stop being used by UI,
# remove Collection*[ViewSet|Serializer] classes and replace with
# RepositoryCollection*[ViewSet|Serializer] classes


class RepositoryCollectionFilter(CollectionVersionFilter):
class CollectionFilter(CollectionVersionFilter):
versioning_class = versioning.UIVersioning
keywords = filters.CharFilter(field_name="keywords", method="filter_by_q")


class RepositoryCollectionViewSet(pulp_ansible_galaxy_views.CollectionViewSet):
class CollectionViewSet(pulp_ansible_galaxy_views.CollectionViewSet):
""" Viewset that uses CollectionVersion to display data for Collection."""
versioning_class = versioning.UIVersioning
filterset_class = RepositoryCollectionFilter
filterset_class = CollectionFilter

# TODO(awcrosby): remove once pulp_ansible is_highest param filters by repo
# https://pulp.plan.io/issues/7428
Expand All @@ -168,9 +54,19 @@ def get_queryset(self):

def get_serializer_class(self):
if self.action == 'list':
return serializers.RepositoryCollectionListSerializer
return serializers.CollectionListSerializer
else:
return serializers.RepositoryCollectionDetailSerializer
return serializers.CollectionDetailSerializer


# TODO: Remove when ui is updated and no longer uses this endpoint
class CollectionViewSetDeprecated(CollectionViewSet):
"""Temporary support of old /_ui/collections/ endpoint without use of
certification flag. This shows content from the 'published' repo."""

def get_queryset(self):
self.kwargs["path"] = 'published'
return super().get_queryset()


class CollectionVersionFilter(filterset.FilterSet):
Expand Down
8 changes: 4 additions & 4 deletions galaxy_ng/tests/unit/api/test_api_ui_collection_viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ def setUp(self):
_get_create_version_in_repo(self.namespace, self.collection1, '1.0.0', self.repo2)

self.repo1_list_url = get_current_ui_url(
'repo-collections-list', kwargs={'path': 'repo1'})
'collections-list', kwargs={'path': 'repo1'})
self.repo2_list_url = get_current_ui_url(
'repo-collections-list', kwargs={'path': 'repo2'})
'collections-list', kwargs={'path': 'repo2'})
self.repo3_list_url = get_current_ui_url(
'repo-collections-list', kwargs={'path': 'repo3'})
'collections-list', kwargs={'path': 'repo3'})
self.repo1_collection1_detail_url = get_current_ui_url(
'repo-collections-detail',
'collections-detail',
kwargs={
'path': 'repo1',
'namespace': namespace_name,
Expand Down

0 comments on commit 6b91399

Please sign in to comment.