예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
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
예제 #4
0
파일: jobs.py 프로젝트: crim-ca/weaver
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
예제 #5
0
파일: utils.py 프로젝트: crim-ca/weaver
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