From 7a3930efe795a2ad9a0b55a7106e21088f745f13 Mon Sep 17 00:00:00 2001 From: Sid Verma Date: Wed, 22 Jul 2020 15:32:24 +0530 Subject: [PATCH] Fail to limited metadata if elastic is not available --- .../core/djangoapps/content_libraries/api.py | 72 +++++++++++-------- openedx/core/lib/blockstore_api/__init__.py | 1 + openedx/core/lib/blockstore_api/methods.py | 12 ++++ 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 790942300d..cb693ac4c4 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -73,6 +73,7 @@ from openedx.core.djangoapps.xblock.learning_context.manager import get_learning from openedx.core.djangoapps.xblock.runtime.olx_parsing import XBlockInclude from openedx.core.lib.blockstore_api import ( get_bundle, + get_bundles, get_bundle_file_data, get_bundle_files, get_or_create_bundle_draft, @@ -93,12 +94,6 @@ log = logging.getLogger(__name__) ContentLibraryNotFound = ContentLibrary.DoesNotExist -class ServerError(APIException): - """ A 500 server error """ - status_code = 500 - default_detail = "Error occurred in the server. Please contact support with details of this error" - - class ContentLibraryBlockNotFound(XBlockNotFoundError): """ XBlock not found in the content library """ @@ -238,31 +233,46 @@ def get_metadata_from_index(queryset): Take a list of ContentLibrary objects and return metadata stored in ContentLibraryIndex. """ - if not ContentLibraryIndexer.indexing_is_enabled(): - raise NotImplementedError("Library indexing needs to be enabled for this API to work") - library_keys = [lib.library_key for lib in queryset] - try: - metadata = ContentLibraryIndexer.get_libraries(library_keys) - libraries = [ - ContentLibraryMetadata( - key=key, - bundle_uuid=metadata[i]['uuid'], - title=metadata[i]['title'], - description=metadata[i]['description'], - num_blocks=metadata[i]['num_blocks'], - version=metadata[i]['version'], - last_published=metadata[i]['last_published'], - allow_public_learning=queryset[i].allow_public_learning, - allow_public_read=queryset[i].allow_public_read, - has_unpublished_changes=metadata[i]['has_unpublished_changes'], - has_unpublished_deletes=metadata[i]['has_unpublished_deletes'], - ) - for i, key in enumerate(library_keys) - ] - return libraries - except (LibraryNotIndexedException, KeyError) as e: - log.exception(e) - raise ServerError("Libraries have missing or invalid indexes, and need to be updated.") + metadata = None + if ContentLibraryIndexer.indexing_is_enabled(): + try: + library_keys = [lib.library_key for lib in queryset] + metadata = ContentLibraryIndexer.get_libraries(library_keys) + except (LibraryNotIndexedException, KeyError, ElasticConnectionError) as e: + log.exception(e) + + # If ContentLibraryIndex is not available, we query blockstore for a limited set of metadata + if metadata is None: + uuids = [lib.bundle_uuid for lib in queryset] + bundles = get_bundles(uuids) + bundle_dict = { + bundle.uuid: { + 'uuid': bundle.uuid, + 'title': bundle.title, + 'description': bundle.description, + 'version': bundle.latest_version, + } + for bundle in bundles + } + metadata = [bundle_dict[uuid] for uuid in uuids] + + libraries = [ + ContentLibraryMetadata( + key=lib.library_key, + bundle_uuid=metadata[i]['uuid'], + title=metadata[i]['title'], + description=metadata[i]['description'], + version=metadata[i]['version'], + allow_public_learning=queryset[i].allow_public_learning, + allow_public_read=queryset[i].allow_public_read, + num_blocks=metadata[i].get('num_blocks'), + last_published=metadata[i].get('last_published'), + has_unpublished_changes=metadata[i].get('has_unpublished_changes'), + has_unpublished_deletes=metadata[i].get('has_unpublished_deletes'), + ) + for i, lib in enumerate(queryset) + ] + return libraries def require_permission_for_library_key(library_key, user, permission): diff --git a/openedx/core/lib/blockstore_api/__init__.py b/openedx/core/lib/blockstore_api/__init__.py index ae40084119..483e97c2eb 100644 --- a/openedx/core/lib/blockstore_api/__init__.py +++ b/openedx/core/lib/blockstore_api/__init__.py @@ -22,6 +22,7 @@ from .methods import ( update_collection, delete_collection, # Bundles: + get_bundles, get_bundle, create_bundle, update_bundle, diff --git a/openedx/core/lib/blockstore_api/methods.py b/openedx/core/lib/blockstore_api/methods.py index 9520f16c62..eec7c69003 100644 --- a/openedx/core/lib/blockstore_api/methods.py +++ b/openedx/core/lib/blockstore_api/methods.py @@ -144,6 +144,18 @@ def delete_collection(collection_uuid): api_request('delete', api_url('collections', str(collection_uuid))) +def get_bundles(uuids=None): + """ + Get the details of all bundles + """ + if uuids is None: + uuids = [] + version_url = api_url('bundles') + '?uuid=' + ','.join(map(str, uuids)) + response = api_request('get', version_url) + # build bundle from response, convert map object to list and return + return [_bundle_from_response(item) for item in response] + + def get_bundle(bundle_uuid): """ Retrieve metadata about the specified bundle