From 991b49b78e72c8ec2ded74d8108f599bea71435e Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 23 May 2024 18:45:06 +0200 Subject: [PATCH] Check dataset state when attempting to acces dataset contents --- lib/galaxy/managers/datasets.py | 19 +++++++++++++++++++ .../webapps/galaxy/services/datasets.py | 17 +++++++++++++++-- lib/galaxy_test/api/test_datasets.py | 11 +++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/managers/datasets.py b/lib/galaxy/managers/datasets.py index 1bbe86ee7021..18c9ae5fe0ed 100644 --- a/lib/galaxy/managers/datasets.py +++ b/lib/galaxy/managers/datasets.py @@ -488,6 +488,25 @@ def serialize_dataset_association_roles(self, trans, dataset_assoc): rval["modify_item_roles"] = modify_item_role_list return rval + def ensure_dataset_on_disk(self, trans, dataset): + # Not a guarantee data is really present, but excludes a lot of expected cases + if dataset.purged or dataset.dataset.purged: + raise exceptions.ItemDeletionException("The dataset you are attempting to view has been purged.") + elif dataset.deleted and not (trans.user_is_admin or self.is_owner(dataset, trans.get_user())): + raise exceptions.ItemDeletionException("The dataset you are attempting to view has been deleted.") + elif dataset.state == Dataset.states.UPLOAD: + raise exceptions.Conflict("Please wait until this dataset finishes uploading before attempting to view it.") + elif dataset.state == Dataset.states.DISCARDED: + raise exceptions.ItemDeletionException("The dataset you are attempting to view has been discarded.") + elif dataset.state == Dataset.states.DEFERRED: + raise exceptions.Conflict( + "The dataset you are attempting to view has deferred data. You can only use this dataset as input for jobs." + ) + elif dataset.state == Dataset.states.PAUSED: + raise exceptions.Conflict( + "The dataset you are attempting to view is in paused state. One of the inputs for the job that creates this dataset has failed." + ) + def ensure_can_change_datatype(self, dataset: model.DatasetInstance, raiseException: bool = True) -> bool: if not dataset.datatype.is_datatype_change_allowed(): if not raiseException: diff --git a/lib/galaxy/webapps/galaxy/services/datasets.py b/lib/galaxy/webapps/galaxy/services/datasets.py index fc67929c3c24..87d4da9c537a 100644 --- a/lib/galaxy/webapps/galaxy/services/datasets.py +++ b/lib/galaxy/webapps/galaxy/services/datasets.py @@ -364,7 +364,17 @@ def show( """ Displays information about and/or content of a dataset. """ - dataset = self.dataset_manager_by_type[hda_ldda].get_accessible(dataset_id, trans.user) + dataset_manager = self.dataset_manager_by_type[hda_ldda] + dataset = dataset_manager.get_accessible(dataset_id, trans.user) + requests_that_require_data = ( + RequestDataType.converted_datasets_state, + RequestDataType.data, + RequestDataType.features, + RequestDataType.raw_data, + RequestDataType.track_config, + ) + if data_type in requests_that_require_data: + dataset_manager.ensure_dataset_on_disk(trans, dataset) # Use data type to return particular type of data. rval: Any @@ -606,7 +616,9 @@ def display( headers = {} rval: Any = "" try: - dataset_instance = self.dataset_manager_by_type[hda_ldda].get_accessible(dataset_id, trans.user) + dataset_manager = self.dataset_manager_by_type[hda_ldda] + dataset_instance = dataset_manager.get_accessible(dataset_id, trans.user) + dataset_manager.ensure_dataset_on_disk(trans, dataset_instance) if raw: if filename and filename != "index": object_store = trans.app.object_store @@ -668,6 +680,7 @@ def get_metadata_file( TODO: Remove the `open_file` parameter when removing the associated legacy endpoint. """ hda = self.hda_manager.get_accessible(history_content_id, trans.user) + self.hda_manager.ensure_dataset_on_disk(trans, hda) file_ext = hda.metadata.spec.get(metadata_file).get("file_ext", metadata_file) fname = "".join(c in util.FILENAME_VALID_CHARS and c or "_" for c in hda.name)[0:150] headers = {} diff --git a/lib/galaxy_test/api/test_datasets.py b/lib/galaxy_test/api/test_datasets.py index 3c8c9daf3420..9705d2d2b577 100644 --- a/lib/galaxy_test/api/test_datasets.py +++ b/lib/galaxy_test/api/test_datasets.py @@ -343,6 +343,17 @@ def test_display(self, history_id): self._assert_status_code_is(display_response, 200) assert display_response.text == contents + def test_display_error_handling(self, history_id): + hda1 = self.dataset_populator.create_deferred_hda( + history_id, "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test-data/1.bed" + ) + display_response = self._get(f"histories/{history_id}/contents/{hda1['id']}/display", {"raw": "True"}) + self._assert_status_code_is(display_response, 409) + assert ( + display_response.json()["err_msg"] + == "The dataset you are attempting to view has deferred data. You can only use this dataset as input for jobs." + ) + def test_get_content_as_text(self, history_id): contents = textwrap.dedent( """\