def run_migration(self): # type: (...) -> None """ Runs any necessary data-schema migration steps. """ db_info = self.get_information() LOGGER.info("Running database migration as needed for %s", db_info) version = db_info["version"] assert self._revision >= version, "Cannot process future DB revision." for rev in range(version, self._revision): from_to_msg = f"[Migrating revision: {rev} -> {rev + 1}]" if rev == 0: LOGGER.info("%s Convert objects with string for UUID-like fields to real UUID types.", from_to_msg) collection = self._database.jobs for cur in collection.find({"id": {"$type": "string"}}): collection.update_one( {"_id": cur["_id"]}, {"$set": { "id": uuid.UUID(str(cur["id"])), "task_id": uuid.UUID(str(cur["task_id"])) if is_uuid(cur["task_id"]) else cur["task_id"], "wps_id": uuid.UUID(str(cur["wps_id"])) if is_uuid(cur["wps_id"]) else None }} ) for collection in [self._database.bills, self._database.quotes]: for cur in collection.find({"id": {"$type": "string"}}): collection.update_one({"_id": cur["_id"]}, {"$set": {"id": uuid.UUID(str(cur["id"]))}}) # NOTE: add any needed migration revisions here with (if rev = next-index)... # update and move to next revision self._database.version.update_one({"revision": rev}, {"$set": {"revision": rev + 1}}, upsert=True) db_info["version"] = rev LOGGER.info("Database up-to-date with: %s", db_info)
def get_vault_url(file, container=None): # type: (Union[VaultFile, uuid.UUID, str], Optional[AnySettingsContainer]) -> str """ Obtain the vault link corresponding to the file. """ if isinstance(file, uuid.UUID) or is_uuid(file): file_id = str(file) else: file_id = file.id settings = get_settings(container) base_url = get_weaver_url(settings) vault_url = base_url + sd.vault_file_service.path.format(file_id=file_id) return vault_url
def get_wps_local_status_location(url_status_location, container, must_exist=True): # type: (str, AnySettingsContainer, bool) -> Optional[str] """ Attempts to retrieve the local XML file path corresponding to the WPS status location as URL. :param url_status_location: URL reference pointing to some WPS status location XML. :param container: any settings container to map configured local paths. :param must_exist: return only existing path if enabled, otherwise return the parsed value without validation. :returns: found local file path if it exists, ``None`` otherwise. """ dir_path = get_wps_output_dir(container) if url_status_location and not urlparse(url_status_location).scheme in [ "", "file" ]: wps_out_url = get_wps_output_url(container) req_out_url = get_url_without_query(url_status_location) out_path = os.path.join( dir_path, req_out_url.replace(wps_out_url, "").lstrip("/")) else: out_path = url_status_location.replace("file://", "") found = os.path.isfile(out_path) if not found and "/jobs/" in url_status_location: job_uuid = url_status_location.rsplit("/jobs/", 1)[-1].split("/", 1)[0] if is_uuid(job_uuid): out_path_join = os.path.join(dir_path, f"{job_uuid}.xml") found = os.path.isfile(out_path_join) if found or not must_exist: out_path = out_path_join if not found and must_exist: out_path_join = os.path.join( dir_path, out_path[1:] if out_path.startswith("/") else out_path) if not os.path.isfile(out_path_join): LOGGER.debug( "Could not map WPS status reference [%s] to input local file path [%s].", url_status_location, out_path) return None out_path = out_path_join LOGGER.debug("Resolved WPS status reference [%s] as local file path [%s].", url_status_location, out_path) return out_path
def get_job(request): # type: (Request) -> Job """ Obtain a job from request parameters. :returns: Job information if found. :raise HTTPNotFound: with JSON body details on missing/non-matching job, process, provider IDs. """ job_id = request.matchdict.get("job_id") try: if not is_uuid(job_id): raise JobInvalidParameter store = get_db(request).get_store(StoreJobs) job = store.fetch_by_id(job_id) except (JobInvalidParameter, JobNotFound) as exc: exception = type(exc) if exception is JobInvalidParameter: desc = "Invalid job reference is not a valid UUID." else: desc = "Could not find job with specified reference." title = "NoSuchJob" raise exception( # new format: https://docs.ogc.org/DRAFTS/18-062.html#_error_situations_7 json={ "title": title, "type": "http://www.opengis.net/def/exceptions/ogcapi-processes-1/1.0/no-such-job", "detail": desc, "status": exception.code, "cause": str(job_id) }, code=title, locator="JobID", description=desc # old format ) provider_id = request.matchdict.get("provider_id", job.service) process_id = request.matchdict.get("process_id", job.process) if provider_id: forbid_local_only(request) if job.service != provider_id: title = "NoSuchProvider" desc = "Could not find job reference corresponding to specified provider reference." raise OWSNotFound( # new format: https://docs.ogc.org/DRAFTS/18-062.html#_error_situations_5 json={ "title": title, "type": "http://www.opengis.net/def/exceptions/ogcapi-processes-1/1.0/no-such-job", "detail": desc, "status": OWSNotFound.code, "cause": str(process_id) }, code=title, locator="provider", description=desc # old format ) if job.process != process_id: title = "NoSuchProcess" desc = "Could not find job reference corresponding to specified process reference." raise OWSNotFound( # new format: https://docs.ogc.org/DRAFTS/18-062.html#_error_situations_5 json={ "title": title, "type": "http://www.opengis.net/def/exceptions/ogcapi-processes-1/1.0/no-such-job", "detail": desc, "status": OWSNotFound.code, "cause": str(process_id) }, code=title, locator="process", description=desc # old format ) return job
def get_job(request): # type: (PyramidRequest) -> Job """ Obtain a :term:`Job` from request parameters. .. versionchanged:: 4.20 When looking for :term:`Job` that refers to a local :term:`Process`, allow implicit resolution of the unspecified ``version`` portion to automatically resolve the identifier. Consider that validation of the expected :term:`Process` for this :term:`Job` is "good enough", since the specific ID is not actually required to obtain the :term:`Job` (could be queried by ID only on the ``/jobs/{jobId}`` endpoint. If the ``version`` is provided though (either query parameter or tagged representation), the validation will ensure that it matches explicitly. :param request: Request with path and query parameters to retrieve the desired job. :returns: Job information if found. :raise HTTPNotFound: with JSON body details on missing/non-matching job, process, provider IDs. """ job_id = request.matchdict.get("job_id") try: if not is_uuid(job_id): raise JobInvalidParameter store = get_db(request).get_store(StoreJobs) job = store.fetch_by_id(job_id) except (JobInvalidParameter, JobNotFound) as exc: exception = type(exc) if exception is JobInvalidParameter: desc = "Invalid job reference is not a valid UUID." else: desc = "Could not find job with specified reference." title = "NoSuchJob" raise exception( # new format: https://docs.ogc.org/is/18-062r2/18-062r2.html#req_core_job-exception-no-such-job json={ "title": title, "type": "http://www.opengis.net/def/exceptions/ogcapi-processes-1/1.0/no-such-job", "detail": desc, "status": exception.code, "cause": str(job_id) }, code=title, locator="JobID", description=desc # old format ) provider_id = request.matchdict.get("provider_id", job.service) process_tag = request.matchdict.get("process_id") if process_tag: process_tag = resolve_process_tag( request) # find version if available as well else: process_tag = job.process if provider_id: forbid_local_only(request) if job.service != provider_id: title = "NoSuchProvider" desc = "Could not find job reference corresponding to specified provider reference." raise OWSNotFound( # new format: https://docs.ogc.org/is/18-062r2/18-062r2.html#req_core_job-exception-no-such-job json={ "title": title, "type": "http://www.opengis.net/def/exceptions/ogcapi-processes-1/1.0/no-such-job", "detail": desc, "status": OWSNotFound.code, "cause": str(provider_id) }, code=title, locator="provider", description=desc # old format ) process_id = Process.split_version(process_tag)[0] if job.process not in [process_id, process_tag]: title = "NoSuchProcess" desc = "Could not find job reference corresponding to specified process reference." raise OWSNotFound( # new format: https://docs.ogc.org/is/18-062r2/18-062r2.html#req_core_job-exception-no-such-job # note: although 'no-such-process' error, return 'no-such-job' because process could exist, only mismatches json={ "title": title, "type": "http://www.opengis.net/def/exceptions/ogcapi-processes-1/1.0/no-such-job", "detail": desc, "status": OWSNotFound.code, "cause": str(process_tag) }, code=title, locator="process", description=desc # old format ) return job